diff --git a/.github/labeler.yml b/.github/labeler.yml index f985fe0fe5..8a741fe9da 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -8,6 +8,7 @@ CUDA: source/lib/src/cuda/**/* ROCM: source/lib/src/rocm/**/* OP: source/op/**/* C++: source/api_cc/**/* +C: source/api_c/**/* LAMMPS: source/lmp/**/* Gromacs: source/gmx/**/* -i-Pi: source/ipi/**/* \ No newline at end of file +i-Pi: source/ipi/**/* diff --git a/.github/workflows/build_cc.yml b/.github/workflows/build_cc.yml index b6547e2c09..f96cff2f03 100644 --- a/.github/workflows/build_cc.yml +++ b/.github/workflows/build_cc.yml @@ -3,26 +3,50 @@ on: pull_request: name: Build C++ jobs: - testpython: + buildcc: name: Build C++ - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest + container: ghcr.io/deepmodeling/deepmd-kit-test-cc:latest strategy: matrix: include: - variant: cpu - variant: cuda + - variant: rocm + - variant: clang steps: - name: work around permission issue run: git config --global --add safe.directory /__w/deepmd-kit/deepmd-kit - uses: actions/checkout@master with: submodules: true - - run: sudo apt update && sudo apt install g++-7 - - run: sudo apt install nvidia-cuda-toolkit + - run: apt-get update && apt-get install -y nvidia-cuda-toolkit if: matrix.variant == 'cuda' + - run: | + apt-get update && apt-get install -y gnupg2 \ + && echo 'deb [arch=amd64] https://repo.radeon.com/rocm/apt/5.3/ jammy main' | tee /etc/apt/sources.list.d/rocm.list \ + && printf 'Package: *\nPin: release o=repo.radeon.com\nPin-Priority: 600' | tee /etc/apt/preferences.d/rocm-pin-600 \ + && curl -s https://repo.radeon.com/rocm/rocm.gpg.key | apt-key add - \ + && apt-get update \ + && apt-get install -y rocm-dev hipcub-dev + if: matrix.variant == 'rocm' + - run: apt-get update && apt-get install -y clang + if: matrix.variant == 'clang' - run: source/install/build_cc.sh env: DP_VARIANT: ${{ matrix.variant }} - CC: gcc-7 - CXX: g++-7 - CONDA_OVERRIDE_CUDA: 11.3 + DOWNLOAD_TENSORFLOW: "FALSE" + if: matrix.variant != 'clang' + - run: source/install/build_cc.sh + env: + DP_VARIANT: cpu + DOWNLOAD_TENSORFLOW: "FALSE" + CC: clang + CXX: clang++ + if: matrix.variant == 'clang' + pass: + name: Pass building C++ + needs: [buildcc] + runs-on: ubuntu-latest + steps: + - run: echo "All jobs passed" diff --git a/.github/workflows/build_wheel.yml b/.github/workflows/build_wheel.yml index 6b749b64fd..c053766b35 100644 --- a/.github/workflows/build_wheel.yml +++ b/.github/workflows/build_wheel.yml @@ -6,64 +6,83 @@ on: jobs: build_wheels: - name: Build wheels on ${{ matrix.os }} + name: Build wheels for cp${{ matrix.python }}-${{ matrix.platform_id }} runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: - os: [ubuntu-18.04] #, windows-latest, macos-latest] - + include: + # linux-64 + - os: ubuntu-latest + python: 310 + platform_id: manylinux_x86_64 + dp_variant: cuda + # macos-x86-64 + - os: macos-latest + python: 310 + platform_id: macosx_x86_64 + dp_variant: cpu + # win-64 + - os: windows-2019 + python: 310 + platform_id: win_amd64 + dp_variant: cpu + # linux-aarch64 + - os: ubuntu-latest + python: 310 + platform_id: manylinux_aarch64 + dp_variant: cpu steps: - - name: work around permission issue - run: git config --global --add safe.directory /__w/deepmd-kit/deepmd-kit - uses: actions/checkout@v2 + with: + submodules: true + - uses: docker/setup-qemu-action@v2 + name: Setup QEMU + if: matrix.platform_id == 'manylinux_aarch64' - uses: actions/setup-python@v2 name: Install Python with: python-version: '3.8' - - name: Install cibuildwheel - run: | - python -m pip install cibuildwheel - + - run: python -m pip install cibuildwheel==2.11.3 - name: Build wheels + run: python -m cibuildwheel --output-dir wheelhouse env: - CIBW_BUILD: "cp36-* cp37-* cp38-* cp39-* cp310-*" - CIBW_MANYLINUX_X86_64_IMAGE: ghcr.io/deepmodeling/manylinux_2_28_x86_64_tensorflow - CIBW_BEFORE_BUILD: pip install tensorflow - CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux*" - run: | - python -m cibuildwheel --output-dir wheelhouse + CIBW_BUILD_VERBOSITY: 1 + CIBW_ARCHS: all + CIBW_BUILD: cp${{ matrix.python }}-${{ matrix.platform_id }} + DP_VARIANT: ${{ matrix.dp_variant }} - uses: actions/upload-artifact@v2 with: path: ./wheelhouse/*.whl - build_sdist: name: Build source distribution runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + with: + submodules: true + - uses: actions/setup-python@v4 name: Install Python with: - python-version: '3.8' - - run: pip install -U scikit-build tensorflow setuptools_scm + python-version: '3.10' + - run: python -m pip install build - name: Build sdist - run: python setup.py sdist + run: python -m build --sdist - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: path: dist/*.tar.gz upload_pypi: needs: [build_wheels, build_sdist] runs-on: ubuntu-latest - if: startsWith(github.event.ref, 'refs/tags/v') + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v') steps: - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v3 with: name: artifact path: dist - - uses: pypa/gh-action-pypi-publish@master with: user: __token__ diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 91905cc258..c41416b181 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -18,7 +18,7 @@ jobs: with: python-version: ${{ matrix.python }} - name: Install requirements - run: pip install -r requirements.txt + run: pip install . - uses: marian-code/python-lint-annotate@v2.5.0 with: python-root-list: "./deepmd/*.py ./deepmd/*/*.py ./deepmd/*/*/*.py ./source/train/*.py ./source/tests/*.py ./source/op/*.py" diff --git a/.github/workflows/package_c.yml b/.github/workflows/package_c.yml new file mode 100644 index 0000000000..e57c0a30e1 --- /dev/null +++ b/.github/workflows/package_c.yml @@ -0,0 +1,26 @@ +name: Build C library + +on: + push: + pull_request: + +jobs: + build_c: + name: Build C library + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + - name: Package C library + run: ./source/install/docker_package_c.sh + - name: Test C library + run: ./source/install/docker_test_package_c.sh + # for download and debug + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + path: ./libdeepmd_c.tar.gz + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: libdeepmd_c.tar.gz diff --git a/.github/workflows/test_cc.yml b/.github/workflows/test_cc.yml index b000c20ea4..e6e7047aa0 100644 --- a/.github/workflows/test_cc.yml +++ b/.github/workflows/test_cc.yml @@ -3,7 +3,7 @@ on: pull_request: name: Test C++ jobs: - testpython: + testcc: name: Test C++ runs-on: ubuntu-latest container: ghcr.io/deepmodeling/deepmd-kit-test-cc:latest @@ -13,5 +13,31 @@ jobs: - uses: actions/checkout@master - run: source/install/test_cc_local.sh env: + OMP_NUM_THREADS: 1 + TF_INTRA_OP_PARALLELISM_THREADS: 1 + TF_INTER_OP_PARALLELISM_THREADS: 1 tensorflow_root: /usr/local - - run: source/install/codecov.sh + # test lammps + - run: apt-get update && apt-get install -y python3-pip python3-venv + - run: source/install/build_lammps.sh + - run: | + python -m pip install -U pip + python -m pip install -e .[cpu,test] + env: + DP_BUILD_TESTING: 1 + - run: pytest --cov=deepmd source/lmp/tests + env: + OMP_NUM_THREADS: 1 + TF_INTRA_OP_PARALLELISM_THREADS: 1 + TF_INTER_OP_PARALLELISM_THREADS: 1 + LAMMPS_PLUGIN_PATH: ${{ github.workspace }}/dp_test/lib/deepmd_lmp + LD_LIBRARY_PATH: ${{ github.workspace }}/dp_test/lib + - uses: codecov/codecov-action@v3 + with: + gcov: true + pass: + name: Pass testing C++ + needs: [testcc] + runs-on: ubuntu-latest + steps: + - run: echo "All jobs passed" diff --git a/.github/workflows/test_python.yml b/.github/workflows/test_python.yml index 962fd8ccab..6ad27a9a22 100644 --- a/.github/workflows/test_python.yml +++ b/.github/workflows/test_python.yml @@ -5,25 +5,10 @@ name: Test Python jobs: testpython: name: Test Python - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest strategy: matrix: include: - - python: 3.6 - gcc: 4.8 - tf: 1.8 - - python: 3.6 - gcc: 4.8 - tf: 1.12 - - python: 3.6 - gcc: 4.8 - tf: 1.14 - - python: 3.6 - gcc: 5 - tf: 1.14 - - python: 3.6 - gcc: 8 - tf: 1.14 - python: 3.7 gcc: 5 tf: 1.14 @@ -54,20 +39,21 @@ jobs: - name: work around permission issue run: git config --global --add safe.directory /__w/deepmd-kit/deepmd-kit - uses: actions/checkout@master - - name: pip cache - uses: actions/cache@v2 - with: - path: ~/.cache/pip - key: - ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - run: python -m pip install -U pip>=21.3.1 - - run: pip install -e .[cpu,test] codecov + - run: pip install -e .[cpu,test] env: CC: gcc-${{ matrix.gcc }} CXX: g++-${{ matrix.gcc }} TENSORFLOW_VERSION: ${{ matrix.tf }} - SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" + DP_BUILD_TESTING: 1 - run: dp --version - - run: pytest --cov=deepmd source/tests && codecov + - run: pytest --cov=deepmd source/tests --durations=0 + - uses: codecov/codecov-action@v3 + with: + gcov: true + pass: + name: Pass testing Python + needs: [testpython] + runs-on: ubuntu-latest + steps: + - run: echo "All jobs passed" diff --git a/.gitignore b/.gitignore index da04490d85..470c2ee21e 100644 --- a/.gitignore +++ b/.gitignore @@ -29,10 +29,16 @@ _templates API_CC doc/api_py/ doc/api_core/ +doc/api_c/ dp/ dp_test/ dp_test_cc/ +dp_test_c/ +dp_c/ build_lammps/ .idea/ build_tests/ build_cc_tests +build_c_tests +build_c/ +libdeepmd_c/ diff --git a/README.md b/README.md index 6f72f21c14..934d78eaf6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![doi:10.1016/j.cpc.2018.03.016](https://img.shields.io/badge/DOI-10.1016%2Fj.cpc.2018.03.016-blue)](https://doi.org/10.1016/j.cpc.2020.107206) ![Citations](https://citations.njzjz.win/10.1016/j.cpc.2018.03.016) [![offline packages](https://img.shields.io/github/downloads/deepmodeling/deepmd-kit/total?label=offline%20packages)](https://github.com/deepmodeling/deepmd-kit/releases) -[![conda install](https://img.shields.io/badge/downloads-9k%20total-green.svg?style=round-square&label=conda%20install)](https://anaconda.org/deepmodeling/deepmd-kit) +[![conda-forge](https://img.shields.io/conda/dn/conda-forge/deepmd-kit?color=red&label=conda-forge&logo=conda-forge)](https://anaconda.org/conda-forge/deepmd-kit) [![pip install](https://img.shields.io/pypi/dm/deepmd-kit?label=pip%20install)](https://pypi.org/project/deepmd-kit) [![docker pull](https://img.shields.io/docker/pulls/deepmodeling/deepmd-kit)](https://hub.docker.com/r/deepmodeling/deepmd-kit) [![Documentation Status](https://readthedocs.org/projects/deepmd/badge/)](https://deepmd.readthedocs.io/) @@ -21,25 +21,25 @@ - [Troubleshooting](#troubleshooting) # About DeePMD-kit -DeePMD-kit is a package written in Python/C++, designed to minimize the effort required to build deep learning based model of interatomic potential energy and force field and to perform molecular dynamics (MD). This brings new hopes to addressing the accuracy-versus-efficiency dilemma in molecular simulations. Applications of DeePMD-kit span from finite molecules to extended systems and from metallic systems to chemically bonded systems. +DeePMD-kit is a package written in Python/C++, designed to minimize the effort required to build deep learning-based model of interatomic potential energy and force field and to perform molecular dynamics (MD). This brings new hopes to addressing the accuracy-versus-efficiency dilemma in molecular simulations. Applications of DeePMD-kit span from finite molecules to extended systems and from metallic systems to chemically bonded systems. For more information, check the [documentation](https://deepmd.readthedocs.io/). # Highlights in DeePMD-kit v2.0 -* [Model compression](doc/freeze/compress.md). Accelerate the efficiency of model inference for 4-15 times. +* [Model compression](doc/freeze/compress.md). Accelerate the efficiency of model inference 4-15 times. * [New descriptors](doc/model/overall.md). Including [`se_e2_r`](doc/model/train-se-e2-r.md) and [`se_e3`](doc/model/train-se-e3.md). -* [Hybridization of descriptors](doc/model/train-hybrid.md). Hybrid descriptor constructed from concatenation of several descriptors. -* [Atom type embedding](doc/model/train-se-e2-a-tebd.md). Enable atom type embedding to decline training complexity and refine performance. -* Training and inference the dipole (vector) and polarizability (matrix). +* [Hybridization of descriptors](doc/model/train-hybrid.md). Hybrid descriptor constructed from the concatenation of several descriptors. +* [Atom type embedding](doc/model/train-se-e2-a-tebd.md). Enable atom-type embedding to decline training complexity and refine performance. +* Training and inference of the dipole (vector) and polarizability (matrix). * Split of training and validation dataset. * Optimized training on GPUs. ## Highlighted features -* **interfaced with TensorFlow**, one of the most popular deep learning frameworks, making the training process highly automatic and efficient, in addition Tensorboard can be used to visualize training procedure. +* **interfaced with TensorFlow**, one of the most popular deep learning frameworks, making the training process highly automatic and efficient, in addition, Tensorboard can be used to visualize training procedures. * **interfaced with high-performance classical MD and quantum (path-integral) MD packages**, i.e., LAMMPS and i-PI, respectively. -* **implements the Deep Potential series models**, which have been successfully applied to finite and extended systems including organic molecules, metals, semiconductors, and insulators, etc. -* **implements MPI and GPU supports**, makes it highly efficient for high performance parallel and distributed computing. -* **highly modularized**, easy to adapt to different descriptors for deep learning based potential energy models. +* **implements the Deep Potential series models**, which have been successfully applied to finite and extended systems including organic molecules, metals, semiconductors, insulators, etc. +* **implements MPI and GPU supports**, making it highly efficient for high-performance parallel and distributed computing. +* **highly modularized**, easy to adapt to different descriptors for deep learning-based potential energy models. ## License and credits The project DeePMD-kit is licensed under [GNU LGPLv3.0](./LICENSE). @@ -47,11 +47,11 @@ If you use this code in any future publications, please cite this using ``Han Wang, Linfeng Zhang, Jiequn Han, and Weinan E. "DeePMD-kit: A deep learning package for many-body potential energy representation and molecular dynamics." Computer Physics Communications 228 (2018): 178-184.`` ## Deep Potential in a nutshell -The goal of Deep Potential is to employ deep learning techniques and realize an inter-atomic potential energy model that is general, accurate, computationally efficient and scalable. The key component is to respect the extensive and symmetry-invariant properties of a potential energy model by assigning a local reference frame and a local environment to each atom. Each environment contains a finite number of atoms, whose local coordinates are arranged in a symmetry preserving way. These local coordinates are then transformed, through a sub-network, to a so-called *atomic energy*. Summing up all the atomic energies gives the potential energy of the system. +The goal of Deep Potential is to employ deep learning techniques and realize an inter-atomic potential energy model that is general, accurate, computationally efficient and scalable. The key component is to respect the extensive and symmetry-invariant properties of a potential energy model by assigning a local reference frame and a local environment to each atom. Each environment contains a finite number of atoms, whose local coordinates are arranged in a symmetry-preserving way. These local coordinates are then transformed, through a sub-network, to so-called *atomic energy*. Summing up all the atomic energies gives the potential energy of the system. The initial proof of concept is in the [Deep Potential][1] paper, which employed an approach that was devised to train the neural network model with the potential energy only. With typical *ab initio* molecular dynamics (AIMD) datasets this is insufficient to reproduce the trajectories. The Deep Potential Molecular Dynamics ([DeePMD][2]) model overcomes this limitation. In addition, the learning process in DeePMD improves significantly over the Deep Potential method thanks to the introduction of a flexible family of loss functions. The NN potential constructed in this way reproduces accurately the AIMD trajectories, both classical and quantum (path integral), in extended and finite systems, at a cost that scales linearly with system size and is always several orders of magnitude lower than that of equivalent AIMD simulations. -Although being highly efficient, the original Deep Potential model satisfies the extensive and symmetry-invariant properties of a potential energy model at the price of introducing discontinuities in the model. This has negligible influence on a trajectory from canonical sampling but might not be sufficient for calculations of dynamical and mechanical properties. These points motivated us to develop the Deep Potential-Smooth Edition ([DeepPot-SE][3]) model, which replaces the non-smooth local frame with a smooth and adaptive embedding network. DeepPot-SE shows great ability in modeling many kinds of systems that are of interests in the fields of physics, chemistry, biology, and materials science. +Although highly efficient, the original Deep Potential model satisfies the extensive and symmetry-invariant properties of a potential energy model at the price of introducing discontinuities in the model. This has negligible influence on a trajectory from canonical sampling but might not be sufficient for calculations of dynamical and mechanical properties. These points motivated us to develop the Deep Potential-Smooth Edition ([DeepPot-SE][3]) model, which replaces the non-smooth local frame with a smooth and adaptive embedding network. DeepPot-SE shows great ability in modeling many kinds of systems that are of interest in the fields of physics, chemistry, biology, and materials science. In addition to building up potential energy models, DeePMD-kit can also be used to build up coarse-grained models. In these models, the quantity that we want to parameterize is the free energy, or the coarse-grained potential, of the coarse-grained particles. See the [DeePCG paper][4] for more details. @@ -59,14 +59,14 @@ In addition to building up potential energy models, DeePMD-kit can also be used Please follow our [GitHub](https://github.com/deepmodeling/deepmd-kit) webpage to download the [latest released version](https://github.com/deepmodeling/deepmd-kit/tree/master) and [development version](https://github.com/deepmodeling/deepmd-kit/tree/devel). -DeePMD-kit offers multiple installation methods. It is recommend using easily methods like [offline packages](doc/install/easy-install.md#offline-packages), [conda](doc/install/easy-install.md#with-conda) and [docker](doc/install/easy-install.md#with-docker). +DeePMD-kit offers multiple installation methods. It is recommended to use easy methods like [offline packages](doc/install/easy-install.md#offline-packages), [conda](doc/install/easy-install.md#with-conda) and [docker](doc/install/easy-install.md#with-docker). -One may manually install DeePMD-kit by following the instuctions on [installing the Python interface](doc/install/install-from-source.md#install-the-python-interface) and [installing the C++ interface](doc/install/install-from-source.md#install-the-c-interface). The C++ interface is necessary when using DeePMD-kit with LAMMPS, i-PI or GROMACS. +One may manually install DeePMD-kit by following the instructions on [installing the Python interface](doc/install/install-from-source.md#install-the-python-interface) and [installing the C++ interface](doc/install/install-from-source.md#install-the-c-interface). The C++ interface is necessary when using DeePMD-kit with LAMMPS, i-PI or GROMACS. # Use DeePMD-kit -A quick-start on using DeePMD-kit can be found as follows: +A quick start on using DeePMD-kit can be found as follows: - [Prepare data with dpdata](doc/data/dpdata.md) - [Training a model](doc/train/training.md) @@ -106,6 +106,7 @@ A full [document](doc/train/train-input-auto.rst) on options in the training inp - [Training a model](doc/train/training.md) - [Advanced options](doc/train/training-advanced.md) - [Parallel training](doc/train/parallel-training.md) + - [Multi-task training](doc/train/multi-task-training.md) - [TensorBoard Usage](doc/train/tensorboard.md) - [Known limitations of using GPUs](doc/train/gpu-limitations.md) - [Training Parameters](doc/train/train-input-auto.rst) @@ -139,20 +140,20 @@ The code is organized as follows: * `source/lib`: source code of DeePMD-kit library. * `source/lmp`: source code of Lammps module. * `source/gmx`: source code of Gromacs plugin. -* `source/op`: tensorflow op implementation. working with library. +* `source/op`: TensorFlow op implementation. working with the library. # Troubleshooting - [Model compatibility](doc/troubleshooting/model_compatability.md) - [Installation](doc/troubleshooting/installation.md) -- [The temperature undulates violently during early stages of MD](doc/troubleshooting/md_energy_undulation.md) +- [The temperature undulates violently during the early stages of MD](doc/troubleshooting/md_energy_undulation.md) - [MD: cannot run LAMMPS after installing a new version of DeePMD-kit](doc/troubleshooting/md_version_compatibility.md) - [Do we need to set rcut < half boxsize?](doc/troubleshooting/howtoset_rcut.md) - [How to set sel?](doc/troubleshooting/howtoset_sel.md) -- [How to control the number of nodes used by a job?](doc/troubleshooting/howtoset_num_nodes.md) +- [How to control the parallelism of a job?](doc/troubleshooting/howtoset_num_nodes.md) - [How to tune Fitting/embedding-net size?](doc/troubleshooting/howtoset_netsize.md) - +- [Why does a model have low precision?](doc/troubleshooting/precision.md) # Contributing diff --git a/backend/dp_backend.py b/backend/dp_backend.py new file mode 100644 index 0000000000..71b8046d6e --- /dev/null +++ b/backend/dp_backend.py @@ -0,0 +1,34 @@ +"""A PEP-517 backend to find TensorFlow.""" +from typing import List +# TODO: switch to scikit_build_core after it is available +from setuptools import build_meta as _orig + +from find_tensorflow import find_tensorflow + +__all__ = [ + "build_sdist", + "build_wheel", + "get_requires_for_build_sdist", + "get_requires_for_build_wheel", + "prepare_metadata_for_build_wheel", +] + + +def __dir__() -> List[str]: + return __all__ + + +prepare_metadata_for_build_wheel = _orig.prepare_metadata_for_build_wheel +build_wheel = _orig.build_wheel +build_sdist = _orig.build_sdist +get_requires_for_build_sdist = _orig.get_requires_for_build_sdist + +def get_requires_for_build_wheel( + config_settings: dict, +) -> List[str]: + return _orig.get_requires_for_build_wheel(config_settings) + find_tensorflow()[1] + +# TODO: export get_requires_for_build_editable, prepare_metadata_for_build_editable, build_editable +# after scikit-build is ready +# See https://github.com/scikit-build/scikit-build/issues/740 +# Now we use the legacy-editable mode diff --git a/backend/find_tensorflow.py b/backend/find_tensorflow.py new file mode 100644 index 0000000000..d0998d0460 --- /dev/null +++ b/backend/find_tensorflow.py @@ -0,0 +1,133 @@ +import site +import os +from importlib.util import find_spec +from importlib.machinery import FileFinder +from sysconfig import get_path +from pathlib import Path +from typing import List, Optional, Tuple, Union +from packaging.specifiers import SpecifierSet + + +def find_tensorflow() -> Tuple[Optional[str], List[str]]: + """Find TensorFlow library. + + Tries to find TensorFlow in the order of: + + 1. Environment variable `TENSORFLOW_ROOT` if set + 2. The current Python environment. + 3. user site packages directory if enabled + 4. system site packages directory (purelib) + 5. add as a requirement (detect TENSORFLOW_VERSION or the latest) and let pip install it + + Parameters + ---------- + config_settings : dict + Configuration settings from pip. + + Returns + ------- + str + TensorFlow library path if found. + list of str + TensorFlow requirement if not found. Empty if found. + """ + requires = [] + + tf_spec = None + if os.environ.get("TENSORFLOW_ROOT") is not None: + site_packages = Path(os.environ.get("TENSORFLOW_ROOT")).parent.absolute() + tf_spec = FileFinder(str(site_packages)).find_spec("tensorflow") + + # get tensorflow spec + # note: isolated build will not work for backend + if tf_spec is None or not tf_spec: + tf_spec = find_spec("tensorflow") + + if not tf_spec and site.ENABLE_USER_SITE: + # first search TF from user site-packages before global site-packages + site_packages = site.getusersitepackages() + if site_packages: + tf_spec = FileFinder(site_packages).find_spec("tensorflow") + + if not tf_spec: + # purelib gets site-packages path + site_packages = get_path("purelib") + if site_packages: + tf_spec = FileFinder(site_packages).find_spec("tensorflow") + + # get install dir from spec + try: + tf_install_dir = tf_spec.submodule_search_locations[0] # type: ignore + # AttributeError if ft_spec is None + # TypeError if submodule_search_locations are None + # IndexError if submodule_search_locations is an empty list + except (AttributeError, TypeError, IndexError): + requires.extend(get_tf_requirement()['cpu']) + # setuptools will re-find tensorflow after installing setup_requires + tf_install_dir = None + return tf_install_dir, requires + + +def get_tf_requirement(tf_version: str = "") -> dict: + """Get TensorFlow requirement (CPU) when TF is not installed. + + If tf_version is not given and the environment variable `TENSORFLOW_VERSION` is set, use it as the requirement. + + Parameters + ---------- + tf_version : str, optional + TF version + + Returns + ------- + dict + TensorFlow requirement, including cpu and gpu. + """ + if tf_version == "": + tf_version = os.environ.get("TENSORFLOW_VERSION", "") + + if tf_version == "": + return { + "cpu": ["tensorflow-cpu; platform_machine!='aarch64'", "tensorflow; platform_machine=='aarch64'"], + "gpu": ["tensorflow; platform_machine!='aarch64'", "tensorflow; platform_machine=='aarch64'"], + } + elif tf_version in SpecifierSet("<1.15") or tf_version in SpecifierSet(">=2.0,<2.1"): + return { + "cpu": [f"tensorflow=={tf_version}; platform_machine!='aarch64'", f"tensorflow=={tf_version}; platform_machine=='aarch64'"], + "gpu": [f"tensorflow-gpu=={tf_version}; platform_machine!='aarch64'", f"tensorflow=={tf_version}; platform_machine=='aarch64'"], + } + else: + return { + "cpu": [f"tensorflow-cpu=={tf_version}; platform_machine!='aarch64'", f"tensorflow=={tf_version}; platform_machine=='aarch64'"], + "gpu": [f"tensorflow=={tf_version}; platform_machine!='aarch64'", f"tensorflow=={tf_version}; platform_machine=='aarch64'"], + } + + +def get_tf_version(tf_path: Union[str, Path]) -> str: + """Get TF version from a TF Python library path. + + Parameters + ---------- + tf_path : str or Path + TF Python library path + + Returns + ------- + str + version + """ + if tf_path is None or tf_path == "": + return "" + version_file = Path(tf_path) / "include" / "tensorflow" / "core" / "public" / "version.h" + major = minor = patch = None + with open(version_file) as f: + for line in f: + if line.startswith("#define TF_MAJOR_VERSION"): + major = line.split()[-1] + elif line.startswith("#define TF_MINOR_VERSION"): + minor = line.split()[-1] + elif line.startswith("#define TF_PATCH_VERSION"): + patch = line.split()[-1] + if None in (major, minor, patch): + raise RuntimeError("Failed to read TF version") + return ".".join((major, minor, patch)) diff --git a/deepmd/.gitignore b/deepmd/.gitignore index 8db60db5b8..5ac6bafb1c 100644 --- a/deepmd/.gitignore +++ b/deepmd/.gitignore @@ -1,3 +1,4 @@ op/_*.py pkg_config +run_config.ini !op/__init__.py \ No newline at end of file diff --git a/deepmd/__init__.py b/deepmd/__init__.py index 9fe29b6d9c..25e94757fc 100644 --- a/deepmd/__init__.py +++ b/deepmd/__init__.py @@ -19,7 +19,11 @@ from .__about__ import __version__ # load third-party plugins -for ep in metadata.entry_points().get('deepmd', []): +try: + eps = metadata.entry_points(group='deepmd') +except TypeError: + eps = metadata.entry_points().get('deepmd', []) +for ep in eps: ep.load() __all__ = [ diff --git a/deepmd/cluster/local.py b/deepmd/cluster/local.py index 6fe454a9a2..69af55040d 100644 --- a/deepmd/cluster/local.py +++ b/deepmd/cluster/local.py @@ -21,6 +21,10 @@ def get_gpus(): Optional[List[int]] List of available GPU IDs. Otherwise, None. """ + if (not tf.test.is_built_with_cuda() and + not (hasattr(tf.test, 'is_built_with_rocm') and tf.test.is_built_with_rocm())): + # TF is built with CPU only, skip expensive subprocess call + return None test_cmd = 'from tensorflow.python.client import device_lib; ' \ 'devices = device_lib.list_local_devices(); ' \ 'gpus = [d.name for d in devices if d.device_type == "GPU"]; ' \ diff --git a/deepmd/common.py b/deepmd/common.py index 76c76bbf1e..a1628644c7 100644 --- a/deepmd/common.py +++ b/deepmd/common.py @@ -43,6 +43,7 @@ "float16": tf.float16, "float32": tf.float32, "float64": tf.float64, + "bfloat16": tf.bfloat16, } @@ -118,7 +119,7 @@ def add_data_requirement( atomic: bool = False, must: bool = False, high_prec: bool = False, - type_sel: bool = None, + type_sel: Optional[bool] = None, repeat: int = 1, default: float = 0., ): @@ -211,141 +212,6 @@ def make_default_mesh( return default_mesh -# TODO not an ideal approach, every class uses this to parse arguments on its own, json -# TODO should be parsed once and the parsed result passed to all objects that need it -class ClassArg: - """Class that take care of input json/yaml parsing. - - The rules for parsing are defined by the `add` method, than `parse` is called to - process the supplied dict - - Attributes - ---------- - arg_dict: Dict[str, Any] - dictionary containing parsing rules - alias_map: Dict[str, Any] - dictionary with keyword aliases - """ - - def __init__(self) -> None: - self.arg_dict = {} - self.alias_map = {} - - def add( - self, - key: str, - types_: Union[type, List[type]], - alias: Optional[Union[str, List[str]]] = None, - default: Any = None, - must: bool = False, - ) -> "ClassArg": - """Add key to be parsed. - - Parameters - ---------- - key : str - key name - types_ : Union[type, List[type]] - list of allowed key types - alias : Optional[Union[str, List[str]]], optional - alias for the key, by default None - default : Any, optional - default value for the key, by default None - must : bool, optional - if the key is mandatory, by default False - - Returns - ------- - ClassArg - instance with added key - """ - if not isinstance(types_, list): - types = [types_] - else: - types = types_ - if alias is not None: - if not isinstance(alias, list): - alias_ = [alias] - else: - alias_ = alias - else: - alias_ = [] - - self.arg_dict[key] = { - "types": types, - "alias": alias_, - "value": default, - "must": must, - } - for ii in alias_: - self.alias_map[ii] = key - - return self - - def _add_single(self, key: str, data: Any): - vtype = type(data) - if data is None: - return data - if not (vtype in self.arg_dict[key]["types"]): - for tp in self.arg_dict[key]["types"]: - try: - vv = tp(data) - except TypeError: - pass - else: - break - else: - raise TypeError( - f"cannot convert provided key {key} to type(s) " - f'{self.arg_dict[key]["types"]} ' - ) - else: - vv = data - self.arg_dict[key]["value"] = vv - - def _check_must(self): - for kk in self.arg_dict: - if self.arg_dict[kk]["must"] and self.arg_dict[kk]["value"] is None: - raise RuntimeError(f"key {kk} must be provided") - - def parse(self, jdata: Dict[str, Any]) -> Dict[str, Any]: - """Parse input dictionary, use the rules defined by add method. - - Parameters - ---------- - jdata : Dict[str, Any] - loaded json/yaml data - - Returns - ------- - Dict[str, Any] - parsed dictionary - """ - for kk in jdata.keys(): - if kk in self.arg_dict: - key = kk - self._add_single(key, jdata[kk]) - else: - if kk in self.alias_map: - key = self.alias_map[kk] - self._add_single(key, jdata[kk]) - self._check_must() - return self.get_dict() - - def get_dict(self) -> Dict[str, Any]: - """Get dictionary built from rules defined by add method. - - Returns - ------- - Dict[str, Any] - settings dictionary with default values - """ - ret = {} - for kk in self.arg_dict.keys(): - ret[kk] = self.arg_dict[kk]["value"] - return ret - - # TODO maybe rename this to j_deprecated and only warn about deprecated keys, # TODO if the deprecated_key argument is left empty function puppose is only custom # TODO error since dict[key] already raises KeyError when the key is missing @@ -577,3 +443,10 @@ def wrapper(self, *args, **kwargs): else: return safe_cast_tensor(returned_tensor, self.precision, GLOBAL_TF_FLOAT_PRECISION) return wrapper + + +def clear_session(): + """Reset all state generated by DeePMD-kit.""" + tf.reset_default_graph() + # TODO: remove this line when data_requirement is not a global variable + data_requirement.clear() diff --git a/deepmd/descriptor/descriptor.py b/deepmd/descriptor/descriptor.py index 219b21172b..a024783ec4 100644 --- a/deepmd/descriptor/descriptor.py +++ b/deepmd/descriptor/descriptor.py @@ -1,8 +1,8 @@ from abc import ABC, abstractmethod -from typing import Any, Dict, List, Tuple +from typing import Optional, Any, Dict, List, Tuple import numpy as np -from deepmd.env import tf +from deepmd.env import tf, GLOBAL_TF_FLOAT_PRECISION from deepmd.utils import Plugin, PluginVariant @@ -185,7 +185,7 @@ def build(self, box_: tf.Tensor, mesh: tf.Tensor, input_dict: Dict[str, Any], - reuse: bool = None, + reuse: Optional[bool] = None, suffix: str = '', ) -> tf.Tensor: """ @@ -227,7 +227,8 @@ def build(self, def enable_compression(self, min_nbor_dist: float, - model_file: str = 'frozon_model.pb', + graph: tf.Graph, + graph_def: tf.GraphDef, table_extrapolate: float = 5., table_stride_1: float = 0.01, table_stride_2: float = 0.1, @@ -242,8 +243,10 @@ def enable_compression(self, ---------- min_nbor_dist : float The nearest distance between atoms - model_file : str, default: 'frozon_model.pb' - The original frozen model, which will be compressed by the program + graph : tf.Graph + The graph of the model + graph_def : tf.GraphDef + The graph definition of the model table_extrapolate : float, default: 5. The scale of model extrapolation table_stride_1 : float, default: 0.01 @@ -262,7 +265,7 @@ def enable_compression(self, raise NotImplementedError( "Descriptor %s doesn't support compression!" % type(self).__name__) - def enable_mixed_precision(self, mixed_prec: dict = None) -> None: + def enable_mixed_precision(self, mixed_prec: Optional[dict] = None) -> None: """ Reveive the mixed precision setting. @@ -406,3 +409,92 @@ def pass_tensors_from_frz_model(self, :meth:`get_tensor_names`. """ raise NotImplementedError("Descriptor %s doesn't support this method!" % type(self).__name__) + + def build_type_exclude_mask(self, + exclude_types: List[Tuple[int, int]], + ntypes: int, + sel: List[int], + ndescrpt: int, + atype: tf.Tensor, + shape0: tf.Tensor) -> tf.Tensor: + r"""Build the type exclude mask for the descriptor. + + Notes + ----- + To exclude the interaction between two types, the derivative of energy with + respect to distances (or angles) between two atoms should be zero[1]_, i.e. + + .. math:: + \forall i \in \text{type 1}, j \in \text{type 2}, + \frac{\partial{E}}{\partial{r_{ij}}} = 0 + + When embedding networks between every two types are built, we can just remove + that network. But when `type_one_side` is enabled, a network may be built for + multiple pairs of types. In this case, we need to build a mask to exclude the + interaction between two types. + + The mask assumes the descriptors are sorted by neighbro type with the fixed + number of given `sel` and each neighbor has the same number of descriptors + (for example 4). + + Parameters + ---------- + exclude_types : List[Tuple[int, int]] + The list of excluded types, e.g. [(0, 1), (1, 0)] means the interaction + between type 0 and type 1 is excluded. + ntypes : int + The number of types. + sel : List[int] + The list of the number of selected neighbors for each type. + ndescrpt : int + The number of descriptors for each atom. + atype : tf.Tensor + The type of atoms, with the size of shape0. + shape0 : tf.Tensor + The shape of the first dimension of the inputs, which is equal to + nsamples * natoms. + + Returns + ------- + tf.Tensor + The type exclude mask, with the shape of (shape0, ndescrpt), and the + precision of GLOBAL_TF_FLOAT_PRECISION. The mask has the value of 1 if the + interaction between two types is not excluded, and 0 otherwise. + + References + ---------- + .. [1] Jinzhe Zeng, Timothy J. Giese, ̧Sölen Ekesan, Darrin M. York, + Development of Range-Corrected Deep Learning Potentials for Fast, + Accurate Quantum Mechanical/molecular Mechanical Simulations of + Chemical Reactions in Solution, J. Chem. Theory Comput., 2021, + 17 (11), 6993-7009. + """ + # generate a mask + type_mask = np.array([ + [1 if (tt_i, tt_j) not in exclude_types else 0 + for tt_i in range(ntypes)] + for tt_j in range(ntypes) + ], dtype = bool) + type_mask = tf.convert_to_tensor(type_mask, dtype = GLOBAL_TF_FLOAT_PRECISION) + type_mask = tf.reshape(type_mask, [-1]) + + # (nsamples * natoms, 1) + atype_expand = tf.reshape(atype, [-1, 1]) + # (nsamples * natoms, ndescrpt) + idx_i = tf.tile(atype_expand * ntypes, (1, ndescrpt)) + ndescrpt_per_neighbor = ndescrpt // np.sum(sel) + # assume the number of neighbors for each type is the same + assert ndescrpt_per_neighbor * np.sum(sel) == ndescrpt + atype_descrpt = np.repeat(np.arange(ntypes), np.array(sel) * ndescrpt_per_neighbor) + atype_descrpt = tf.convert_to_tensor(atype_descrpt, dtype = tf.int32) + # (1, ndescrpt) + atype_descrpt = tf.reshape(atype_descrpt, (1, ndescrpt)) + # (nsamples * natoms, ndescrpt) + idx_j = tf.tile(atype_descrpt, (shape0, 1)) + # the index to mask (row index * ntypes + col index) + idx = idx_i + idx_j + idx = tf.reshape(idx, [-1]) + mask = tf.nn.embedding_lookup(type_mask, idx) + # same as inputs_i, (nsamples * natoms, ndescrpt) + mask = tf.reshape(mask, [-1, ndescrpt]) + return mask diff --git a/deepmd/descriptor/hybrid.py b/deepmd/descriptor/hybrid.py index d1c188affc..a96be9bc6a 100644 --- a/deepmd/descriptor/hybrid.py +++ b/deepmd/descriptor/hybrid.py @@ -2,7 +2,6 @@ from typing import Tuple, List from deepmd.env import tf -from deepmd.common import ClassArg from deepmd.env import op_module from deepmd.env import GLOBAL_TF_FLOAT_PRECISION from deepmd.env import GLOBAL_NP_FLOAT_PRECISION @@ -30,7 +29,8 @@ class DescrptHybrid (Descriptor): Build a descriptor from the concatenation of the list of descriptors. """ def __init__ (self, - list : list + list : list, + multi_task: bool = False ) -> None : """ Constructor @@ -40,17 +40,16 @@ def __init__ (self, if descrpt_list == [] or descrpt_list is None: raise RuntimeError('cannot build descriptor from an empty list of descriptors.') formatted_descript_list = [] + self.multi_task = multi_task for ii in descrpt_list: if isinstance(ii, Descriptor): formatted_descript_list.append(ii) elif isinstance(ii, dict): + if multi_task: + ii['multi_task'] = True formatted_descript_list.append(Descriptor(**ii)) else: raise NotImplementedError - # args = ClassArg()\ - # .add('list', list, must = True) - # class_data = args.parse(jdata) - # dict_list = class_data['list'] self.descrpt_list = formatted_descript_list self.numb_descrpt = len(self.descrpt_list) for ii in range(1, self.numb_descrpt): @@ -134,7 +133,28 @@ def compute_input_stats (self, """ for ii in self.descrpt_list: ii.compute_input_stats(data_coord, data_box, data_atype, natoms_vec, mesh, input_dict) - + + def merge_input_stats(self, stat_dict): + """ + Merge the statisitcs computed from compute_input_stats to obtain the self.davg and self.dstd. + + Parameters + ---------- + stat_dict + The dict of statisitcs computed from compute_input_stats, including: + sumr + The sum of radial statisitcs. + suma + The sum of relative coord statisitcs. + sumn + The sum of neighbor numbers. + sumr2 + The sum of square of radial statisitcs. + suma2 + The sum of square of relative coord statisitcs. + """ + for ii in self.descrpt_list: + ii.merge_input_stats(stat_dict) def build (self, coord_ : tf.Tensor, @@ -233,7 +253,8 @@ def prod_force_virial(self, def enable_compression(self, min_nbor_dist: float, - model_file: str = 'frozon_model.pb', + graph: tf.Graph, + graph_def: tf.GraphDef, table_extrapolate: float = 5., table_stride_1: float = 0.01, table_stride_2: float = 0.1, @@ -248,8 +269,10 @@ def enable_compression(self, ---------- min_nbor_dist : float The nearest distance between atoms - model_file : str, default: 'frozon_model.pb' - The original frozen model, which will be compressed by the program + graph : tf.Graph + The graph of the model + graph_def : tf.GraphDef + The graph_def of the model table_extrapolate : float, default: 5. The scale of model extrapolation table_stride_1 : float, default: 0.01 @@ -262,7 +285,7 @@ def enable_compression(self, The suffix of the scope """ for idx, ii in enumerate(self.descrpt_list): - ii.enable_compression(min_nbor_dist, model_file, table_extrapolate, table_stride_1, table_stride_2, check_frequency, suffix=f"{suffix}_{idx}") + ii.enable_compression(min_nbor_dist, graph, graph_def, table_extrapolate, table_stride_1, table_stride_2, check_frequency, suffix=f"{suffix}_{idx}") def enable_mixed_precision(self, mixed_prec : dict = None) -> None: diff --git a/deepmd/descriptor/loc_frame.py b/deepmd/descriptor/loc_frame.py index f956d5ef36..d96b38385c 100644 --- a/deepmd/descriptor/loc_frame.py +++ b/deepmd/descriptor/loc_frame.py @@ -33,9 +33,9 @@ class DescrptLocFrame (Descriptor) : - axis_rule[i*6+0]: class of the atom defining the first axis of type-i atom. 0 for neighbors with full coordinates and 1 for neighbors only with relative distance.\n\n\ - axis_rule[i*6+1]: type of the atom defining the first axis of type-i atom.\n\n\ - axis_rule[i*6+2]: index of the axis atom defining the first axis. Note that the neighbors with the same class and type are sorted according to their relative distance.\n\n\ - - axis_rule[i*6+3]: class of the atom defining the first axis of type-i atom. 0 for neighbors with full coordinates and 1 for neighbors only with relative distance.\n\n\ + - axis_rule[i*6+3]: class of the atom defining the second axis of type-i atom. 0 for neighbors with full coordinates and 1 for neighbors only with relative distance.\n\n\ - axis_rule[i*6+4]: type of the atom defining the second axis of type-i atom.\n\n\ - - axis_rule[i*6+5]: class of the atom defining the second axis of type-i atom. 0 for neighbors with full coordinates and 1 for neighbors only with relative distance. + - axis_rule[i*6+5]: index of the axis atom defining the second axis. Note that the neighbors with the same class and type are sorted according to their relative distance. """ def __init__(self, rcut: float, @@ -46,12 +46,6 @@ def __init__(self, """ Constructor """ - # args = ClassArg()\ - # .add('sel_a', list, must = True) \ - # .add('sel_r', list, must = True) \ - # .add('rcut', float, default = 6.0) \ - # .add('axis_rule',list, must = True) - # class_data = args.parse(jdata) self.sel_a = sel_a self.sel_r = sel_r self.axis_rule = axis_rule @@ -99,7 +93,7 @@ def __init__(self, def get_rcut (self) -> float: """ - Returns the cut-off radisu + Returns the cut-off radius """ return self.rcut_r diff --git a/deepmd/descriptor/se_a.py b/deepmd/descriptor/se_a.py index 9b54daaa94..1f92030926 100644 --- a/deepmd/descriptor/se_a.py +++ b/deepmd/descriptor/se_a.py @@ -1,6 +1,6 @@ import math import numpy as np -from typing import Tuple, List, Dict, Any +from typing import Optional, Tuple, List, Dict, Any from deepmd.env import tf from deepmd.common import get_activation_func, get_precision, cast_precision @@ -95,6 +95,8 @@ class DescrptSeA (DescrptSe): The precision of the embedding net parameters. Supported options are |PRECISION| uniform_seed Only for the purpose of backward compatibility, retrieves the old behavior of using the random seed + multi_task + If the model has multi fitting nets to train. References ---------- @@ -111,13 +113,14 @@ def __init__ (self, axis_neuron: int = 8, resnet_dt: bool = False, trainable: bool = True, - seed: int = None, + seed: Optional[int] = None, type_one_side: bool = True, exclude_types: List[List[int]] = [], set_davg_zero: bool = False, activation_function: str = 'tanh', precision: str = 'default', - uniform_seed: bool = False + uniform_seed: bool = False, + multi_task: bool = False ) -> None: """ Constructor @@ -191,7 +194,9 @@ def __init__ (self, sel_r = self.sel_r) self.sub_sess = tf.Session(graph = sub_graph, config=default_tf_session_config) self.original_sel = None - + self.multi_task = multi_task + if multi_task: + self.stat_dict = {'sumr': [], 'suma': [], 'sumn': [], 'sumr2': [], 'suma2': []} def get_rcut (self) -> float: """ @@ -258,8 +263,6 @@ def compute_input_stats (self, input_dict Dictionary for additional input """ - all_davg = [] - all_dstd = [] if True: sumr = [] suma = [] @@ -274,30 +277,61 @@ def compute_input_stats (self, sumn.append(sysn) sumr2.append(sysr2) suma2.append(sysa2) - sumr = np.sum(sumr, axis = 0) - suma = np.sum(suma, axis = 0) - sumn = np.sum(sumn, axis = 0) - sumr2 = np.sum(sumr2, axis = 0) - suma2 = np.sum(suma2, axis = 0) - for type_i in range(self.ntypes) : - davgunit = [sumr[type_i]/(sumn[type_i]+1e-15), 0, 0, 0] - dstdunit = [self._compute_std(sumr2[type_i], sumr[type_i], sumn[type_i]), - self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), - self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), - self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]) - ] - davg = np.tile(davgunit, self.ndescrpt // 4) - dstd = np.tile(dstdunit, self.ndescrpt // 4) - all_davg.append(davg) - all_dstd.append(dstd) + if not self.multi_task: + stat_dict = {'sumr': sumr, 'suma': suma, 'sumn': sumn, 'sumr2': sumr2, 'suma2': suma2} + self.merge_input_stats(stat_dict) + else: + self.stat_dict['sumr'] += sumr + self.stat_dict['suma'] += suma + self.stat_dict['sumn'] += sumn + self.stat_dict['sumr2'] += sumr2 + self.stat_dict['suma2'] += suma2 + def merge_input_stats(self, stat_dict): + """ + Merge the statisitcs computed from compute_input_stats to obtain the self.davg and self.dstd. + + Parameters + ---------- + stat_dict + The dict of statisitcs computed from compute_input_stats, including: + sumr + The sum of radial statisitcs. + suma + The sum of relative coord statisitcs. + sumn + The sum of neighbor numbers. + sumr2 + The sum of square of radial statisitcs. + suma2 + The sum of square of relative coord statisitcs. + """ + all_davg = [] + all_dstd = [] + sumr = np.sum(stat_dict['sumr'], axis = 0) + suma = np.sum(stat_dict['suma'], axis = 0) + sumn = np.sum(stat_dict['sumn'], axis = 0) + sumr2 = np.sum(stat_dict['sumr2'], axis = 0) + suma2 = np.sum(stat_dict['suma2'], axis = 0) + for type_i in range(self.ntypes) : + davgunit = [sumr[type_i]/(sumn[type_i]+1e-15), 0, 0, 0] + dstdunit = [self._compute_std(sumr2[type_i], sumr[type_i], sumn[type_i]), + self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), + self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), + self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]) + ] + davg = np.tile(davgunit, self.ndescrpt // 4) + dstd = np.tile(dstdunit, self.ndescrpt // 4) + all_davg.append(davg) + all_dstd.append(dstd) if not self.set_davg_zero: self.davg = np.array(all_davg) self.dstd = np.array(all_dstd) def enable_compression(self, min_nbor_dist : float, - model_file : str = 'frozon_model.pb', + graph: tf.Graph, + graph_def: tf.GraphDef, table_extrapolate : float = 5, table_stride_1 : float = 0.01, table_stride_2 : float = 0.1, @@ -311,8 +345,10 @@ def enable_compression(self, ---------- min_nbor_dist The nearest distance between atoms - model_file - The original frozen model, which will be compressed by the program + grapf : tf.Graph + The graph of the model + graph_def : tf.GraphDef + The graph_def of the model table_extrapolate The scale of model extrapolation table_stride_1 @@ -344,7 +380,7 @@ def enable_compression(self, self.compress = True self.table = DPTabulate( - self, self.filter_neuron, model_file, self.type_one_side, self.exclude_types, self.compress_activation_fn, suffix=suffix) + self, self.filter_neuron, graph, graph_def, self.type_one_side, self.exclude_types, self.compress_activation_fn, suffix=suffix) self.table_config = [table_extrapolate, table_stride_1, table_stride_2, check_frequency] self.lower, self.upper \ = self.table.build(min_nbor_dist, @@ -352,7 +388,6 @@ def enable_compression(self, table_stride_1, table_stride_2) - graph, _ = load_graph_def(model_file) self.davg = get_tensor_by_name_from_graph(graph, 'descrpt_attr%s/t_avg' % suffix) self.dstd = get_tensor_by_name_from_graph(graph, 'descrpt_attr%s/t_std' % suffix) @@ -556,18 +591,13 @@ def _pass_filter(self, inputs = tf.reshape(inputs, [-1, natoms[0], self.ndescrpt]) output = [] output_qmat = [] - if not (self.type_one_side and len(self.exclude_types) == 0) and type_embedding is None: + if not self.type_one_side and type_embedding is None: for type_i in range(self.ntypes): inputs_i = tf.slice (inputs, [ 0, start_index, 0], [-1, natoms[2+type_i], -1] ) inputs_i = tf.reshape(inputs_i, [-1, self.ndescrpt]) - if self.type_one_side: - # reuse NN parameters for all types to support type_one_side along with exclude_types - reuse = tf.AUTO_REUSE - filter_name = 'filter_type_all'+suffix - else: - filter_name = 'filter_type_'+str(type_i)+suffix + filter_name = 'filter_type_'+str(type_i)+suffix layer, qmat = self._filter(inputs_i, type_i, name=filter_name, natoms=natoms, reuse=reuse, trainable = trainable, activation_fn = self.filter_activation_fn) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[2+type_i], self.get_dim_out()]) qmat = tf.reshape(qmat, [tf.shape(inputs)[0], natoms[2+type_i], self.get_dim_rot_mat_1() * 3]) @@ -580,6 +610,17 @@ def _pass_filter(self, type_i = -1 if nvnmd_cfg.enable and nvnmd_cfg.quantize_descriptor: inputs_i = descrpt2r4(inputs_i, natoms) + if len(self.exclude_types): + mask = self.build_type_exclude_mask( + self.exclude_types, + self.ntypes, + self.sel_a, + self.ndescrpt, + atype, + tf.shape(inputs_i)[0], + ) + inputs_i *= mask + layer, qmat = self._filter(inputs_i, type_i, name='filter_type_all'+suffix, natoms=natoms, reuse=reuse, trainable = trainable, activation_fn = self.filter_activation_fn, type_embedding=type_embedding) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[0], self.get_dim_out()]) qmat = tf.reshape(qmat, [tf.shape(inputs)[0], natoms[0], self.get_dim_rot_mat_1() * 3]) diff --git a/deepmd/descriptor/se_a_ebd.py b/deepmd/descriptor/se_a_ebd.py index 9a6c2b206e..66034078ea 100644 --- a/deepmd/descriptor/se_a_ebd.py +++ b/deepmd/descriptor/se_a_ebd.py @@ -1,8 +1,8 @@ import numpy as np -from typing import Tuple, List +from typing import Optional, Tuple, List from deepmd.env import tf -from deepmd.common import ClassArg, get_activation_func, get_precision, add_data_requirement +from deepmd.common import get_activation_func, get_precision, add_data_requirement from deepmd.utils.network import one_layer from deepmd.env import GLOBAL_TF_FLOAT_PRECISION from deepmd.env import GLOBAL_NP_FLOAT_PRECISION @@ -31,7 +31,7 @@ class DescrptSeAEbd (DescrptSeA): Number of the axis neuron (number of columns of the sub-matrix of the embedding matrix) resnet_dt Time-step `dt` in the resnet construction: - y = x + dt * \phi (Wx + b) + y = x + dt * \\phi (Wx + b) trainable If the weights of embedding net are trainable. seed @@ -62,7 +62,7 @@ def __init__ (self, axis_neuron: int = 8, resnet_dt: bool = False, trainable: bool = True, - seed: int = None, + seed: Optional[int] = None, type_one_side: bool = True, type_nchanl : int = 2, type_nlayer : int = 1, @@ -75,12 +75,6 @@ def __init__ (self, """ Constructor """ - # args = ClassArg()\ - # .add('type_nchanl', int, default = 4) \ - # .add('type_nlayer', int, default = 2) \ - # .add('type_one_side', bool, default = True) \ - # .add('numb_aparam', int, default = 0) - # class_data = args.parse(jdata) DescrptSeA.__init__(self, rcut, rcut_smth, diff --git a/deepmd/descriptor/se_a_ef.py b/deepmd/descriptor/se_a_ef.py index cfe9c25d46..c272ed7491 100644 --- a/deepmd/descriptor/se_a_ef.py +++ b/deepmd/descriptor/se_a_ef.py @@ -1,5 +1,5 @@ import numpy as np -from typing import Tuple, List +from typing import Optional, Tuple, List from deepmd.env import tf from deepmd.common import add_data_requirement @@ -29,7 +29,7 @@ class DescrptSeAEf (Descriptor): Number of the axis neuron (number of columns of the sub-matrix of the embedding matrix) resnet_dt Time-step `dt` in the resnet construction: - y = x + dt * \phi (Wx + b) + y = x + dt * \\phi (Wx + b) trainable If the weights of embedding net are trainable. seed @@ -56,7 +56,7 @@ def __init__(self, axis_neuron: int = 8, resnet_dt: bool = False, trainable: bool = True, - seed: int = None, + seed: Optional[int] = None, type_one_side: bool = True, exclude_types: List[List[int]] = [], set_davg_zero: bool = False, @@ -101,10 +101,10 @@ def __init__(self, precision, uniform_seed, ) - + def get_rcut (self) -> float: """ - Returns the cut-off radisu + Returns the cut-off radius """ return self.descrpt_vert.rcut_r @@ -284,7 +284,7 @@ def __init__ (self, axis_neuron: int = 8, resnet_dt: bool = False, trainable: bool = True, - seed: int = None, + seed: Optional[int] = None, type_one_side: bool = True, exclude_types: List[List[int]] = [], set_davg_zero: bool = False, @@ -309,25 +309,6 @@ def __init__ (self, precision, uniform_seed ) - # DescrptSeA.__init__(self, **jdata) - # args = ClassArg()\ - # .add('sel', list, must = True) \ - # .add('rcut', float, default = 6.0) \ - # .add('rcut_smth',float, default = 5.5) \ - # .add('neuron', list, default = [10, 20, 40]) \ - # .add('axis_neuron', int, default = 4, alias = 'n_axis_neuron') \ - # .add('resnet_dt',bool, default = False) \ - # .add('trainable',bool, default = True) \ - # .add('seed', int) - # class_data = args.parse(jdata) - # self.sel_a = class_data['sel'] - # self.rcut_r = class_data['rcut'] - # self.rcut_r_smth = class_data['rcut_smth'] - # self.filter_neuron = class_data['neuron'] - # self.n_axis_neuron = class_data['axis_neuron'] - # self.filter_resnet_dt = class_data['resnet_dt'] - # self.seed = class_data['seed'] - # self.trainable = class_data['trainable'] self.sel_a = sel self.rcut_r = rcut self.rcut_r_smth = rcut_smth diff --git a/deepmd/descriptor/se_atten.py b/deepmd/descriptor/se_atten.py index ee2ab39a7f..00190672e4 100644 --- a/deepmd/descriptor/se_atten.py +++ b/deepmd/descriptor/se_atten.py @@ -1,6 +1,6 @@ import math import numpy as np -from typing import Tuple, List, Dict, Any +from typing import Optional, Tuple, List, Dict, Any from packaging.version import Version from deepmd.env import tf @@ -38,7 +38,7 @@ class DescrptSeAtten(DescrptSeA): Number of the axis neuron :math:`M_2` (number of columns of the sub-matrix of the embedding matrix) resnet_dt Time-step `dt` in the resnet construction: - y = x + dt * \phi (Wx + b) + y = x + dt * \\phi (Wx + b) trainable If the weights of embedding net are trainable. seed @@ -64,6 +64,8 @@ class DescrptSeAtten(DescrptSeA): Whether to dot the relative coordinates on the attention weights as a gated scheme. attn_mask Whether to mask the diagonal in the attention weights. + multi_task + If the model has multi fitting nets to train. """ def __init__(self, @@ -75,7 +77,7 @@ def __init__(self, axis_neuron: int = 8, resnet_dt: bool = False, trainable: bool = True, - seed: int = None, + seed: Optional[int] = None, type_one_side: bool = True, exclude_types: List[List[int]] = [], set_davg_zero: bool = False, @@ -85,7 +87,8 @@ def __init__(self, attn: int = 128, attn_layer: int = 2, attn_dotr: bool = True, - attn_mask: bool = False + attn_mask: bool = False, + multi_task: bool = False ) -> None: DescrptSeA.__init__(self, rcut, @@ -101,7 +104,8 @@ def __init__(self, set_davg_zero=set_davg_zero, activation_function=activation_function, precision=precision, - uniform_seed=uniform_seed + uniform_seed=uniform_seed, + multi_task=multi_task ) """ Constructor @@ -153,7 +157,7 @@ def compute_input_stats(self, mesh: list, input_dict: dict, mixed_type: bool = False, - real_natoms_vec: list = None + real_natoms_vec: Optional[list] = None ) -> None: """ Compute the statisitcs (avg and std) of the training data. The input will be normalized by the statistics. @@ -180,8 +184,6 @@ def compute_input_stats(self, real_natoms_vec If mixed_type is True, it takes in the real natoms_vec for each frame. """ - all_davg = [] - all_dstd = [] if True: sumr = [] suma = [] @@ -208,26 +210,15 @@ def compute_input_stats(self, sumn.append(sysn) sumr2.append(sysr2) suma2.append(sysa2) - sumr = np.sum(sumr, axis=0) - suma = np.sum(suma, axis=0) - sumn = np.sum(sumn, axis=0) - sumr2 = np.sum(sumr2, axis=0) - suma2 = np.sum(suma2, axis=0) - for type_i in range(self.ntypes): - davgunit = [sumr[type_i] / (sumn[type_i] + 1e-15), 0, 0, 0] - dstdunit = [self._compute_std(sumr2[type_i], sumr[type_i], sumn[type_i]), - self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), - self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), - self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]) - ] - davg = np.tile(davgunit, self.ndescrpt // 4) - dstd = np.tile(dstdunit, self.ndescrpt // 4) - all_davg.append(davg) - all_dstd.append(dstd) - - if not self.set_davg_zero: - self.davg = np.array(all_davg) - self.dstd = np.array(all_dstd) + if not self.multi_task: + stat_dict = {'sumr': sumr, 'suma': suma, 'sumn': sumn, 'sumr2': sumr2, 'suma2': suma2} + self.merge_input_stats(stat_dict) + else: + self.stat_dict['sumr'] += sumr + self.stat_dict['suma'] += suma + self.stat_dict['sumn'] += sumn + self.stat_dict['sumr2'] += sumr2 + self.stat_dict['suma2'] += suma2 def build(self, coord_: tf.Tensor, @@ -236,7 +227,7 @@ def build(self, box_: tf.Tensor, mesh: tf.Tensor, input_dict: dict, - reuse: bool = None, + reuse: Optional[bool] = None, suffix: str = '' ) -> tf.Tensor: """ diff --git a/deepmd/descriptor/se_r.py b/deepmd/descriptor/se_r.py index 929007bcf5..5773c47202 100644 --- a/deepmd/descriptor/se_r.py +++ b/deepmd/descriptor/se_r.py @@ -1,5 +1,5 @@ import numpy as np -from typing import Tuple, List +from typing import Optional, Tuple, List from deepmd.env import tf from deepmd.common import get_activation_func, get_precision, cast_precision @@ -34,7 +34,7 @@ class DescrptSeR (DescrptSe): Number of neurons in each hidden layers of the embedding net resnet_dt Time-step `dt` in the resnet construction: - y = x + dt * \phi (Wx + b) + y = x + dt * \\phi (Wx + b) trainable If the weights of embedding net are trainable. seed @@ -58,31 +58,18 @@ def __init__ (self, neuron: List[int] = [24,48,96], resnet_dt: bool = False, trainable: bool = True, - seed: int = None, + seed: Optional[int] = None, type_one_side: bool = True, exclude_types: List[List[int]] = [], set_davg_zero: bool = False, activation_function: str = 'tanh', precision: str = 'default', - uniform_seed: bool = False + uniform_seed: bool = False, + multi_task: bool = False ) -> None: """ Constructor """ - # args = ClassArg()\ - # .add('sel', list, must = True) \ - # .add('rcut', float, default = 6.0) \ - # .add('rcut_smth',float, default = 0.5) \ - # .add('neuron', list, default = [10, 20, 40]) \ - # .add('resnet_dt',bool, default = False) \ - # .add('trainable',bool, default = True) \ - # .add('seed', int) \ - # .add('type_one_side', bool, default = False) \ - # .add('exclude_types', list, default = []) \ - # .add('set_davg_zero', bool, default = False) \ - # .add("activation_function", str, default = "tanh") \ - # .add("precision", str, default = "default") - # class_data = args.parse(jdata) if rcut < rcut_smth: raise RuntimeError("rcut_smth (%f) should be no more than rcut (%f)!" % (rcut_smth, rcut)) self.sel_r = sel @@ -144,11 +131,13 @@ def __init__ (self, rcut_smth = self.rcut_smth, sel = self.sel_r) self.sub_sess = tf.Session(graph = sub_graph, config=default_tf_session_config) - + self.multi_task = multi_task + if multi_task: + self.stat_dict = {'sumr': [], 'sumn': [], 'sumr2': []} def get_rcut (self) : """ - Returns the cut-off radisu + Returns the cut-off radius """ return self.rcut @@ -204,8 +193,6 @@ def compute_input_stats (self, input_dict Dictionary for additional input """ - all_davg = [] - all_dstd = [] sumr = [] sumn = [] sumr2 = [] @@ -215,11 +202,36 @@ def compute_input_stats (self, sumr.append(sysr) sumn.append(sysn) sumr2.append(sysr2) - sumr = np.sum(sumr, axis = 0) - sumn = np.sum(sumn, axis = 0) - sumr2 = np.sum(sumr2, axis = 0) - for type_i in range(self.ntypes) : - davgunit = [sumr[type_i]/sumn[type_i]] + if not self.multi_task: + stat_dict = {'sumr': sumr, 'sumn': sumn, 'sumr2': sumr2} + self.merge_input_stats(stat_dict) + else: + self.stat_dict['sumr'] += sumr + self.stat_dict['sumn'] += sumn + self.stat_dict['sumr2'] += sumr2 + + def merge_input_stats(self, stat_dict): + """ + Merge the statisitcs computed from compute_input_stats to obtain the self.davg and self.dstd. + + Parameters + ---------- + stat_dict + The dict of statisitcs computed from compute_input_stats, including: + sumr + The sum of radial statisitcs. + sumn + The sum of neighbor numbers. + sumr2 + The sum of square of radial statisitcs. + """ + all_davg = [] + all_dstd = [] + sumr = np.sum(stat_dict['sumr'], axis=0) + sumn = np.sum(stat_dict['sumn'], axis=0) + sumr2 = np.sum(stat_dict['sumr2'], axis=0) + for type_i in range(self.ntypes): + davgunit = [sumr[type_i] / sumn[type_i]] dstdunit = [self._compute_std(sumr2[type_i], sumr[type_i], sumn[type_i])] davg = np.tile(davgunit, self.ndescrpt // 1) dstd = np.tile(dstdunit, self.ndescrpt // 1) @@ -232,7 +244,8 @@ def compute_input_stats (self, def enable_compression(self, min_nbor_dist : float, - model_file : str = 'frozon_model.pb', + graph: tf.Graph, + graph_def: tf.GraphDef, table_extrapolate : float = 5, table_stride_1 : float = 0.01, table_stride_2 : float = 0.1, @@ -246,8 +259,10 @@ def enable_compression(self, ---------- min_nbor_dist The nearest distance between atoms - model_file - The original frozen model, which will be compressed by the program + grapf : tf.Graph + The graph of the model + graph_def : tf.GraphDef + The graph_def of the model table_extrapolate The scale of model extrapolation table_stride_1 @@ -273,7 +288,7 @@ def enable_compression(self, self.compress = True self.table = DPTabulate( - self, self.filter_neuron, model_file, activation_fn = self.filter_activation_fn, suffix=suffix) + self, self.filter_neuron, graph, graph_def, activation_fn = self.filter_activation_fn, suffix=suffix) self.table_config = [table_extrapolate, table_stride_1, table_stride_2, check_frequency] self.lower, self.upper \ = self.table.build(min_nbor_dist, @@ -281,7 +296,6 @@ def enable_compression(self, table_stride_1, table_stride_2) - graph, _ = load_graph_def(model_file) self.davg = get_tensor_by_name_from_graph(graph, 'descrpt_attr%s/t_avg' % suffix) self.dstd = get_tensor_by_name_from_graph(graph, 'descrpt_attr%s/t_std' % suffix) @@ -379,7 +393,7 @@ def build (self, tf.summary.histogram('rij', self.rij) tf.summary.histogram('nlist', self.nlist) - self.dout = self._pass_filter(self.descrpt_reshape, natoms, suffix = suffix, reuse = reuse, trainable = self.trainable) + self.dout = self._pass_filter(self.descrpt_reshape, atype, natoms, suffix = suffix, reuse = reuse, trainable = self.trainable) tf.summary.histogram('embedding_net_output', self.dout) return self.dout @@ -434,6 +448,7 @@ def prod_force_virial(self, def _pass_filter(self, inputs, + atype, natoms, reuse = None, suffix = '', @@ -441,18 +456,13 @@ def _pass_filter(self, start_index = 0 inputs = tf.reshape(inputs, [-1, natoms[0], self.ndescrpt]) output = [] - if not (self.type_one_side and len(self.exclude_types) == 0): + if not self.type_one_side: for type_i in range(self.ntypes): inputs_i = tf.slice (inputs, [ 0, start_index, 0], [-1, natoms[2+type_i], -1] ) inputs_i = tf.reshape(inputs_i, [-1, self.ndescrpt]) - if self.type_one_side: - # reuse NN parameters for all types to support type_one_side along with exclude_types - reuse = tf.AUTO_REUSE - filter_name = 'filter_type_all'+suffix - else: - filter_name = 'filter_type_'+str(type_i)+suffix + filter_name = 'filter_type_'+str(type_i)+suffix layer = self._filter_r(inputs_i, type_i, name=filter_name, natoms=natoms, reuse=reuse, trainable = trainable, activation_fn = self.filter_activation_fn) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[2+type_i], self.get_dim_out()]) output.append(layer) @@ -461,6 +471,16 @@ def _pass_filter(self, inputs_i = inputs inputs_i = tf.reshape(inputs_i, [-1, self.ndescrpt]) type_i = -1 + if len(self.exclude_types): + mask = self.build_type_exclude_mask( + self.exclude_types, + self.ntypes, + self.sel_r, + self.ndescrpt, + atype, + tf.shape(inputs_i)[0], + ) + inputs_i *= mask layer = self._filter_r(inputs_i, type_i, name='filter_type_all'+suffix, natoms=natoms, reuse=reuse, trainable = trainable, activation_fn = self.filter_activation_fn) layer = tf.reshape(layer, [tf.shape(inputs)[0], natoms[0], self.get_dim_out()]) output.append(layer) diff --git a/deepmd/descriptor/se_t.py b/deepmd/descriptor/se_t.py index f9453f17c3..2ecfa00693 100644 --- a/deepmd/descriptor/se_t.py +++ b/deepmd/descriptor/se_t.py @@ -1,5 +1,5 @@ import numpy as np -from typing import Tuple, List +from typing import Optional, Tuple, List from deepmd.env import tf from deepmd.common import get_activation_func, get_precision, cast_precision @@ -35,7 +35,7 @@ class DescrptSeT (DescrptSe): Number of neurons in each hidden layers of the embedding net resnet_dt Time-step `dt` in the resnet construction: - y = x + dt * \phi (Wx + b) + y = x + dt * \\phi (Wx + b) trainable If the weights of embedding net are trainable. seed @@ -56,11 +56,12 @@ def __init__ (self, neuron: List[int] = [24,48,96], resnet_dt: bool = False, trainable: bool = True, - seed: int = None, + seed: Optional[int] = None, set_davg_zero: bool = False, activation_function: str = 'tanh', precision: str = 'default', - uniform_seed: bool = False + uniform_seed: bool = False, + multi_task: bool = False ) -> None: """ Constructor @@ -128,11 +129,13 @@ def __init__ (self, sel_a = self.sel_a, sel_r = self.sel_r) self.sub_sess = tf.Session(graph = sub_graph, config=default_tf_session_config) - + self.multi_task = multi_task + if multi_task: + self.stat_dict = {'sumr': [], 'suma': [], 'sumn': [], 'sumr2': [], 'suma2': []} def get_rcut (self) -> float: """ - Returns the cut-off radisu + Returns the cut-off radius """ return self.rcut_r @@ -189,8 +192,6 @@ def compute_input_stats (self, input_dict Dictionary for additional input """ - all_davg = [] - all_dstd = [] if True: sumr = [] suma = [] @@ -205,23 +206,53 @@ def compute_input_stats (self, sumn.append(sysn) sumr2.append(sysr2) suma2.append(sysa2) - sumr = np.sum(sumr, axis = 0) - suma = np.sum(suma, axis = 0) - sumn = np.sum(sumn, axis = 0) - sumr2 = np.sum(sumr2, axis = 0) - suma2 = np.sum(suma2, axis = 0) - for type_i in range(self.ntypes) : - davgunit = [sumr[type_i]/sumn[type_i], 0, 0, 0] - dstdunit = [self._compute_std(sumr2[type_i], sumr[type_i], sumn[type_i]), - self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), - self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), - self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]) - ] - davg = np.tile(davgunit, self.ndescrpt // 4) - dstd = np.tile(dstdunit, self.ndescrpt // 4) - all_davg.append(davg) - all_dstd.append(dstd) + if not self.multi_task: + stat_dict = {'sumr': sumr, 'suma': suma, 'sumn': sumn, 'sumr2': sumr2, 'suma2': suma2} + self.merge_input_stats(stat_dict) + else: + self.stat_dict['sumr'] += sumr + self.stat_dict['suma'] += suma + self.stat_dict['sumn'] += sumn + self.stat_dict['sumr2'] += sumr2 + self.stat_dict['suma2'] += suma2 + + def merge_input_stats(self, stat_dict): + """ + Merge the statisitcs computed from compute_input_stats to obtain the self.davg and self.dstd. + Parameters + ---------- + stat_dict + The dict of statisitcs computed from compute_input_stats, including: + sumr + The sum of radial statisitcs. + suma + The sum of relative coord statisitcs. + sumn + The sum of neighbor numbers. + sumr2 + The sum of square of radial statisitcs. + suma2 + The sum of square of relative coord statisitcs. + """ + all_davg = [] + all_dstd = [] + sumr = np.sum(stat_dict['sumr'], axis = 0) + suma = np.sum(stat_dict['suma'], axis = 0) + sumn = np.sum(stat_dict['sumn'], axis = 0) + sumr2 = np.sum(stat_dict['sumr2'], axis = 0) + suma2 = np.sum(stat_dict['suma2'], axis = 0) + for type_i in range(self.ntypes) : + davgunit = [sumr[type_i]/(sumn[type_i]+1e-15), 0, 0, 0] + dstdunit = [self._compute_std(sumr2[type_i], sumr[type_i], sumn[type_i]), + self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), + self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]), + self._compute_std(suma2[type_i], suma[type_i], sumn[type_i]) + ] + davg = np.tile(davgunit, self.ndescrpt // 4) + dstd = np.tile(dstdunit, self.ndescrpt // 4) + all_davg.append(davg) + all_dstd.append(dstd) if not self.set_davg_zero: self.davg = np.array(all_davg) self.dstd = np.array(all_dstd) @@ -229,7 +260,8 @@ def compute_input_stats (self, def enable_compression(self, min_nbor_dist : float, - model_file : str = 'frozon_model.pb', + graph: tf.Graph, + graph_def: tf.GraphDef, table_extrapolate : float = 5, table_stride_1 : float = 0.01, table_stride_2 : float = 0.1, @@ -243,8 +275,10 @@ def enable_compression(self, ---------- min_nbor_dist The nearest distance between atoms - model_file - The original frozen model, which will be compressed by the program + grapf : tf.Graph + The graph of the model + graph_def : tf.GraphDef + The graph_def of the model table_extrapolate The scale of model extrapolation table_stride_1 @@ -270,7 +304,7 @@ def enable_compression(self, self.compress = True self.table = DPTabulate( - self, self.filter_neuron, model_file, activation_fn = self.filter_activation_fn, suffix=suffix) + self, self.filter_neuron, graph, graph_def, activation_fn = self.filter_activation_fn, suffix=suffix) self.table_config = [table_extrapolate, table_stride_1 * 10, table_stride_2 * 10, check_frequency] self.lower, self.upper \ = self.table.build(min_nbor_dist, @@ -278,7 +312,6 @@ def enable_compression(self, table_stride_1 * 10, table_stride_2 * 10) - graph, _ = load_graph_def(model_file) self.davg = get_tensor_by_name_from_graph(graph, 'descrpt_attr%s/t_avg' % suffix) self.dstd = get_tensor_by_name_from_graph(graph, 'descrpt_attr%s/t_std' % suffix) diff --git a/deepmd/entrypoints/compress.py b/deepmd/entrypoints/compress.py index d8f8e3e933..701571398c 100644 --- a/deepmd/entrypoints/compress.py +++ b/deepmd/entrypoints/compress.py @@ -10,7 +10,7 @@ from deepmd.utils.argcheck import normalize from deepmd.utils.compat import update_deepmd_input from deepmd.utils.errors import GraphTooLargeError, GraphWithoutTensorError -from deepmd.utils.graph import get_tensor_by_name +from deepmd.utils.graph import load_graph_def, get_tensor_by_name_from_graph from .freeze import freeze from .train import train, get_rcut, get_min_nbor_dist @@ -66,9 +66,10 @@ def compress( log_level : int logging level """ + graph, _ = load_graph_def(input) try: - t_jdata = get_tensor_by_name(input, 'train_attr/training_script') - t_min_nbor_dist = get_tensor_by_name(input, 'train_attr/min_nbor_dist') + t_jdata = get_tensor_by_name_from_graph(graph, 'train_attr/training_script') + t_min_nbor_dist = get_tensor_by_name_from_graph(graph, 'train_attr/min_nbor_dist') jdata = json.loads(t_jdata) except GraphWithoutTensorError as e: if training_script == None: @@ -88,7 +89,7 @@ def compress( jdata = update_deepmd_input(jdata) t_min_nbor_dist = get_min_nbor_dist(jdata, get_rcut(jdata)) - _check_compress_type(input) + _check_compress_type(graph) tf.constant(t_min_nbor_dist, name = 'train_attr/min_nbor_dist', @@ -151,9 +152,9 @@ def compress( "increase the step size." % step ) from e -def _check_compress_type(model_file): +def _check_compress_type(graph: tf.Graph): try: - t_model_type = bytes.decode(get_tensor_by_name(model_file, 'model_type')) + t_model_type = bytes.decode(get_tensor_by_name_from_graph(graph, 'model_type')) except GraphWithoutTensorError as e: # Compatible with the upgraded model, which has no 'model_type' info t_model_type = None diff --git a/deepmd/entrypoints/convert.py b/deepmd/entrypoints/convert.py index cbe00e9e5d..586d7f2ee2 100644 --- a/deepmd/entrypoints/convert.py +++ b/deepmd/entrypoints/convert.py @@ -1,4 +1,11 @@ -from deepmd.utils.convert import convert_012_to_21, convert_10_to_21, convert_20_to_21, convert_13_to_21, convert_12_to_21 +from deepmd.utils.convert import ( + convert_012_to_21, + convert_10_to_21, + convert_20_to_21, + convert_13_to_21, + convert_12_to_21, + convert_pbtxt_to_pb, +) def convert( *, @@ -18,5 +25,7 @@ def convert( convert_13_to_21(input_model, output_model) elif FROM == '2.0': convert_20_to_21(input_model, output_model) + elif FROM == 'pbtxt': + convert_pbtxt_to_pb(input_model, output_model) else: raise RuntimeError('unsupported model version ' + FROM) diff --git a/deepmd/entrypoints/freeze.py b/deepmd/entrypoints/freeze.py index e13c4c778b..0ddf87468b 100755 --- a/deepmd/entrypoints/freeze.py +++ b/deepmd/entrypoints/freeze.py @@ -8,11 +8,12 @@ import logging import google.protobuf.message -from deepmd.env import tf, FITTING_NET_PATTERN +from deepmd.env import tf, FITTING_NET_PATTERN, REMOVE_SUFFIX_DICT from deepmd.utils.errors import GraphTooLargeError from deepmd.utils.sess import run_sess from deepmd.utils.graph import get_pattern_nodes_from_graph_def from os.path import abspath +import json # load grad of force module import deepmd.op @@ -28,9 +29,9 @@ def _transfer_fitting_net_trainable_variables(sess, old_graph_def, raw_graph_def): old_pattern = FITTING_NET_PATTERN raw_pattern = FITTING_NET_PATTERN\ - .replace('idt', 'idt+_\d+')\ - .replace('bias', 'bias+_\d+')\ - .replace('matrix', 'matrix+_\d+') + .replace('idt', r'idt+_\d+')\ + .replace('bias', r'bias+_\d+')\ + .replace('matrix', r'matrix+_\d+') old_graph_nodes = get_pattern_nodes_from_graph_def( old_graph_def, old_pattern @@ -56,7 +57,88 @@ def _transfer_fitting_net_trainable_variables(sess, old_graph_def, raw_graph_def node.attr["value"].tensor.tensor_content = tensor.tostring() return old_graph_def -def _make_node_names(model_type: str, modifier_type: Optional[str] = None) -> List[str]: + +def _remove_fitting_net_suffix(output_graph_def, out_suffix): + """Remove fitting net suffix for multi-task mode + + Parameters + ---------- + output_graph_def : tf.GraphDef + The output graph to remove suffix. + out_suffix : str + The suffix to remove. + """ + + def change_name(name, suffix): + if suffix in name: + for item in REMOVE_SUFFIX_DICT: + if item.format(suffix) in name: + name = name.replace(item.format(suffix), REMOVE_SUFFIX_DICT[item]) + break + assert suffix not in name, 'fitting net name illegal!' + return name + + for node in output_graph_def.node: + if out_suffix in node.name: + node.name = change_name(node.name, out_suffix) + for idx in range(len(node.input)): + if out_suffix in node.input[idx]: + node.input[idx] = change_name(node.input[idx], out_suffix) + attr_list = node.attr['_class'].list.s + for idx in range(len(attr_list)): + if out_suffix in bytes.decode(attr_list[idx]): + attr_list[idx] = bytes(change_name(bytes.decode(attr_list[idx]), out_suffix), encoding='utf8') + return output_graph_def + + +def _modify_model_suffix(output_graph_def, out_suffix, freeze_type): + """Modify model suffix in graph nodes for multi-task mode, including fitting net, model attr and training script. + + Parameters + ---------- + output_graph_def : tf.GraphDef + The output graph to remove suffix. + out_suffix : str + The suffix to remove. + freeze_type : str + The model type to freeze. + """ + output_graph_def = _remove_fitting_net_suffix( + output_graph_def, + out_suffix + ) + for node in output_graph_def.node: + if 'model_attr/model_type' in node.name: + node.attr['value'].tensor.string_val[0] = bytes(freeze_type, encoding='utf8') + # change the input script for frozen model + elif 'train_attr/training_script' in node.name: + jdata = json.loads(node.attr['value'].tensor.string_val[0]) + # fitting net + assert out_suffix in jdata['model']['fitting_net_dict'] + jdata['model']['fitting_net'] = jdata['model'].pop('fitting_net_dict')[out_suffix] + # data systems + systems = jdata['training'].pop('data_dict') + if out_suffix in systems: + jdata['training']['training_data'] = systems[out_suffix]['training_data'] + if 'validation_data' in systems[out_suffix]: + jdata['training']['validation_data'] = systems[out_suffix]['validation_data'] + else: + jdata['training']['training_data'] = {} + log.warning('The fitting net {} has no training data in input script, resulting in ' + 'untrained frozen model, and cannot be compressed directly! '.format(out_suffix)) + # loss + if 'loss_dict' in jdata: + loss_dict = jdata.pop('loss_dict') + if out_suffix in loss_dict: + jdata['loss'] = loss_dict[out_suffix] + # fitting weight + if 'fitting_weight' in jdata['training']: + jdata['training'].pop('fitting_weight') + node.attr['value'].tensor.string_val[0] = bytes(json.dumps(jdata), encoding='utf8') + return output_graph_def + + +def _make_node_names(model_type: str, modifier_type: Optional[str] = None, out_suffix: str = '') -> List[str]: """Get node names based on model type. Parameters @@ -65,6 +147,8 @@ def _make_node_names(model_type: str, modifier_type: Optional[str] = None) -> Li str type of model modifier_type : Optional[str], optional modifier type if any, by default None + out_suffix : str + suffix for output nodes Returns ------- @@ -158,9 +242,107 @@ def _make_node_names(model_type: str, modifier_type: Optional[str] = None) -> Li "o_dm_virial", "o_dm_av", ] + if out_suffix != '': + for ind in range(len(nodes)): + if (nodes[ind][:2] == 'o_' and nodes[ind] not in ["o_rmat", "o_rmat_deriv", "o_nlist", "o_rij"]) \ + or nodes[ind] == "model_attr/sel_type" \ + or nodes[ind] == "model_attr/output_dim": + nodes[ind] += '_{}'.format(out_suffix) + elif 'fitting_attr' in nodes[ind]: + content = nodes[ind].split('/')[1] + nodes[ind] = 'fitting_attr_{}/{}'.format(out_suffix, content) return nodes +def freeze_graph(sess, input_graph, input_node, freeze_type, modifier, out_graph_name, node_names=None, out_suffix=''): + """Freeze the single graph with chosen out_suffix. + + Parameters + ---------- + sess : tf.Session + The default session. + input_graph : tf.GraphDef + The input graph_def stored from the checkpoint. + input_node : List[str] + The expected nodes to freeze. + freeze_type : str + The model type to freeze. + modifier : Optional[str], optional + Modifier type if any, by default None. + out_graph_name : str + The output graph. + node_names : Optional[str], optional + Names of nodes to output, by default None. + out_suffix : str + The chosen suffix to freeze in the input_graph. + """ + if node_names is None: + output_node = _make_node_names(freeze_type, modifier, out_suffix=out_suffix) + different_set = set(output_node) - set(input_node) + if different_set: + log.warning( + "The following nodes are not in the graph: %s. " + "Skip freezeing these nodes. You may be freezing " + "a checkpoint generated by an old version." % different_set + ) + # use intersection as output list + output_node = list(set(output_node) & set(input_node)) + else: + output_node = node_names.split(",") + log.info(f"The following nodes will be frozen: {output_node}") + # We use a built-in TF helper to export variables to constants + output_graph_def = tf.graph_util.convert_variables_to_constants( + sess, # The session is used to retrieve the weights + input_graph, # The graph_def is used to retrieve the nodes + output_node, # The output node names are used to select the usefull nodes + ) + # if multi-task, change fitting_net suffix and model_type + if out_suffix != '': + output_graph_def = _modify_model_suffix(output_graph_def, out_suffix, freeze_type) + + # If we need to transfer the fitting net variables + output_graph_def = _transfer_fitting_net_trainable_variables( + sess, + output_graph_def, + input_graph + ) + + # Finally we serialize and dump the output graph to the filesystem + with tf.gfile.GFile(out_graph_name, "wb") as f: + f.write(output_graph_def.SerializeToString()) + log.info(f"{len(output_graph_def.node):d} ops in the final graph.") + + +def freeze_graph_multi(sess, input_graph, input_node, modifier, out_graph_name, node_names): + """Freeze multiple graphs for multi-task model. + + Parameters + ---------- + sess : tf.Session + The default session. + input_graph : tf.GraphDef + The input graph_def stored from the checkpoint. + input_node : List[str] + The expected nodes to freeze. + modifier : Optional[str], optional + Modifier type if any, by default None. + out_graph_name : str + The output graph. + node_names : Optional[str], optional + Names of nodes to output, by default None. + """ + input_script = json.loads(run_sess(sess, "train_attr/training_script:0", feed_dict={})) + assert 'model' in input_script.keys() and 'fitting_net_dict' in input_script['model'] + for fitting_key in input_script['model']['fitting_net_dict']: + fitting_type = input_script['model']['fitting_net_dict'][fitting_key]['type'] + if out_graph_name[-3:] == '.pb': + output_graph_item = out_graph_name[:-3] + '_{}.pb'.format(fitting_key) + else: + output_graph_item = out_graph_name + '_{}'.format(fitting_key) + freeze_graph(sess, input_graph, input_node, fitting_type, modifier, output_graph_item, node_names, + out_suffix=fitting_key) + + def freeze( *, checkpoint_folder: str, output: str, node_names: Optional[str] = None, nvnmd_weight: Optional[str] = None, **kwargs ): @@ -224,39 +406,9 @@ def freeze( ) else: modifier_type = None - if node_names is None: - output_node_list = _make_node_names(model_type, modifier_type) - different_set = set(output_node_list) - set(nodes) - if different_set: - log.warning( - "The following nodes are not in the graph: %s. " - "Skip freezeing these nodes. You may be freezing " - "a checkpoint generated by an old version." % different_set - ) - # use intersection as output list - output_node_list = list(set(output_node_list) & set(nodes)) - else: - output_node_list = node_names.split(",") - log.info(f"The following nodes will be frozen: {output_node_list}") - if nvnmd_weight is not None: save_weight(sess, nvnmd_weight) # nvnmd - - # We use a built-in TF helper to export variables to constants - output_graph_def = tf.graph_util.convert_variables_to_constants( - sess, # The session is used to retrieve the weights - input_graph_def, # The graph_def is used to retrieve the nodes - output_node_list, # The output node names are used to select the usefull nodes - ) - - # If we need to transfer the fitting net variables - output_graph_def = _transfer_fitting_net_trainable_variables( - sess, - output_graph_def, - input_graph_def - ) - - # Finally we serialize and dump the output graph to the filesystem - with tf.gfile.GFile(output_graph, "wb") as f: - f.write(output_graph_def.SerializeToString()) - log.info(f"{len(output_graph_def.node):d} ops in the final graph.") + if model_type != 'multi-task': + freeze_graph(sess, input_graph_def, nodes, model_type, modifier_type, output_graph, node_names) + else: + freeze_graph_multi(sess, input_graph_def, nodes, modifier_type, output_graph, node_names) diff --git a/deepmd/entrypoints/main.py b/deepmd/entrypoints/main.py index 045441374a..845f3940c7 100644 --- a/deepmd/entrypoints/main.py +++ b/deepmd/entrypoints/main.py @@ -7,6 +7,7 @@ from typing import Dict, List, Optional from deepmd import __version__ +from deepmd.common import clear_session from deepmd.entrypoints import ( compress, config, @@ -156,20 +157,35 @@ def main_parser() -> argparse.ArgumentParser: parser_train.add_argument( "INPUT", help="the input parameter file in json or yaml format" ) - parser_train.add_argument( + parser_train_subgroup = parser_train.add_mutually_exclusive_group() + parser_train_subgroup.add_argument( "-i", "--init-model", type=str, default=None, help="Initialize the model by the provided checkpoint.", ) - parser_train.add_argument( + parser_train_subgroup.add_argument( "-r", "--restart", type=str, default=None, help="Restart the training from the provided checkpoint.", ) + parser_train_subgroup.add_argument( + "-f", + "--init-frz-model", + type=str, + default=None, + help="Initialize the training from the frozen model.", + ) + parser_train_subgroup.add_argument( + "-t", + "--finetune", + type=str, + default=None, + help="Finetune the frozen pretrained model.", + ) parser_train.add_argument( "-o", "--output", @@ -177,13 +193,6 @@ def main_parser() -> argparse.ArgumentParser: default="out.json", help="The output file of the parameters used in training.", ) - parser_train.add_argument( - "-f", - "--init-frz-model", - type=str, - default=None, - help="Initialize the training from the frozen model.", - ) parser_train.add_argument( "--skip-neighbor-stat", action="store_true", @@ -273,7 +282,7 @@ def main_parser() -> argparse.ArgumentParser: "--detail-file", type=str, default=None, - help="File where details of energy force and virial accuracy will be written", + help="The prefix to files where details of energy, force and virial accuracy/accuracy per atom will be written", ) parser_tst.add_argument( "-a", @@ -434,7 +443,7 @@ def main_parser() -> argparse.ArgumentParser: parser_transform.add_argument( 'FROM', type = str, - choices = ['0.12', '1.0', '1.1', '1.2', '1.3', '2.0'], + choices = ['0.12', '1.0', '1.1', '1.2', '1.3', '2.0', 'pbtxt'], help="The original model compatibility", ) parser_transform.add_argument( @@ -540,15 +549,24 @@ def parse_args(args: Optional[List[str]] = None) -> argparse.Namespace: return parsed_args -def main(): +def main(args: Optional[List[str]] = None): """DeePMD-Kit entry point. + Parameters + ---------- + args: List[str], optional + list of command line arguments, used to avoid calling from the subprocess, + as it is quite slow to import tensorflow + Raises ------ RuntimeError if no command was input """ - args = parse_args() + if args is not None: + clear_session() + + args = parse_args(args=args) # do not set log handles for None, it is useless # log handles for train will be set separatelly @@ -584,3 +602,6 @@ def main(): pass else: raise RuntimeError(f"unknown command {args.command}") + + if args is not None: + clear_session() diff --git a/deepmd/entrypoints/test.py b/deepmd/entrypoints/test.py index 1cd23534a4..b8ea83689b 100644 --- a/deepmd/entrypoints/test.py +++ b/deepmd/entrypoints/test.py @@ -204,6 +204,7 @@ def test_ener( data.add("aparam", dp.get_dim_aparam(), atomic=True, must=True, high_prec=False) test_data = data.get_test() + mixed_type = data.mixed_type natoms = len(test_data["type"][0]) nframes = test_data["box"].shape[0] numb_test = min(nframes, numb_test) @@ -216,7 +217,10 @@ def test_ener( efield = None if not data.pbc: box = None - atype = test_data["type"][0] + if mixed_type: + atype = test_data["type"][:numb_test].reshape([numb_test, -1]) + else: + atype = test_data["type"][0] if dp.get_dim_fparam() > 0: fparam = test_data["fparam"][:numb_test] else: @@ -234,6 +238,7 @@ def test_ener( aparam=aparam, atomic=has_atom_ener, efield=efield, + mixed_type=mixed_type ) energy = ret[0] force = ret[1] @@ -284,6 +289,12 @@ def test_ener( header="%s: data_e pred_e" % system, append=append_detail, ) + pe_atom = pe / natoms + save_txt_file( + detail_path.with_suffix(".e_peratom.out"), + pe_atom, + header = "%s: data_e pred_e" % system, + ) pf = np.concatenate( ( np.reshape(test_data["force"][:numb_test], [-1, 3]), @@ -312,6 +323,15 @@ def test_ener( "pred_vyy pred_vyz pred_vzx pred_vzy pred_vzz", append=append_detail, ) + pv_atom = pv / natoms + save_txt_file( + detail_path.with_suffix(".v_peratom.out"), + pv_atom, + header=f"{system}: data_vxx data_vxy data_vxz data_vyx data_vyy " + "data_vyz data_vzx data_vzy data_vzz pred_vxx pred_vxy pred_vxz pred_vyx " + "pred_vyy pred_vyz pred_vzx pred_vzy pred_vzz", + append=append_detail, + ) return { "rmse_ea" : (rmse_ea, energy.size), "rmse_f" : (rmse_f, force.size), diff --git a/deepmd/entrypoints/train.py b/deepmd/entrypoints/train.py index 7ffdc7c8b0..43f6efacaf 100755 --- a/deepmd/entrypoints/train.py +++ b/deepmd/entrypoints/train.py @@ -8,6 +8,7 @@ import time import os from typing import Dict, List, Optional, Any +import numpy as np from deepmd.common import data_requirement, expand_sys_str, j_loader, j_must_have from deepmd.env import tf, reset_default_tf_session_config, GLOBAL_ENER_FLOAT_PRECISION @@ -21,6 +22,7 @@ from deepmd.utils.sess import run_sess from deepmd.utils.neighbor_stat import NeighborStat from deepmd.utils.path import DPPath +from deepmd.utils.finetune import replace_model_params_with_pretrained_model __all__ = ["train"] @@ -39,6 +41,7 @@ def train( log_path: Optional[str], is_compress: bool = False, skip_neighbor_stat: bool = False, + finetune: Optional[str] = None, **kwargs, ): """Run DeePMD model training. @@ -65,6 +68,8 @@ def train( indicates whether in the model compress mode skip_neighbor_stat : bool, default=False skip checking neighbor statistics + finetune : Optional[str] + path to pretrained model or None Raises ------ @@ -75,6 +80,7 @@ def train( init_model=init_model, restart=restart, init_frz_model=init_frz_model, + finetune=finetune, log_path=log_path, log_level=log_level, mpi_log=mpi_log @@ -86,6 +92,10 @@ def train( # load json database jdata = j_loader(INPUT) + origin_type_map = None + if run_opt.finetune is not None: + jdata, origin_type_map = replace_model_params_with_pretrained_model(jdata, run_opt.finetune) + jdata = update_deepmd_input(jdata, warning=True, dump="input_v2_compat.json") jdata = normalize(jdata) @@ -104,6 +114,8 @@ def train( log.info(message) run_opt.print_resource_summary() + if origin_type_map is not None: + jdata['model']['origin_type_map'] = origin_type_map _do_work(jdata, run_opt, is_compress) @@ -147,20 +159,41 @@ def _do_work(jdata: Dict[str, Any], run_opt: RunOptions, is_compress: bool = Fal # setup data modifier modifier = get_modifier(jdata["model"].get("modifier", None)) + # check the multi-task mode + multi_task_mode = "fitting_net_dict" in jdata["model"] + # decouple the training data from the model compress process train_data = None valid_data = None if not is_compress: # init data - train_data = get_data(jdata["training"]["training_data"], rcut, ipt_type_map, modifier) - train_data.print_summary("training") - if jdata["training"].get("validation_data", None) is not None: - valid_data = get_data(jdata["training"]["validation_data"], rcut, train_data.type_map, modifier) - valid_data.print_summary("validation") + if not multi_task_mode: + train_data = get_data(jdata["training"]["training_data"], rcut, ipt_type_map, modifier) + train_data.print_summary("training") + if jdata["training"].get("validation_data", None) is not None: + valid_data = get_data(jdata["training"]["validation_data"], rcut, train_data.type_map, modifier) + valid_data.print_summary("validation") + else: + train_data = {} + valid_data = {} + for data_systems in jdata["training"]["data_dict"]: + if jdata["training"]["fitting_weight"][data_systems] > 0.: # check only the available pair + train_data[data_systems] = get_data( + jdata["training"]["data_dict"][data_systems]["training_data"], rcut, + ipt_type_map, modifier, multi_task_mode) + train_data[data_systems].print_summary("training in {}".format(data_systems)) + if jdata["training"]["data_dict"][data_systems].get("validation_data", None) is not None: + valid_data[data_systems] = get_data( + jdata["training"]["data_dict"][data_systems]["validation_data"], rcut, + train_data[data_systems].type_map, modifier, multi_task_mode) + valid_data[data_systems].print_summary("validation in {}".format(data_systems)) # get training info stop_batch = j_must_have(jdata["training"], "numb_steps") - model.build(train_data, stop_batch) + origin_type_map = jdata["model"].get("origin_type_map", None) + if origin_type_map is not None and not origin_type_map: # get the type_map from data if not provided + origin_type_map = get_data(jdata["training"]["training_data"], rcut, None, modifier).get_type_map() + model.build(train_data, stop_batch, origin_type_map=origin_type_map) if not is_compress: # train the model with the provided systems in a cyclic way @@ -174,10 +207,12 @@ def _do_work(jdata: Dict[str, Any], run_opt: RunOptions, is_compress: bool = Fal log.info("finished compressing") -def get_data(jdata: Dict[str, Any], rcut, type_map, modifier): +def get_data(jdata: Dict[str, Any], rcut, type_map, modifier, multi_task_mode=False): systems = j_must_have(jdata, "systems") if isinstance(systems, str): systems = expand_sys_str(systems) + elif isinstance(systems, list): + systems = systems.copy() help_msg = 'Please check your setting for data systems' # check length of systems if len(systems) == 0: @@ -199,6 +234,7 @@ def get_data(jdata: Dict[str, Any], rcut, type_map, modifier): batch_size = j_must_have(jdata, "batch_size") sys_probs = jdata.get("sys_probs", None) auto_prob = jdata.get("auto_prob", "prob_sys_size") + optional_type_map = not multi_task_mode data = DeepmdDataSystem( systems=systems, @@ -207,6 +243,7 @@ def get_data(jdata: Dict[str, Any], rcut, type_map, modifier): shuffle_test=True, # to satisfy the old api rcut=rcut, type_map=type_map, + optional_type_map=optional_type_map, modifier=modifier, trn_all_set=True, # sample from all sets sys_probs=sys_probs, @@ -256,8 +293,26 @@ def get_nbor_stat(jdata, rcut, one_type: bool = False): if type_map and len(type_map) == 0: type_map = None - train_data = get_data(jdata["training"]["training_data"], max_rcut, type_map, None) - train_data.get_batch() + multi_task_mode = "data_dict" in jdata["training"] + if not multi_task_mode: + train_data = get_data(jdata["training"]["training_data"], max_rcut, type_map, None) + train_data.get_batch() + else: + assert type_map is not None, 'Data stat in multi-task mode must have available type_map! ' + train_data = None + for systems in jdata["training"]["data_dict"]: + tmp_data = get_data(jdata["training"]["data_dict"][systems]["training_data"], max_rcut, type_map, None) + tmp_data.get_batch() + assert tmp_data.get_type_map(), \ + "In multi-task mode, 'type_map.raw' must be defined in data systems {}! ".format(systems) + if train_data is None: + train_data = tmp_data + else: + train_data.system_dirs += tmp_data.system_dirs + train_data.data_systems += tmp_data.data_systems + train_data.natoms += tmp_data.natoms + train_data.natoms_vec += tmp_data.natoms_vec + train_data.default_mesh += tmp_data.default_mesh data_ntypes = train_data.get_ntypes() if type_map is not None: map_ntypes = len(type_map) diff --git a/deepmd/env.py b/deepmd/env.py index 36c4b4b7c2..9fcde6fd05 100644 --- a/deepmd/env.py +++ b/deepmd/env.py @@ -46,6 +46,7 @@ "EMBEDDING_NET_PATTERN", "TYPE_EMBEDDING_PATTERN", "ATTENTION_LAYER_PATTERN", + "REMOVE_SUFFIX_DICT", "TF_VERSION" ] @@ -120,6 +121,30 @@ r"model_attr/t_tab_data|" ) +REMOVE_SUFFIX_DICT = { + "model_attr/sel_type_{}": "model_attr/sel_type", + "model_attr/output_dim_{}": "model_attr/output_dim", + "_{}/": "/", + "o_energy_{}": "o_energy", + "o_force_{}": "o_force", + "o_virial_{}": "o_virial", + "o_atom_energy_{}": "o_atom_energy", + "o_atom_virial_{}": "o_atom_virial", + "o_dipole_{}": "o_dipole", + "o_global_dipole_{}": "o_global_dipole", + "o_polar_{}": "o_polar", + "o_global_polar_{}": "o_global_polar", + "o_rmat_{}": "o_rmat", + "o_rmat_deriv_{}": "o_rmat_deriv", + "o_nlist_{}": "o_nlist", + "o_rij_{}": "o_rij", + "o_dm_force_{}": "o_dm_force", + "o_dm_virial_{}": "o_dm_virial", + "o_dm_av_{}": "o_dm_av", + "o_wfc_{}": "o_wfc", +} + + def set_env_if_empty(key: str, value: str, verbose: bool = True): """Set environment variable only if it is empty. @@ -327,14 +352,14 @@ def get_module(module_name: str) -> "ModuleType": def _get_package_constants( - config_file: Path = Path(__file__).parent / "pkg_config/run_config.ini", + config_file: Path = Path(__file__).parent / "run_config.ini", ) -> Dict[str, str]: """Read package constants set at compile time by CMake to dictionary. Parameters ---------- config_file : str, optional - path to CONFIG file, by default "pkg_config/run_config.ini" + path to CONFIG file, by default "run_config.ini" Returns ------- @@ -351,7 +376,7 @@ def _get_package_constants( TF_VERSION = GLOBAL_CONFIG["tf_version"] TF_CXX11_ABI_FLAG = int(GLOBAL_CONFIG["tf_cxx11_abi_flag"]) -op_module = get_module("op_abi") +op_module = get_module("deepmd_op") op_grads_module = get_module("op_grads") # FLOAT_PREC diff --git a/deepmd/fit/__init__.py b/deepmd/fit/__init__.py index 71d582e8ca..3f94c00a43 100644 --- a/deepmd/fit/__init__.py +++ b/deepmd/fit/__init__.py @@ -1,6 +1,4 @@ from .ener import EnerFitting -from .wfc import WFCFitting from .dipole import DipoleFittingSeA from .polar import PolarFittingSeA from .polar import GlobalPolarFittingSeA -from .polar import PolarFittingLocFrame diff --git a/deepmd/fit/dipole.py b/deepmd/fit/dipole.py index 2935aa2b06..932c834577 100644 --- a/deepmd/fit/dipole.py +++ b/deepmd/fit/dipole.py @@ -1,6 +1,6 @@ import warnings import numpy as np -from typing import Tuple, List +from typing import Optional, Tuple, List from deepmd.env import tf from deepmd.common import add_data_requirement, get_activation_func, get_precision, cast_precision @@ -24,7 +24,7 @@ class DipoleFittingSeA (Fitting) : Number of neurons in each hidden layer of the fitting net resnet_dt : bool Time-step `dt` in the resnet construction: - y = x + dt * \phi (Wx + b) + y = x + dt * \\phi (Wx + b) sel_type : List[int] The atom types selected to have an atomic dipole prediction. If is None, all atoms are selected. seed : int @@ -49,23 +49,14 @@ def __init__ (self, """ Constructor """ - if not isinstance(descrpt, DescrptSeA) : - raise RuntimeError('DipoleFittingSeA only supports DescrptSeA') self.ntypes = descrpt.get_ntypes() self.dim_descrpt = descrpt.get_dim_out() - # args = ClassArg()\ - # .add('neuron', list, default = [120,120,120], alias = 'n_neuron')\ - # .add('resnet_dt', bool, default = True)\ - # .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'dipole_type')\ - # .add('seed', int)\ - # .add("activation_function", str, default = "tanh")\ - # .add('precision', str, default = "default") - # class_data = args.parse(jdata) self.n_neuron = neuron self.resnet_dt = resnet_dt self.sel_type = sel_type if self.sel_type is None: self.sel_type = [ii for ii in range(self.ntypes)] + self.sel_mask = np.array([ii in self.sel_type for ii in range(self.ntypes)], dtype=bool) self.seed = seed self.uniform_seed = uniform_seed self.seed_shift = one_layer_rand_seed_shift() @@ -89,11 +80,58 @@ def get_out_size(self) -> int: """ return 3 + def _build_lower(self, + start_index, + natoms, + inputs, + rot_mat, + suffix='', + reuse=None + ): + # cut-out inputs + inputs_i = tf.slice(inputs, + [0, start_index, 0], + [-1, natoms, -1]) + inputs_i = tf.reshape(inputs_i, [-1, self.dim_descrpt]) + rot_mat_i = tf.slice(rot_mat, + [0, start_index, 0], + [-1, natoms, -1]) + rot_mat_i = tf.reshape(rot_mat_i, [-1, self.dim_rot_mat_1, 3]) + layer = inputs_i + for ii in range(0, len(self.n_neuron)): + if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii - 1]: + layer += one_layer(layer, self.n_neuron[ii], name='layer_' + str(ii) + suffix, + reuse=reuse, seed=self.seed, use_timestep=self.resnet_dt, + activation_fn=self.fitting_activation_fn, precision=self.fitting_precision, + uniform_seed=self.uniform_seed, initial_variables=self.fitting_net_variables, + mixed_prec=self.mixed_prec) + else: + layer = one_layer(layer, self.n_neuron[ii], name='layer_' + str(ii) + suffix, + reuse=reuse, seed=self.seed, activation_fn=self.fitting_activation_fn, + precision=self.fitting_precision, uniform_seed=self.uniform_seed, + initial_variables=self.fitting_net_variables, mixed_prec=self.mixed_prec) + if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift + # (nframes x natoms) x naxis + final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn=None, + name='final_layer' + suffix, reuse=reuse, seed=self.seed, + precision=self.fitting_precision, uniform_seed=self.uniform_seed, + initial_variables=self.fitting_net_variables, mixed_prec=self.mixed_prec, + final_layer=True) + if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift + # (nframes x natoms) x 1 * naxis + final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms, 1, self.dim_rot_mat_1]) + # (nframes x natoms) x 1 x 3(coord) + final_layer = tf.matmul(final_layer, rot_mat_i) + # nframes x natoms x 3 + final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms, 3]) + return final_layer + @cast_precision def build (self, input_d : tf.Tensor, rot_mat : tf.Tensor, natoms : tf.Tensor, + input_dict: Optional[dict] = None, reuse : bool = None, suffix : str = '') -> tf.Tensor: """ @@ -110,6 +148,8 @@ def build (self, natoms[0]: number of local atoms natoms[1]: total number of atoms held by this processor natoms[i]: 2 <= i < Ntypes+2, number of type i atoms + input_dict + Additional dict for inputs. reuse The weights in the networks should be reused when get the variable. suffix @@ -120,46 +160,58 @@ def build (self, dipole The atomic dipole. """ + if input_dict is None: + input_dict = {} + type_embedding = input_dict.get('type_embedding', None) + atype = input_dict.get('atype', None) + nframes = input_dict.get('nframes') start_index = 0 inputs = tf.reshape(input_d, [-1, natoms[0], self.dim_descrpt]) rot_mat = tf.reshape(rot_mat, [-1, natoms[0], self.dim_rot_mat]) - count = 0 - outs_list = [] - for type_i in range(self.ntypes): - # cut-out inputs - inputs_i = tf.slice (inputs, - [ 0, start_index, 0], - [-1, natoms[2+type_i], -1] ) - inputs_i = tf.reshape(inputs_i, [-1, self.dim_descrpt]) - rot_mat_i = tf.slice (rot_mat, - [ 0, start_index, 0], - [-1, natoms[2+type_i], -1] ) - rot_mat_i = tf.reshape(rot_mat_i, [-1, self.dim_rot_mat_1, 3]) - start_index += natoms[2+type_i] - if not type_i in self.sel_type : - continue - layer = inputs_i - for ii in range(0,len(self.n_neuron)) : - if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, uniform_seed = self.uniform_seed, initial_variables = self.fitting_net_variables, mixed_prec = self.mixed_prec) - else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, uniform_seed = self.uniform_seed, initial_variables = self.fitting_net_variables, mixed_prec = self.mixed_prec) - if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift - # (nframes x natoms) x naxis - final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision, uniform_seed = self.uniform_seed, initial_variables = self.fitting_net_variables, mixed_prec = self.mixed_prec, final_layer = True) - if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift - # (nframes x natoms) x 1 * naxis - final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], 1, self.dim_rot_mat_1]) - # (nframes x natoms) x 1 x 3(coord) - final_layer = tf.matmul(final_layer, rot_mat_i) - # nframes x natoms x 3 - final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i], 3]) + if type_embedding is not None: + nloc_mask = tf.reshape(tf.tile(tf.repeat(self.sel_mask, natoms[2:]), [nframes]), [nframes, -1]) + atype_nall = tf.reshape(atype, [-1, natoms[1]]) + # (nframes x nloc_masked) + self.atype_nloc_masked = tf.reshape(tf.slice(atype_nall, [0, 0], [-1, natoms[0]])[nloc_mask], [-1]) ## lammps will make error + self.nloc_masked = tf.shape(tf.reshape(self.atype_nloc_masked, [nframes, -1]))[1] + atype_embed = tf.nn.embedding_lookup(type_embedding, self.atype_nloc_masked) + else: + atype_embed = None + + self.atype_embed = atype_embed - # concat the results - outs_list.append(final_layer) - count += 1 - outs = tf.concat(outs_list, axis = 1) + if atype_embed is None: + count = 0 + outs_list = [] + for type_i in range(self.ntypes): + if type_i not in self.sel_type: + start_index += natoms[2+type_i] + continue + final_layer = self._build_lower( + start_index, natoms[2+type_i], + inputs, rot_mat, suffix='_type_'+str(type_i)+suffix, reuse=reuse) + start_index += natoms[2 + type_i] + # concat the results + outs_list.append(final_layer) + count += 1 + outs = tf.concat(outs_list, axis = 1) + else: + inputs = tf.reshape(tf.reshape(inputs, [nframes, natoms[0], self.dim_descrpt])[nloc_mask], + [-1, self.dim_descrpt]) + rot_mat = tf.reshape(tf.reshape(rot_mat, [nframes, natoms[0], self.dim_rot_mat_1 * 3])[nloc_mask], + [-1, self.dim_rot_mat_1, 3]) + atype_embed = tf.cast(atype_embed, self.fitting_precision) + type_shape = atype_embed.get_shape().as_list() + inputs = tf.concat([inputs, atype_embed], axis=1) + self.dim_descrpt = self.dim_descrpt + type_shape[1] + inputs = tf.reshape(inputs, [nframes, self.nloc_masked, self.dim_descrpt]) + rot_mat = tf.reshape(rot_mat, [nframes, self.nloc_masked, self.dim_rot_mat_1 * 3]) + final_layer = self._build_lower( + 0, self.nloc_masked, + inputs, rot_mat, suffix=suffix, reuse=reuse) + # nframes x natoms x 3 + outs = tf.reshape(final_layer, [nframes, self.nloc_masked, 3]) tf.summary.histogram('fitting_net_output', outs) return tf.reshape(outs, [-1]) diff --git a/deepmd/fit/ener.py b/deepmd/fit/ener.py index 47e9589cf3..75c13dc9ab 100644 --- a/deepmd/fit/ener.py +++ b/deepmd/fit/ener.py @@ -1,9 +1,11 @@ +import logging import warnings import numpy as np -from typing import Tuple, List +from typing import Optional, Tuple, List from packaging.version import Version from deepmd.env import tf +from deepmd.infer import DeepPotential from deepmd.common import add_data_requirement, get_activation_func, get_precision, cast_precision from deepmd.utils.network import one_layer_rand_seed_shift from deepmd.utils.network import one_layer as one_layer_deepmd @@ -18,6 +20,8 @@ from deepmd.nvnmd.utils.config import nvnmd_cfg from deepmd.nvnmd.fit.ener import one_layer_nvnmd +log = logging.getLogger(__name__) + class EnerFitting (Fitting): r"""Fitting the energy of the system. The force and the virial can also be trained. @@ -136,7 +140,7 @@ def __init__ (self, self.atom_ener_v = atom_ener for at, ae in enumerate(atom_ener): if ae is not None: - self.atom_ener.append(tf.constant(ae, self.fitting_precision, name = "atom_%d_ener" % at)) + self.atom_ener.append(tf.constant(ae, GLOBAL_TF_FLOAT_PRECISION, name = "atom_%d_ener" % at)) else: self.atom_ener.append(None) self.useBN = False @@ -282,6 +286,7 @@ def compute_input_stats(self, def _compute_std (self, sumv2, sumv, sumn) : return np.sqrt(sumv2/sumn - np.multiply(sumv/sumn, sumv/sumn)) + @cast_precision def _build_lower( self, start_index, @@ -364,7 +369,6 @@ def _build_lower( return final_layer - @cast_precision def build (self, inputs : tf.Tensor, natoms : tf.Tensor, @@ -421,12 +425,11 @@ def build (self, t_daparam = tf.constant(self.numb_aparam, name = 'daparam', dtype = tf.int32) - if type_embedding is not None: - self.t_bias_atom_e = tf.get_variable('t_bias_atom_e', - self.bias_atom_e.shape, - dtype=self.fitting_precision, - trainable=False, - initializer=tf.constant_initializer(self.bias_atom_e)) + self.t_bias_atom_e = tf.get_variable('t_bias_atom_e', + self.bias_atom_e.shape, + dtype=GLOBAL_TF_FLOAT_PRECISION, + trainable=False, + initializer=tf.constant_initializer(self.bias_atom_e)) if self.numb_fparam > 0: t_fparam_avg = tf.get_variable('t_fparam_avg', self.numb_fparam, @@ -456,9 +459,9 @@ def build (self, nframes = input_dict.get('nframes') if nframes is not None: # like inputs, but we don't want to add a dependency on inputs - inputs_zero = tf.zeros((nframes, natoms[0], self.dim_descrpt), dtype=self.fitting_precision) + inputs_zero = tf.zeros((nframes, natoms[0], self.dim_descrpt), dtype=GLOBAL_TF_FLOAT_PRECISION) else: - inputs_zero = tf.zeros_like(inputs, dtype=self.fitting_precision) + inputs_zero = tf.zeros_like(inputs, dtype=GLOBAL_TF_FLOAT_PRECISION) if bias_atom_e is not None : @@ -476,9 +479,9 @@ def build (self, aparam = (aparam - t_aparam_avg) * t_aparam_istd aparam = tf.reshape(aparam, [-1, self.numb_aparam * natoms[0]]) + atype_nall = tf.reshape(atype, [-1, natoms[1]]) + self.atype_nloc = tf.reshape(tf.slice(atype_nall, [0, 0], [-1, natoms[0]]), [-1]) ## lammps will make error if type_embedding is not None: - atype_nall = tf.reshape(atype, [-1, natoms[1]]) - self.atype_nloc = tf.reshape(tf.slice(atype_nall, [0, 0], [-1, natoms[0]]), [-1]) ## lammps will make error atype_embed = tf.nn.embedding_lookup(type_embedding, self.atype_nloc) else: atype_embed = None @@ -489,23 +492,19 @@ def build (self, start_index = 0 outs_list = [] for type_i in range(self.ntypes): - if bias_atom_e is None : - type_bias_ae = 0.0 - else : - type_bias_ae = bias_atom_e[type_i] final_layer = self._build_lower( start_index, natoms[2+type_i], inputs, fparam, aparam, - bias_atom_e=type_bias_ae, suffix='_type_'+str(type_i)+suffix, reuse=reuse + bias_atom_e=0., suffix='_type_'+str(type_i)+suffix, reuse=reuse ) # concat the results if type_i < len(self.atom_ener) and self.atom_ener[type_i] is not None: zero_layer = self._build_lower( start_index, natoms[2+type_i], inputs_zero, fparam, aparam, - bias_atom_e=type_bias_ae, suffix='_type_'+str(type_i)+suffix, reuse=True + bias_atom_e=0., suffix='_type_'+str(type_i)+suffix, reuse=True ) - final_layer += self.atom_ener[type_i] - zero_layer + final_layer -= zero_layer final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i]]) outs_list.append(final_layer) start_index += natoms[2+type_i] @@ -514,14 +513,13 @@ def build (self, outs = tf.concat(outs_list, axis = 1) # with type embedding else: - if len(self.atom_ener) > 0: - raise RuntimeError("setting atom_ener is not supported by type embedding") - atype_embed = tf.cast(atype_embed, self.fitting_precision) + atype_embed = tf.cast(atype_embed, GLOBAL_TF_FLOAT_PRECISION) type_shape = atype_embed.get_shape().as_list() inputs = tf.concat( [tf.reshape(inputs,[-1,self.dim_descrpt]),atype_embed], axis=1 ) + original_dim_descrpt = self.dim_descrpt self.dim_descrpt = self.dim_descrpt + type_shape[1] inputs = tf.reshape(inputs, [-1, natoms[0], self.dim_descrpt]) final_layer = self._build_lower( @@ -529,12 +527,26 @@ def build (self, inputs, fparam, aparam, bias_atom_e=0.0, suffix=suffix, reuse=reuse ) + if len(self.atom_ener): + # remove contribution in vacuum + inputs_zero = tf.concat( + [tf.reshape(inputs_zero, [-1, original_dim_descrpt]), atype_embed], + axis=1 + ) + inputs_zero = tf.reshape(inputs_zero, [-1, natoms[0], self.dim_descrpt]) + zero_layer = self._build_lower( + 0, natoms[0], + inputs_zero, fparam, aparam, + bias_atom_e=0.0, suffix=suffix, reuse=True, + ) + # atomic energy will be stored in `self.t_bias_atom_e` which is not trainable + final_layer -= zero_layer outs = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[0]]) - # add bias - self.atom_ener_before = outs - self.add_type = tf.reshape(tf.nn.embedding_lookup(self.t_bias_atom_e, self.atype_nloc), [tf.shape(inputs)[0], natoms[0]]) - outs = outs + self.add_type - self.atom_ener_after = outs + # add bias + self.atom_ener_before = outs + self.add_type = tf.reshape(tf.nn.embedding_lookup(self.t_bias_atom_e, self.atype_nloc), [tf.shape(inputs)[0], natoms[0]]) + outs = outs + self.add_type + self.atom_ener_after = outs if self.tot_ener_zero: force_tot_ener = 0.0 @@ -575,34 +587,90 @@ def init_variables(self, try: self.bias_atom_e = get_tensor_by_name_from_graph(graph, 'fitting_attr%s/t_bias_atom_e' % suffix) except GraphWithoutTensorError: - # model without type_embedding has no t_bias_atom_e + # for compatibility, old models has no t_bias_atom_e pass - def enable_compression(self, - model_file: str, - suffix: str = "" + def change_energy_bias(self, + data, + frozen_model, + origin_type_map, + full_type_map, + bias_shift='delta', + ntest=10 ) -> None: """ - Set the fitting net attributes from the frozen model_file when fparam or aparam is not zero + Change the energy bias according to the input data and the pretrained model. Parameters ---------- - model_file : str - The input frozen model file - suffix : str, optional - The suffix of the scope + data : DeepmdDataSystem + The training data. + frozen_model : str + The path file of frozen model. + origin_type_map : list + The original type_map in dataset, they are targets to change the energy bias. + full_type_map : str + The full type_map in pretrained model + bias_shift : str + The mode for changing energy bias : ['delta', 'statistic'] + 'delta' : perform predictions on energies of target dataset, + and do least sqaure on the errors to obtain the target shift as bias. + 'statistic' : directly use the statistic energy bias in the target dataset. + ntest : int + The number of test samples in a system to change the energy bias. """ - if self.numb_fparam > 0 or self.numb_aparam > 0: - graph, _ = load_graph_def(model_file) - if self.numb_fparam > 0: - self.fparam_avg = get_tensor_by_name_from_graph(graph, 'fitting_attr%s/t_fparam_avg' % suffix) - self.fparam_inv_std = get_tensor_by_name_from_graph(graph, 'fitting_attr%s/t_fparam_istd' % suffix) - if self.numb_aparam > 0: - self.aparam_avg = get_tensor_by_name_from_graph(graph, 'fitting_attr%s/t_aparam_avg' % suffix) - self.aparam_inv_std = get_tensor_by_name_from_graph(graph, 'fitting_attr%s/t_aparam_istd' % suffix) + type_numbs = [] + energy_ground_truth = [] + energy_predict = [] + sorter = np.argsort(full_type_map) + idx_type_map = sorter[np.searchsorted(full_type_map, origin_type_map, sorter=sorter)] + mixed_type = data.mixed_type + numb_type = len(full_type_map) + dp = None + if bias_shift == 'delta': + # init model + dp = DeepPotential(frozen_model) + for sys in data.data_systems: + test_data = sys.get_test() + nframes = test_data["box"].shape[0] + numb_test = min(nframes, ntest) + if mixed_type: + atype = test_data["type"][:numb_test].reshape([numb_test, -1]) + else: + atype = test_data["type"][0] + assert np.array([i in idx_type_map for i in list(set(atype.reshape(-1)))]).all(), \ + "Some types are not in 'type_map'!" + energy_ground_truth.append(test_data["energy"][:numb_test].reshape([numb_test, 1])) + if mixed_type: + type_numbs.append(np.array([(atype == i).sum(axis=-1) for i in idx_type_map], dtype=np.int32).T) + else: + type_numbs.append(np.tile(np.bincount(atype, minlength=numb_type)[idx_type_map], (numb_test, 1))) + if bias_shift == 'delta': + coord = test_data["coord"][:numb_test].reshape([numb_test, -1]) + box = test_data["box"][:numb_test] + ret = dp.eval(coord, box, atype, mixed_type=mixed_type) + energy_predict.append(ret[0].reshape([numb_test, 1])) + type_numbs = np.concatenate(type_numbs) + energy_ground_truth = np.concatenate(energy_ground_truth) + old_bias = self.bias_atom_e[idx_type_map] + if bias_shift == 'delta': + energy_predict = np.concatenate(energy_predict) + bias_diff = energy_ground_truth - energy_predict + delta_bias = np.linalg.lstsq(type_numbs, bias_diff, rcond=None)[0] + unbias_e = energy_predict + type_numbs @ delta_bias + atom_numbs = type_numbs.sum(-1) + rmse_ae = (np.sqrt(np.square(unbias_e - energy_ground_truth)) / atom_numbs).mean() + self.bias_atom_e[idx_type_map] += delta_bias.reshape(-1) + log.info("RMSE of atomic energy after linear regression is: {} eV/atom.".format(rmse_ae)) + elif bias_shift == 'statistic': + statistic_bias = np.linalg.lstsq(type_numbs, energy_ground_truth, rcond=None)[0] + self.bias_atom_e[idx_type_map] = statistic_bias.reshape(-1) + else: + raise RuntimeError('Unknown bias_shift mode: ' + bias_shift) + log.info("Change energy bias of {} from {} to {}.".format(str(origin_type_map), str(old_bias), + str(self.bias_atom_e[idx_type_map]))) - - def enable_mixed_precision(self, mixed_prec: dict = None) -> None: + def enable_mixed_precision(self, mixed_prec: Optional[dict] = None) -> None: """ Reveive the mixed precision setting. diff --git a/deepmd/fit/polar.py b/deepmd/fit/polar.py index 3bb3d9966b..2bd07b847b 100644 --- a/deepmd/fit/polar.py +++ b/deepmd/fit/polar.py @@ -1,6 +1,6 @@ import warnings import numpy as np -from typing import Tuple, List +from typing import Optional, Tuple, List from deepmd.env import tf from deepmd.common import add_data_requirement, cast_precision, get_activation_func, get_precision @@ -14,93 +14,6 @@ from deepmd.env import GLOBAL_TF_FLOAT_PRECISION -class PolarFittingLocFrame () : - """ - Fitting polarizability with local frame descriptor. - - .. deprecated:: 2.0.0 - This class is not supported any more. - """ - def __init__ (self, jdata, descrpt) : - if not isinstance(descrpt, DescrptLocFrame) : - raise RuntimeError('PolarFittingLocFrame only supports DescrptLocFrame') - self.ntypes = descrpt.get_ntypes() - self.dim_descrpt = descrpt.get_dim_out() - args = ClassArg()\ - .add('neuron', list, default = [120,120,120], alias = 'n_neuron')\ - .add('resnet_dt', bool, default = True)\ - .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ - .add('seed', int)\ - .add("activation_function", str, default = "tanh")\ - .add('precision', str, default = "default") - class_data = args.parse(jdata) - self.n_neuron = class_data['neuron'] - self.resnet_dt = class_data['resnet_dt'] - self.sel_type = class_data['sel_type'] - self.seed = class_data['seed'] - self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) - self.fitting_precision = get_precision(class_data['precision']) - self.useBN = False - - def get_sel_type(self): - return self.sel_type - - def get_out_size(self): - return 9 - - def build (self, - input_d, - rot_mat, - natoms, - reuse = None, - suffix = '') : - start_index = 0 - inputs = tf.cast(tf.reshape(input_d, [-1, natoms[0], self.dim_descrpt]), self.fitting_precision) - rot_mat = tf.reshape(rot_mat, [-1, 9 * natoms[0]]) - - count = 0 - outs_list = [] - for type_i in range(self.ntypes): - # cut-out inputs - inputs_i = tf.slice (inputs, - [ 0, start_index, 0], - [-1, natoms[2+type_i], -1] ) - inputs_i = tf.reshape(inputs_i, [-1, self.dim_descrpt]) - rot_mat_i = tf.slice (rot_mat, - [ 0, start_index* 9], - [-1, natoms[2+type_i]* 9] ) - rot_mat_i = tf.reshape(rot_mat_i, [-1, 3, 3]) - start_index += natoms[2+type_i] - if not type_i in self.sel_type : - continue - layer = inputs_i - for ii in range(0,len(self.n_neuron)) : - if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) - else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision) - # (nframes x natoms) x 9 - final_layer = one_layer(layer, 9, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision, final_layer = True) - # (nframes x natoms) x 3 x 3 - final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], 3, 3]) - # (nframes x natoms) x 3 x 3 - final_layer = final_layer + tf.transpose(final_layer, perm = [0,2,1]) - # (nframes x natoms) x 3 x 3(coord) - final_layer = tf.matmul(final_layer, rot_mat_i) - # (nframes x natoms) x 3(coord) x 3(coord) - final_layer = tf.matmul(rot_mat_i, final_layer, transpose_a = True) - # nframes x natoms x 3 x 3 - final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i], 3, 3]) - - # concat the results - outs_list.append(final_layer) - count += 1 - outs = tf.concat(outs_list, axis = 1) - - tf.summary.histogram('fitting_net_output', outs) - return tf.cast(tf.reshape(outs, [-1]), GLOBAL_TF_FLOAT_PRECISION) - - class PolarFittingSeA (Fitting) : """ Fit the atomic polarizability with descriptor se_a @@ -113,7 +26,7 @@ class PolarFittingSeA (Fitting) : Number of neurons in each hidden layer of the fitting net resnet_dt : bool Time-step `dt` in the resnet construction: - y = x + dt * \phi (Wx + b) + y = x + dt * \\phi (Wx + b) sel_type : List[int] The atom types selected to have an atomic polarizability prediction. If is None, all atoms are selected. fit_diag : bool @@ -148,21 +61,8 @@ def __init__ (self, """ Constructor """ - if not isinstance(descrpt, DescrptSeA) : - raise RuntimeError('PolarFittingSeA only supports DescrptSeA') self.ntypes = descrpt.get_ntypes() self.dim_descrpt = descrpt.get_dim_out() - # args = ClassArg()\ - # .add('neuron', list, default = [120,120,120], alias = 'n_neuron')\ - # .add('resnet_dt', bool, default = True)\ - # .add('fit_diag', bool, default = True)\ - # .add('diag_shift', [list,float], default = [0.0 for ii in range(self.ntypes)])\ - # .add('scale', [list,float], default = [1.0 for ii in range(self.ntypes)])\ - # .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'pol_type')\ - # .add('seed', int)\ - # .add("activation_function", str , default = "tanh")\ - # .add('precision', str, default = "default") - # class_data = args.parse(jdata) self.n_neuron = neuron self.resnet_dt = resnet_dt self.sel_type = sel_type @@ -177,17 +77,20 @@ def __init__ (self, self.fitting_precision = get_precision(precision) if self.sel_type is None: self.sel_type = [ii for ii in range(self.ntypes)] + self.sel_mask = np.array([ii in self.sel_type for ii in range(self.ntypes)], dtype=bool) if self.scale is None: self.scale = [1.0 for ii in range(self.ntypes)] #if self.diag_shift is None: # self.diag_shift = [0.0 for ii in range(self.ntypes)] if type(self.sel_type) is not list: self.sel_type = [self.sel_type] - self.constant_matrix = np.zeros(len(self.sel_type)) # len(sel_type) x 1, store the average diagonal value + self.sel_type = sorted(self.sel_type) + self.constant_matrix = np.zeros(self.ntypes) # self.ntypes x 1, store the average diagonal value #if type(self.diag_shift) is not list: # self.diag_shift = [self.diag_shift] if type(self.scale) is not list: - self.scale = [self.scale] + self.scale = [self.scale for ii in range(self.ntypes)] + self.scale = np.array(self.scale) self.dim_rot_mat_1 = descrpt.get_dim_rot_mat_1() self.dim_rot_mat = self.dim_rot_mat_1 * 3 self.useBN = False @@ -270,13 +173,85 @@ def compute_input_stats(self, atom_polar,_,_,_ \ = np.linalg.lstsq(matrix, bias, rcond = 1e-3) for itype in range(len(self.sel_type)): - self.constant_matrix[itype] = np.mean(np.diagonal(atom_polar[itype].reshape((3,3)))) + self.constant_matrix[self.sel_type[itype]] = np.mean(np.diagonal(atom_polar[itype].reshape((3,3)))) + + def _build_lower(self, + start_index, + natoms, + inputs, + rot_mat, + suffix='', + reuse=None): + # cut-out inputs + inputs_i = tf.slice(inputs, + [0, start_index * self.dim_descrpt], + [-1, natoms * self.dim_descrpt]) + inputs_i = tf.reshape(inputs_i, [-1, self.dim_descrpt]) + rot_mat_i = tf.slice(rot_mat, + [0, start_index * self.dim_rot_mat], + [-1, natoms * self.dim_rot_mat]) + rot_mat_i = tf.reshape(rot_mat_i, [-1, self.dim_rot_mat_1, 3]) + layer = inputs_i + for ii in range(0, len(self.n_neuron)): + if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii - 1]: + layer += one_layer(layer, self.n_neuron[ii], name='layer_' + str(ii) + suffix, + reuse=reuse, seed=self.seed, use_timestep=self.resnet_dt, + activation_fn=self.fitting_activation_fn, precision=self.fitting_precision, + uniform_seed=self.uniform_seed, initial_variables=self.fitting_net_variables, + mixed_prec=self.mixed_prec) + else: + layer = one_layer(layer, self.n_neuron[ii], name='layer_' + str(ii) + suffix, + reuse=reuse, seed=self.seed, activation_fn=self.fitting_activation_fn, + precision=self.fitting_precision, uniform_seed=self.uniform_seed, + initial_variables=self.fitting_net_variables, mixed_prec=self.mixed_prec) + if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift + if self.fit_diag: + bavg = np.zeros(self.dim_rot_mat_1) + # bavg[0] = self.avgeig[0] + # bavg[1] = self.avgeig[1] + # bavg[2] = self.avgeig[2] + # (nframes x natoms) x naxis + final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn=None, + name='final_layer' + suffix, reuse=reuse, seed=self.seed, + bavg=bavg, precision=self.fitting_precision, uniform_seed=self.uniform_seed, + initial_variables=self.fitting_net_variables, mixed_prec=self.mixed_prec, + final_layer=True) + if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift + # (nframes x natoms) x naxis + final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms, self.dim_rot_mat_1]) + # (nframes x natoms) x naxis x naxis + final_layer = tf.matrix_diag(final_layer) + else: + bavg = np.zeros(self.dim_rot_mat_1 * self.dim_rot_mat_1) + # bavg[0*self.dim_rot_mat_1+0] = self.avgeig[0] + # bavg[1*self.dim_rot_mat_1+1] = self.avgeig[1] + # bavg[2*self.dim_rot_mat_1+2] = self.avgeig[2] + # (nframes x natoms) x (naxis x naxis) + final_layer = one_layer(layer, self.dim_rot_mat_1 * self.dim_rot_mat_1, activation_fn=None, + name='final_layer' + suffix, reuse=reuse, seed=self.seed, + bavg=bavg, precision=self.fitting_precision, uniform_seed=self.uniform_seed, + initial_variables=self.fitting_net_variables, mixed_prec=self.mixed_prec, + final_layer=True) + if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift + # (nframes x natoms) x naxis x naxis + final_layer = tf.reshape(final_layer, + [tf.shape(inputs)[0] * natoms, self.dim_rot_mat_1, self.dim_rot_mat_1]) + # (nframes x natoms) x naxis x naxis + final_layer = final_layer + tf.transpose(final_layer, perm=[0, 2, 1]) + # (nframes x natoms) x naxis x 3(coord) + final_layer = tf.matmul(final_layer, rot_mat_i) + # (nframes x natoms) x 3(coord) x 3(coord) + final_layer = tf.matmul(rot_mat_i, final_layer, transpose_a=True) + # nframes x natoms x 3 x 3 + final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms, 3, 3]) + return final_layer @cast_precision def build (self, input_d : tf.Tensor, rot_mat : tf.Tensor, natoms : tf.Tensor, + input_dict: Optional[dict] = None, reuse : bool = None, suffix : str = '') : """ @@ -293,6 +268,8 @@ def build (self, natoms[0]: number of local atoms natoms[1]: total number of atoms held by this processor natoms[i]: 2 <= i < Ntypes+2, number of type i atoms + input_dict + Additional dict for inputs. reuse The weights in the networks should be reused when get the variable. suffix @@ -303,72 +280,76 @@ def build (self, atomic_polar The atomic polarizability """ + if input_dict is None: + input_dict = {} + type_embedding = input_dict.get('type_embedding', None) + atype = input_dict.get('atype', None) + nframes = input_dict.get('nframes') start_index = 0 inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) rot_mat = tf.reshape(rot_mat, [-1, self.dim_rot_mat * natoms[0]]) - count = 0 - outs_list = [] - for type_i in range(self.ntypes): - # cut-out inputs - inputs_i = tf.slice (inputs, - [ 0, start_index* self.dim_descrpt], - [-1, natoms[2+type_i]* self.dim_descrpt] ) - inputs_i = tf.reshape(inputs_i, [-1, self.dim_descrpt]) - rot_mat_i = tf.slice (rot_mat, - [ 0, start_index* self.dim_rot_mat], - [-1, natoms[2+type_i]* self.dim_rot_mat] ) - rot_mat_i = tf.reshape(rot_mat_i, [-1, self.dim_rot_mat_1, 3]) - start_index += natoms[2+type_i] - if not type_i in self.sel_type : - continue - layer = inputs_i - for ii in range(0,len(self.n_neuron)) : - if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, uniform_seed = self.uniform_seed, initial_variables = self.fitting_net_variables, mixed_prec = self.mixed_prec) - else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, uniform_seed = self.uniform_seed, initial_variables = self.fitting_net_variables, mixed_prec = self.mixed_prec) - if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift - if self.fit_diag : - bavg = np.zeros(self.dim_rot_mat_1) - # bavg[0] = self.avgeig[0] - # bavg[1] = self.avgeig[1] - # bavg[2] = self.avgeig[2] - # (nframes x natoms) x naxis - final_layer = one_layer(layer, self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg, precision = self.fitting_precision, uniform_seed = self.uniform_seed, initial_variables = self.fitting_net_variables, mixed_prec = self.mixed_prec, final_layer = True) - if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift - # (nframes x natoms) x naxis - final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], self.dim_rot_mat_1]) - # (nframes x natoms) x naxis x naxis - final_layer = tf.matrix_diag(final_layer) - else : - bavg = np.zeros(self.dim_rot_mat_1*self.dim_rot_mat_1) - # bavg[0*self.dim_rot_mat_1+0] = self.avgeig[0] - # bavg[1*self.dim_rot_mat_1+1] = self.avgeig[1] - # bavg[2*self.dim_rot_mat_1+2] = self.avgeig[2] - # (nframes x natoms) x (naxis x naxis) - final_layer = one_layer(layer, self.dim_rot_mat_1*self.dim_rot_mat_1, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, bavg = bavg, precision = self.fitting_precision, uniform_seed = self.uniform_seed, initial_variables = self.fitting_net_variables, mixed_prec = self.mixed_prec, final_layer = True) - if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift - # (nframes x natoms) x naxis x naxis - final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], self.dim_rot_mat_1, self.dim_rot_mat_1]) - # (nframes x natoms) x naxis x naxis - final_layer = final_layer + tf.transpose(final_layer, perm = [0,2,1]) - # (nframes x natoms) x naxis x 3(coord) - final_layer = tf.matmul(final_layer, rot_mat_i) - # (nframes x natoms) x 3(coord) x 3(coord) - final_layer = tf.matmul(rot_mat_i, final_layer, transpose_a = True) - # nframes x natoms x 3 x 3 - final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i], 3, 3]) + if type_embedding is not None: + # nframes x nloc + nloc_mask = tf.reshape(tf.tile(tf.repeat(self.sel_mask, natoms[2:]), [nframes]), [nframes, -1]) + # nframes x nloc_masked + scale = tf.reshape( + tf.reshape(tf.tile(tf.repeat(self.scale, natoms[2:]), [nframes]), [nframes, -1])[nloc_mask], + [nframes, -1]) + if self.shift_diag: + # nframes x nloc_masked + constant_matrix = tf.reshape(tf.reshape(tf.tile(tf.repeat( + self.constant_matrix, natoms[2:]), [nframes]), [nframes, -1])[nloc_mask], [nframes, -1]) + atype_nall = tf.reshape(atype, [-1, natoms[1]]) + # (nframes x nloc_masked) + self.atype_nloc_masked = tf.reshape(tf.slice(atype_nall, [0, 0], [-1, natoms[0]])[nloc_mask], [-1]) ## lammps will make error + self.nloc_masked = tf.shape(tf.reshape(self.atype_nloc_masked, [nframes, -1]))[1] + atype_embed = tf.nn.embedding_lookup(type_embedding, self.atype_nloc_masked) + else: + atype_embed = None + + self.atype_embed = atype_embed + + if atype_embed is None: + count = 0 + outs_list = [] + for type_i in range(self.ntypes): + if type_i not in self.sel_type: + start_index += natoms[2+type_i] + continue + final_layer = self._build_lower( + start_index, natoms[2+type_i], + inputs, rot_mat, suffix='_type_'+str(type_i)+suffix, reuse=reuse) + # shift and scale + sel_type_idx = self.sel_type.index(type_i) + final_layer = final_layer * self.scale[sel_type_idx] + final_layer = final_layer + self.constant_matrix[sel_type_idx] * tf.eye(3, batch_shape=[tf.shape(inputs)[0], natoms[2+type_i]], dtype = self.fitting_precision) + start_index += natoms[2 + type_i] + + # concat the results + outs_list.append(final_layer) + count += 1 + outs = tf.concat(outs_list, axis = 1) + else: + inputs = tf.reshape(tf.reshape(inputs, [nframes, natoms[0], self.dim_descrpt])[nloc_mask], + [-1, self.dim_descrpt]) + rot_mat = tf.reshape(tf.reshape(rot_mat, [nframes, natoms[0], self.dim_rot_mat])[nloc_mask], + [-1, self.dim_rot_mat * self.nloc_masked]) + atype_embed = tf.cast(atype_embed, self.fitting_precision) + type_shape = atype_embed.get_shape().as_list() + inputs = tf.concat([inputs, atype_embed], axis=1) + self.dim_descrpt = self.dim_descrpt + type_shape[1] + inputs = tf.reshape(inputs, [-1, self.dim_descrpt * self.nloc_masked]) + final_layer = self._build_lower( + 0, self.nloc_masked, + inputs, rot_mat, suffix=suffix, reuse=reuse) # shift and scale - sel_type_idx = self.sel_type.index(type_i) - final_layer = final_layer * self.scale[sel_type_idx] - final_layer = final_layer + self.constant_matrix[sel_type_idx] * tf.eye(3, batch_shape=[tf.shape(inputs)[0], natoms[2+type_i]], dtype = GLOBAL_TF_FLOAT_PRECISION) - - # concat the results - outs_list.append(final_layer) - count += 1 - outs = tf.concat(outs_list, axis = 1) - + final_layer *= tf.expand_dims(tf.expand_dims(scale, -1), -1) + if self.shift_diag: + final_layer += tf.expand_dims(tf.expand_dims(constant_matrix, -1), -1) * \ + tf.eye(3, batch_shape=[1, 1], dtype=self.fitting_precision) + outs = final_layer + tf.summary.histogram('fitting_net_output', outs) return tf.reshape(outs, [-1]) @@ -417,7 +398,7 @@ class GlobalPolarFittingSeA () : Number of neurons in each hidden layer of the fitting net resnet_dt : bool Time-step `dt` in the resnet construction: - y = x + dt * \phi (Wx + b) + y = x + dt * \\phi (Wx + b) sel_type : List[int] The atom types selected to have an atomic polarizability prediction fit_diag : bool @@ -479,6 +460,7 @@ def build (self, input_d, rot_mat, natoms, + input_dict: Optional[dict] = None, reuse = None, suffix = '') -> tf.Tensor: """ @@ -495,6 +477,8 @@ def build (self, natoms[0]: number of local atoms natoms[1]: total number of atoms held by this processor natoms[i]: 2 <= i < Ntypes+2, number of type i atoms + input_dict + Additional dict for inputs. reuse The weights in the networks should be reused when get the variable. suffix @@ -506,7 +490,7 @@ def build (self, The system polarizability """ inputs = tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]) - outs = self.polar_fitting.build(input_d, rot_mat, natoms, reuse, suffix) + outs = self.polar_fitting.build(input_d, rot_mat, natoms, input_dict, reuse, suffix) # nframes x natoms x 9 outs = tf.reshape(outs, [tf.shape(inputs)[0], -1, 9]) outs = tf.reduce_sum(outs, axis = 1) diff --git a/deepmd/fit/wfc.py b/deepmd/fit/wfc.py deleted file mode 100644 index 564d601cae..0000000000 --- a/deepmd/fit/wfc.py +++ /dev/null @@ -1,105 +0,0 @@ -import warnings -import numpy as np -from typing import Tuple, List - -from deepmd.env import tf -from deepmd.common import ClassArg, add_data_requirement, get_activation_func, get_precision -from deepmd.utils.network import one_layer, one_layer_rand_seed_shift -from deepmd.descriptor import DescrptLocFrame - -from deepmd.env import global_cvt_2_tf_float -from deepmd.env import GLOBAL_TF_FLOAT_PRECISION - -class WFCFitting () : - """ - Fitting Wannier function centers (WFCs) with local frame descriptor. - - .. deprecated:: 2.0.0 - This class is not supported any more. - """ - def __init__ (self, jdata, descrpt): - if not isinstance(descrpt, DescrptLocFrame) : - raise RuntimeError('WFC only supports DescrptLocFrame') - self.ntypes = descrpt.get_ntypes() - self.dim_descrpt = descrpt.get_dim_out() - args = ClassArg()\ - .add('neuron', list, default = [120,120,120], alias = 'n_neuron')\ - .add('resnet_dt', bool, default = True)\ - .add('wfc_numb', int, must = True)\ - .add('sel_type', [list,int], default = [ii for ii in range(self.ntypes)], alias = 'wfc_type')\ - .add('seed', int)\ - .add("activation_function", str, default = "tanh")\ - .add('precision', str, default = "default")\ - .add('uniform_seed', bool, default = False) - class_data = args.parse(jdata) - self.n_neuron = class_data['neuron'] - self.resnet_dt = class_data['resnet_dt'] - self.wfc_numb = class_data['wfc_numb'] - self.sel_type = class_data['sel_type'] - self.seed = class_data['seed'] - self.uniform_seed = class_data['uniform_seed'] - self.seed_shift = one_layer_rand_seed_shift() - self.fitting_activation_fn = get_activation_func(class_data["activation_function"]) - self.fitting_precision = get_precision(class_data['precision']) - self.useBN = False - - - def get_sel_type(self): - return self.sel_type - - def get_wfc_numb(self): - return self.wfc_numb - - def get_out_size(self): - return self.wfc_numb * 3 - - def build (self, - input_d, - rot_mat, - natoms, - reuse = None, - suffix = '') : - start_index = 0 - inputs = tf.cast(tf.reshape(input_d, [-1, self.dim_descrpt * natoms[0]]), self.fitting_precision) - rot_mat = tf.reshape(rot_mat, [-1, 9 * natoms[0]]) - - count = 0 - for type_i in range(self.ntypes): - # cut-out inputs - inputs_i = tf.slice (inputs, - [ 0, start_index* self.dim_descrpt], - [-1, natoms[2+type_i]* self.dim_descrpt] ) - inputs_i = tf.reshape(inputs_i, [-1, self.dim_descrpt]) - rot_mat_i = tf.slice (rot_mat, - [ 0, start_index* 9], - [-1, natoms[2+type_i]* 9] ) - rot_mat_i = tf.reshape(rot_mat_i, [-1, 3, 3]) - start_index += natoms[2+type_i] - if not type_i in self.sel_type : - continue - layer = inputs_i - for ii in range(0,len(self.n_neuron)) : - if ii >= 1 and self.n_neuron[ii] == self.n_neuron[ii-1] : - layer+= one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, use_timestep = self.resnet_dt, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, uniform_seed = self.uniform_seed) - else : - layer = one_layer(layer, self.n_neuron[ii], name='layer_'+str(ii)+'_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, activation_fn = self.fitting_activation_fn, precision = self.fitting_precision, uniform_seed = self.uniform_seed) - if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift - # (nframes x natoms) x (nwfc x 3) - final_layer = one_layer(layer, self.wfc_numb * 3, activation_fn = None, name='final_layer_type_'+str(type_i)+suffix, reuse=reuse, seed = self.seed, precision = self.fitting_precision, uniform_seed = self.uniform_seed) - if (not self.uniform_seed) and (self.seed is not None): self.seed += self.seed_shift - # (nframes x natoms) x nwfc(wc) x 3(coord_local) - final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0] * natoms[2+type_i], self.wfc_numb, 3]) - # (nframes x natoms) x nwfc(wc) x 3(coord) - final_layer = tf.matmul(final_layer, rot_mat_i) - # nframes x natoms x nwfc(wc) x 3(coord_local) - final_layer = tf.reshape(final_layer, [tf.shape(inputs)[0], natoms[2+type_i], self.wfc_numb, 3]) - - # concat the results - if count == 0: - outs = final_layer - else: - outs = tf.concat([outs, final_layer], axis = 1) - count += 1 - - tf.summary.histogram('fitting_net_output', outs) - return tf.cast(tf.reshape(outs, [-1]), GLOBAL_TF_FLOAT_PRECISION) diff --git a/deepmd/infer/deep_eval.py b/deepmd/infer/deep_eval.py index f45a20daf1..a16e1d48f3 100644 --- a/deepmd/infer/deep_eval.py +++ b/deepmd/infer/deep_eval.py @@ -1,4 +1,3 @@ -import os from typing import List, Optional, TYPE_CHECKING, Union from functools import lru_cache @@ -137,7 +136,8 @@ def _get_tensor( tf.Tensor loaded tensor """ - tensor_path = os.path.join(self.load_prefix, tensor_name) + # do not use os.path.join as it doesn't work on Windows + tensor_path = "/".join((self.load_prefix, tensor_name)) tensor = self.graph.get_tensor_by_name(tensor_path) if attr_name: setattr(self, attr_name, tensor) @@ -180,7 +180,7 @@ def _load_graph( @staticmethod def sort_input( - coord : np.ndarray, atom_type : np.ndarray, sel_atoms : List[int] = None + coord : np.ndarray, atom_type : np.ndarray, sel_atoms : List[int] = None, mixed_type : bool = False ): """ Sort atoms in the system according their types. @@ -193,8 +193,12 @@ def sort_input( atom_type The type of atoms Should be of shape [natoms] - sel_atom + sel_atoms The selected atoms by type + mixed_type + Whether to perform the mixed_type mode. + If True, the input data has the mixed_type format (see doc/model/train_se_atten.md), + in which frames in a system may have different natoms_vec(s), with the same nloc. Returns ------- @@ -212,6 +216,11 @@ def sort_input( Only output if sel_atoms is not None The index mapping from the selected atoms to sorted selected atoms. """ + if mixed_type: + # mixed_type need not to resort + natoms = atom_type[0].size + idx_map = np.arange(natoms) + return coord, atom_type, idx_map if sel_atoms is not None: selection = [False] * np.size(atom_type) for ii in sel_atoms: @@ -256,13 +265,17 @@ def reverse_map(vec : np.ndarray, imap : List[int]) -> np.ndarray: return ret - def make_natoms_vec(self, atom_types : np.ndarray) -> np.ndarray : + def make_natoms_vec(self, atom_types : np.ndarray, mixed_type : bool = False) -> np.ndarray : """Make the natom vector used by deepmd-kit. Parameters ---------- atom_types The type of atoms + mixed_type + Whether to perform the mixed_type mode. + If True, the input data has the mixed_type format (see doc/model/train_se_atten.md), + in which frames in a system may have different natoms_vec(s), with the same nloc. Returns ------- @@ -274,9 +287,15 @@ def make_natoms_vec(self, atom_types : np.ndarray) -> np.ndarray : """ natoms_vec = np.zeros (self.ntypes+2).astype(int) - natoms = atom_types.size + if mixed_type: + natoms = atom_types[0].size + else: + natoms = atom_types.size natoms_vec[0] = natoms natoms_vec[1] = natoms + if mixed_type: + natoms_vec[2] = natoms + return natoms_vec for ii in range (self.ntypes) : natoms_vec[ii+2] = np.count_nonzero(atom_types == ii) return natoms_vec diff --git a/deepmd/infer/deep_pot.py b/deepmd/infer/deep_pot.py index 71eb8fae9c..14ff152a2b 100644 --- a/deepmd/infer/deep_pot.py +++ b/deepmd/infer/deep_pot.py @@ -123,7 +123,11 @@ def __init__( # now load tensors to object attributes for attr_name, tensor_name in self.tensors.items(): - self._get_tensor(tensor_name, attr_name) + try: + self._get_tensor(tensor_name, attr_name) + except KeyError: + if attr_name != "t_descriptor": + raise self._run_default_sess() self.tmap = self.tmap.decode('UTF-8').split() @@ -160,7 +164,7 @@ def get_rcut(self) -> float: """Get the cut-off radius of this model.""" return self.rcut - def get_type_map(self) -> List[int]: + def get_type_map(self) -> List[str]: """Get the type map (element name of the atom types) of this model.""" return self.tmap @@ -199,8 +203,11 @@ def eval_func(*args, **kwargs): eval_func = inner_func return eval_func - def _get_natoms_and_nframes(self, coords: np.ndarray, atom_types: List[int]) -> Tuple[int, int]: - natoms = len(atom_types) + def _get_natoms_and_nframes(self, coords: np.ndarray, atom_types: Union[List[int], np.ndarray], mixed_type: bool = False) -> Tuple[int, int]: + if mixed_type: + natoms = len(atom_types[0]) + else: + natoms = len(atom_types) coords = np.reshape(np.array(coords), [-1, natoms * 3]) nframes = coords.shape[0] return natoms, nframes @@ -214,6 +221,7 @@ def eval( fparam: Optional[np.ndarray] = None, aparam: Optional[np.ndarray] = None, efield: Optional[np.ndarray] = None, + mixed_type: bool = False, ) -> Tuple[np.ndarray, ...]: """Evaluate the energy, force and virial by using this DP. @@ -245,7 +253,10 @@ def eval( efield The external field on atoms. The array should be of size nframes x natoms x 3 - + mixed_type + Whether to perform the mixed_type mode. + If True, the input data has the mixed_type format (see doc/model/train_se_atten.md), + in which frames in a system may have different natoms_vec(s), with the same nloc. Returns ------- energy @@ -260,8 +271,8 @@ def eval( The atomic virial. Only returned when atomic == True """ # reshape coords before getting shape - natoms, numb_test = self._get_natoms_and_nframes(coords, atom_types) - output = self._eval_func(self._eval_inner, numb_test, natoms)(coords, cells, atom_types, fparam = fparam, aparam = aparam, atomic = atomic, efield = efield) + natoms, numb_test = self._get_natoms_and_nframes(coords, atom_types, mixed_type=mixed_type) + output = self._eval_func(self._eval_inner, numb_test, natoms)(coords, cells, atom_types, fparam = fparam, aparam = aparam, atomic = atomic, efield = efield, mixed_type=mixed_type) if self.modifier_type is not None: if atomic: @@ -283,11 +294,15 @@ def _prepare_feed_dict( fparam=None, aparam=None, atomic=False, - efield=None + efield=None, + mixed_type=False ): # standarize the shape of inputs - natoms, nframes = self._get_natoms_and_nframes(coords, atom_types) - atom_types = np.array(atom_types, dtype = int).reshape([-1]) + natoms, nframes = self._get_natoms_and_nframes(coords, atom_types, mixed_type=mixed_type) + if mixed_type: + atom_types = np.array(atom_types, dtype=int).reshape([-1, natoms]) + else: + atom_types = np.array(atom_types, dtype = int).reshape([-1]) coords = np.reshape(np.array(coords), [-1, natoms * 3]) if cells is None: pbc = False @@ -328,22 +343,31 @@ def _prepare_feed_dict( raise RuntimeError('got wrong size of frame param, should be either %d x %d x %d or %d x %d or %d' % (nframes, natoms, fdim, natoms, fdim, fdim)) # sort inputs - coords, atom_types, imap = self.sort_input(coords, atom_types) + coords, atom_types, imap = self.sort_input(coords, atom_types, mixed_type=mixed_type) if self.has_efield: efield = np.reshape(efield, [nframes, natoms, 3]) efield = efield[:,imap,:] efield = np.reshape(efield, [nframes, natoms*3]) # make natoms_vec and default_mesh - natoms_vec = self.make_natoms_vec(atom_types) + natoms_vec = self.make_natoms_vec(atom_types, mixed_type=mixed_type) assert(natoms_vec[0] == natoms) # evaluate feed_dict_test = {} feed_dict_test[self.t_natoms] = natoms_vec - feed_dict_test[self.t_type ] = np.tile(atom_types, [nframes, 1]).reshape([-1]) + if mixed_type: + feed_dict_test[self.t_type] = atom_types.reshape([-1]) + else: + feed_dict_test[self.t_type] = np.tile(atom_types, [nframes, 1]).reshape([-1]) feed_dict_test[self.t_coord] = np.reshape(coords, [-1]) - feed_dict_test[self.t_box ] = np.reshape(cells , [-1]) + + if len(self.t_box.shape) == 1: + feed_dict_test[self.t_box ] = np.reshape(cells , [-1]) + elif len(self.t_box.shape) == 2: + feed_dict_test[self.t_box ] = cells + else: + raise RuntimeError if self.has_efield: feed_dict_test[self.t_efield]= np.reshape(efield, [-1]) if pbc: @@ -364,10 +388,11 @@ def _eval_inner( fparam=None, aparam=None, atomic=False, - efield=None + efield=None, + mixed_type=False ): - natoms, nframes = self._get_natoms_and_nframes(coords, atom_types) - feed_dict_test, imap = self._prepare_feed_dict(coords, cells, atom_types, fparam, aparam, efield) + natoms, nframes = self._get_natoms_and_nframes(coords, atom_types, mixed_type=mixed_type) + feed_dict_test, imap = self._prepare_feed_dict(coords, cells, atom_types, fparam, aparam, efield, mixed_type=mixed_type) t_out = [self.t_energy, self.t_force, self.t_virial] @@ -406,6 +431,7 @@ def eval_descriptor(self, fparam: Optional[np.ndarray] = None, aparam: Optional[np.ndarray] = None, efield: Optional[np.ndarray] = None, + mixed_type: bool = False, ) -> np.array: """Evaluate descriptors by using this DP. @@ -435,14 +461,18 @@ def eval_descriptor(self, efield The external field on atoms. The array should be of size nframes x natoms x 3 + mixed_type + Whether to perform the mixed_type mode. + If True, the input data has the mixed_type format (see doc/model/train_se_atten.md), + in which frames in a system may have different natoms_vec(s), with the same nloc. Returns ------- descriptor Descriptors. """ - natoms, numb_test = self._get_natoms_and_nframes(coords, atom_types) - descriptor = self._eval_func(self._eval_descriptor_inner, numb_test, natoms)(coords, cells, atom_types, fparam = fparam, aparam = aparam, efield = efield) + natoms, numb_test = self._get_natoms_and_nframes(coords, atom_types, mixed_type=mixed_type) + descriptor = self._eval_func(self._eval_descriptor_inner, numb_test, natoms)(coords, cells, atom_types, fparam = fparam, aparam = aparam, efield = efield, mixed_type=mixed_type) return descriptor def _eval_descriptor_inner(self, @@ -452,8 +482,9 @@ def _eval_descriptor_inner(self, fparam: Optional[np.ndarray] = None, aparam: Optional[np.ndarray] = None, efield: Optional[np.ndarray] = None, + mixed_type: bool = False, ) -> np.array: - natoms, nframes = self._get_natoms_and_nframes(coords, atom_types) - feed_dict_test, imap = self._prepare_feed_dict(coords, cells, atom_types, fparam, aparam, efield) + natoms, nframes = self._get_natoms_and_nframes(coords, atom_types, mixed_type=mixed_type) + feed_dict_test, imap = self._prepare_feed_dict(coords, cells, atom_types, fparam, aparam, efield, mixed_type=mixed_type) descriptor, = run_sess(self.sess, [self.t_descriptor], feed_dict = feed_dict_test) return self.reverse_map(np.reshape(descriptor, [nframes, natoms, -1]), imap) diff --git a/deepmd/infer/deep_tensor.py b/deepmd/infer/deep_tensor.py index b170066f0c..b4f6b69427 100644 --- a/deepmd/infer/deep_tensor.py +++ b/deepmd/infer/deep_tensor.py @@ -98,7 +98,7 @@ def get_rcut(self) -> float: """Get the cut-off radius of this model.""" return self.rcut - def get_type_map(self) -> List[int]: + def get_type_map(self) -> List[str]: """Get the type map (element name of the atom types) of this model.""" return self.tmap @@ -122,7 +122,8 @@ def eval( atomic: bool = True, fparam: Optional[np.ndarray] = None, aparam: Optional[np.ndarray] = None, - efield: Optional[np.ndarray] = None + efield: Optional[np.ndarray] = None, + mixed_type: bool = False, ) -> np.ndarray: """Evaluate the model. @@ -147,6 +148,10 @@ def eval( Not used in this model efield Not used in this model + mixed_type + Whether to perform the mixed_type mode. + If True, the input data has the mixed_type format (see doc/model/train_se_atten.md), + in which frames in a system may have different natoms_vec(s), with the same nloc. Returns ------- @@ -156,8 +161,12 @@ def eval( else of size nframes x natoms x output_dim """ # standarize the shape of inputs - atom_types = np.array(atom_types, dtype = int).reshape([-1]) - natoms = atom_types.size + if mixed_type: + natoms = atom_types[0].size + atom_types = np.array(atom_types, dtype=int).reshape([-1, natoms]) + else: + atom_types = np.array(atom_types, dtype = int).reshape([-1]) + natoms = atom_types.size coords = np.reshape(np.array(coords), [-1, natoms * 3]) nframes = coords.shape[0] if cells is None: @@ -168,16 +177,20 @@ def eval( cells = np.array(cells).reshape([nframes, 9]) # sort inputs - coords, atom_types, imap, sel_at, sel_imap = self.sort_input(coords, atom_types, sel_atoms = self.get_sel_type()) + coords, atom_types, imap, sel_at, sel_imap = \ + self.sort_input(coords, atom_types, sel_atoms=self.get_sel_type(), mixed_type=mixed_type) # make natoms_vec and default_mesh - natoms_vec = self.make_natoms_vec(atom_types) + natoms_vec = self.make_natoms_vec(atom_types, mixed_type=mixed_type) assert(natoms_vec[0] == natoms) # evaluate feed_dict_test = {} feed_dict_test[self.t_natoms] = natoms_vec - feed_dict_test[self.t_type ] = np.tile(atom_types, [nframes,1]).reshape([-1]) + if mixed_type: + feed_dict_test[self.t_type] = atom_types.reshape([-1]) + else: + feed_dict_test[self.t_type] = np.tile(atom_types, [nframes, 1]).reshape([-1]) feed_dict_test[self.t_coord] = np.reshape(coords, [-1]) feed_dict_test[self.t_box ] = np.reshape(cells , [-1]) if pbc: @@ -214,7 +227,8 @@ def eval_full( atomic: bool = False, fparam: Optional[np.array] = None, aparam: Optional[np.array] = None, - efield: Optional[np.array] = None + efield: Optional[np.array] = None, + mixed_type: bool = False, ) -> Tuple[np.ndarray, ...]: """Evaluate the model with interface similar to the energy model. Will return global tensor, component-wise force and virial @@ -240,6 +254,10 @@ def eval_full( Not used in this model efield Not used in this model + mixed_type + Whether to perform the mixed_type mode. + If True, the input data has the mixed_type format (see doc/model/train_se_atten.md), + in which frames in a system may have different natoms_vec(s), with the same nloc. Returns ------- @@ -263,8 +281,12 @@ def eval_full( f"do not support eval_full with old tensor model" # standarize the shape of inputs - atom_types = np.array(atom_types, dtype = int).reshape([-1]) - natoms = atom_types.size + if mixed_type: + natoms = atom_types[0].size + atom_types = np.array(atom_types, dtype =int).reshape([-1, natoms]) + else: + atom_types = np.array(atom_types, dtype=int).reshape([-1]) + natoms = atom_types.size coords = np.reshape(np.array(coords), [-1, natoms * 3]) nframes = coords.shape[0] if cells is None: @@ -276,16 +298,20 @@ def eval_full( nout = self.output_dim # sort inputs - coords, atom_types, imap, sel_at, sel_imap = self.sort_input(coords, atom_types, sel_atoms = self.get_sel_type()) + coords, atom_types, imap, sel_at, sel_imap = self.sort_input( + coords, atom_types, sel_atoms=self.get_sel_type(), mixed_type=mixed_type) # make natoms_vec and default_mesh - natoms_vec = self.make_natoms_vec(atom_types) + natoms_vec = self.make_natoms_vec(atom_types, mixed_type=mixed_type) assert(natoms_vec[0] == natoms) # evaluate feed_dict_test = {} feed_dict_test[self.t_natoms] = natoms_vec - feed_dict_test[self.t_type ] = np.tile(atom_types, [nframes,1]).reshape([-1]) + if mixed_type: + feed_dict_test[self.t_type] = atom_types.reshape([-1]) + else: + feed_dict_test[self.t_type] = np.tile(atom_types, [nframes, 1]).reshape([-1]) feed_dict_test[self.t_coord] = np.reshape(coords, [-1]) feed_dict_test[self.t_box ] = np.reshape(cells , [-1]) if pbc: diff --git a/deepmd/infer/ewald_recp.py b/deepmd/infer/ewald_recp.py index 227fe2a7e2..05293e91bd 100644 --- a/deepmd/infer/ewald_recp.py +++ b/deepmd/infer/ewald_recp.py @@ -2,7 +2,6 @@ from typing import Tuple, List from deepmd.env import tf -from deepmd.common import ClassArg from deepmd.env import GLOBAL_TF_FLOAT_PRECISION from deepmd.env import GLOBAL_NP_FLOAT_PRECISION from deepmd.env import GLOBAL_ENER_FLOAT_PRECISION diff --git a/deepmd/lmp.py b/deepmd/lmp.py new file mode 100644 index 0000000000..1fa2db9e44 --- /dev/null +++ b/deepmd/lmp.py @@ -0,0 +1,49 @@ +"""Register entry points for lammps-wheel.""" +import os +import platform +from pathlib import Path +from typing import List, Optional + +from find_libpython import find_libpython + +from deepmd.env import tf + + +def get_env(paths: List[Optional[str]]) -> str: + """Get the environment variable from given paths""" + return ":".join((p for p in paths if p is not None)) + + +if platform.system() == "Linux": + lib_env = "LD_LIBRARY_PATH" +elif platform.system() == "Darwin": + lib_env = "DYLD_FALLBACK_LIBRARY_PATH" +else: + raise RuntimeError("Unsupported platform") + +tf_dir = tf.sysconfig.get_lib() +op_dir = str((Path(__file__).parent / "op").absolute()) +# set LD_LIBRARY_PATH +os.environ[lib_env] = get_env([ + os.environ.get(lib_env), + tf_dir, + os.path.join(tf_dir, "python"), + op_dir, +]) + +# preload python library +libpython = find_libpython() +if platform.system() == "Linux": + preload_env = "LD_PRELOAD" +elif platform.system() == "Darwin": + preload_env = "DYLD_INSERT_LIBRARIES" +else: + raise RuntimeError("Unsupported platform") +os.environ[preload_env] = get_env([ + os.environ.get(preload_env), + libpython, +]) + +def get_op_dir() -> str: + """Get the directory of the deepmd-kit OP library""" + return op_dir diff --git a/deepmd/loss/ener.py b/deepmd/loss/ener.py index be57ce5c18..c48fa3d508 100644 --- a/deepmd/loss/ener.py +++ b/deepmd/loss/ener.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, add_data_requirement +from deepmd.common import add_data_requirement from deepmd.env import global_cvt_2_tf_float from deepmd.env import global_cvt_2_ener_float @@ -15,7 +15,7 @@ class EnerStdLoss (Loss) : Parameters ---------- enable_atom_ener_coeff : bool - if true, the energy will be computed as \sum_i c_i E_i + if true, the energy will be computed as \\sum_i c_i E_i """ def __init__ (self, starter_learning_rate : float, @@ -142,10 +142,10 @@ def build (self, more_loss['l2_pref_force_loss'] = l2_pref_force_loss # only used when tensorboard was set as true - self.l2_loss_summary = tf.summary.scalar('l2_loss', tf.sqrt(l2_loss)) - self.l2_loss_ener_summary = tf.summary.scalar('l2_ener_loss', global_cvt_2_tf_float(tf.sqrt(l2_ener_loss)) / global_cvt_2_tf_float(natoms[0])) - self.l2_loss_force_summary = tf.summary.scalar('l2_force_loss', tf.sqrt(l2_force_loss)) - self.l2_loss_virial_summary = tf.summary.scalar('l2_virial_loss', tf.sqrt(l2_virial_loss) / global_cvt_2_tf_float(natoms[0])) + self.l2_loss_summary = tf.summary.scalar('l2_loss_' + suffix, tf.sqrt(l2_loss)) + self.l2_loss_ener_summary = tf.summary.scalar('l2_ener_loss_' + suffix, global_cvt_2_tf_float(tf.sqrt(l2_ener_loss)) / global_cvt_2_tf_float(natoms[0])) + self.l2_loss_force_summary = tf.summary.scalar('l2_force_loss_' + suffix, tf.sqrt(l2_force_loss)) + self.l2_loss_virial_summary = tf.summary.scalar('l2_virial_loss_' + suffix, tf.sqrt(l2_virial_loss) / global_cvt_2_tf_float(natoms[0])) self.l2_l = l2_loss self.l2_more = more_loss @@ -173,75 +173,7 @@ def eval(self, sess, feed_dict, natoms): results["rmse_v"] = np.sqrt(error_v) / natoms[0] if self.has_pf: results["rmse_pf"] = np.sqrt(error_pf) - return results - - def print_header(self): # depreciated - prop_fmt = ' %11s %11s' - print_str = '' - print_str += prop_fmt % ('rmse_tst', 'rmse_trn') - if self.has_e : - print_str += prop_fmt % ('rmse_e_tst', 'rmse_e_trn') - if self.has_ae : - print_str += prop_fmt % ('rmse_ae_tst', 'rmse_ae_trn') - if self.has_f : - print_str += prop_fmt % ('rmse_f_tst', 'rmse_f_trn') - if self.has_v : - print_str += prop_fmt % ('rmse_v_tst', 'rmse_v_trn') - if self.has_pf : - print_str += prop_fmt % ('rmse_pf_tst', 'rmse_pf_trn') - return print_str - - def print_on_training(self, - tb_writer, - cur_batch, - sess, - natoms, - feed_dict_test, - feed_dict_batch): # depreciated - - run_data = [ - self.l2_l, - self.l2_more['l2_ener_loss'], - self.l2_more['l2_force_loss'], - self.l2_more['l2_virial_loss'], - self.l2_more['l2_atom_ener_loss'], - self.l2_more['l2_pref_force_loss'] - ] - - # first train data - train_out = run_sess(sess, run_data, feed_dict=feed_dict_batch) - error_train, error_e_train, error_f_train, error_v_train, error_ae_train, error_pf_train = train_out - - # than test data, if tensorboard log writter is present, commpute summary - # and write tensorboard logs - if tb_writer: - summary_merged_op = tf.summary.merge([self.l2_loss_summary, self.l2_loss_ener_summary, self.l2_loss_force_summary, self.l2_loss_virial_summary]) - run_data.insert(0, summary_merged_op) - - test_out = run_sess(sess, run_data, feed_dict=feed_dict_test) - - if tb_writer: - summary = test_out.pop(0) - tb_writer.add_summary(summary, cur_batch) - - error_test, error_e_test, error_f_test, error_v_test, error_ae_test, error_pf_test = test_out - - - print_str = "" - prop_fmt = " %11.2e %11.2e" - print_str += prop_fmt % (np.sqrt(error_test), np.sqrt(error_train)) - if self.has_e : - print_str += prop_fmt % (np.sqrt(error_e_test) / natoms[0], np.sqrt(error_e_train) / natoms[0]) - if self.has_ae : - print_str += prop_fmt % (np.sqrt(error_ae_test), np.sqrt(error_ae_train)) - if self.has_f : - print_str += prop_fmt % (np.sqrt(error_f_test), np.sqrt(error_f_train)) - if self.has_v : - print_str += prop_fmt % (np.sqrt(error_v_test) / natoms[0], np.sqrt(error_v_train) / natoms[0]) - if self.has_pf: - print_str += prop_fmt % (np.sqrt(error_pf_test), np.sqrt(error_pf_train)) - - return print_str + return results class EnerDipoleLoss (Loss) : @@ -252,17 +184,11 @@ def __init__ (self, start_pref_ed : float = 1.0, limit_pref_ed : float = 1.0 ) -> None : - self.starter_learning_rate = kwarg['starter_learning_rate'] - args = ClassArg()\ - .add('start_pref_e', float, must = True, default = 0.1) \ - .add('limit_pref_e', float, must = True, default = 1.00)\ - .add('start_pref_ed', float, must = True, default = 1.00)\ - .add('limit_pref_ed', float, must = True, default = 1.00) - class_data = args.parse(jdata) - self.start_pref_e = class_data['start_pref_e'] - self.limit_pref_e = class_data['limit_pref_e'] - self.start_pref_ed = class_data['start_pref_ed'] - self.limit_pref_ed = class_data['limit_pref_ed'] + self.starter_learning_rate = starter_learning_rate + self.start_pref_e = start_pref_e + self.limit_pref_e = limit_pref_e + self.start_pref_ed = start_pref_ed + self.limit_pref_ed = limit_pref_ed # data required add_data_requirement('energy', 1, atomic=False, must=True, high_prec=True) add_data_requirement('energy_dipole', 3, atomic=False, must=True, high_prec=False) @@ -308,9 +234,9 @@ def build (self, more_loss['l2_ener_loss'] = l2_ener_loss more_loss['l2_ener_dipole_loss'] = l2_ener_dipole_loss - self.l2_loss_summary = tf.summary.scalar('l2_loss', tf.sqrt(l2_loss)) - self.l2_loss_ener_summary = tf.summary.scalar('l2_ener_loss', tf.sqrt(l2_ener_loss) / global_cvt_2_tf_float(natoms[0])) - self.l2_ener_dipole_loss_summary = tf.summary.scalar('l2_ener_dipole_loss', tf.sqrt(l2_ener_dipole_loss)) + self.l2_loss_summary = tf.summary.scalar('l2_loss_' + suffix, tf.sqrt(l2_loss)) + self.l2_loss_ener_summary = tf.summary.scalar('l2_ener_loss_' + suffix, tf.sqrt(l2_ener_loss) / global_cvt_2_tf_float(natoms[0])) + self.l2_ener_dipole_loss_summary = tf.summary.scalar('l2_ener_dipole_loss_' + suffix, tf.sqrt(l2_ener_dipole_loss)) self.l2_l = l2_loss self.l2_more = more_loss @@ -330,58 +256,3 @@ def eval(self, sess, feed_dict, natoms): 'rmse_ed': np.sqrt(error_ed) } return results - - @staticmethod - def print_header() : # depreciated - prop_fmt = ' %9s %9s' - print_str = '' - print_str += prop_fmt % ('l2_tst', 'l2_trn') - print_str += prop_fmt % ('l2_e_tst', 'l2_e_trn') - print_str += prop_fmt % ('l2_ed_tst', 'l2_ed_trn') - return print_str - - def print_on_training(self, - tb_writer, - cur_batch, - sess, - natoms, - feed_dict_test, - feed_dict_batch): # depreciated - - run_data = [ - self.l2_l, - self.l2_more['l2_ener_loss'], - self.l2_more['l2_ener_dipole_loss'] - ] - - # first train data - train_out = run_sess(sess, run_data, feed_dict=feed_dict_batch) - error_train, error_e_train, error_ed_train = train_out - - # than test data, if tensorboard log writter is present, commpute summary - # and write tensorboard logs - if tb_writer: - summary_merged_op = tf.summary.merge([ - self.l2_loss_summary, - self.l2_loss_ener_summary, - self.l2_ener_dipole_loss_summary - ]) - run_data.insert(0, summary_merged_op) - - test_out = run_sess(sess, run_data, feed_dict=feed_dict_test) - - if tb_writer: - summary = test_out.pop(0) - tb_writer.add_summary(summary, cur_batch) - - error_test, error_e_test, error_ed_test = test_out - - print_str = "" - prop_fmt = " %9.2e %9.2e" - print_str += prop_fmt % (np.sqrt(error_test), np.sqrt(error_train)) - print_str += prop_fmt % (np.sqrt(error_e_test) / natoms[0], np.sqrt(error_e_train) / natoms[0]) - print_str += prop_fmt % (np.sqrt(error_ed_test), np.sqrt(error_ed_train)) - return print_str - - - diff --git a/deepmd/loss/tensor.py b/deepmd/loss/tensor.py index 64763627a3..e7cbde6ebd 100644 --- a/deepmd/loss/tensor.py +++ b/deepmd/loss/tensor.py @@ -1,6 +1,6 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg, add_data_requirement +from deepmd.common import add_data_requirement from deepmd.env import global_cvt_2_tf_float from deepmd.env import global_cvt_2_ener_float @@ -77,7 +77,7 @@ def build (self, local_loss = global_cvt_2_tf_float(find_atomic) * tf.reduce_mean( tf.square(self.scale*(polar - atomic_polar_hat)), name='l2_'+suffix) more_loss['local_loss'] = local_loss l2_loss += self.local_weight * local_loss - self.l2_loss_local_summary = tf.summary.scalar('l2_local_loss', + self.l2_loss_local_summary = tf.summary.scalar('l2_local_loss_' + suffix, tf.sqrt(more_loss['local_loss'])) @@ -101,7 +101,7 @@ def build (self, global_loss = global_cvt_2_tf_float(find_global) * tf.reduce_mean( tf.square(self.scale*(global_polar - polar_hat)), name='l2_'+suffix) more_loss['global_loss'] = global_loss - self.l2_loss_global_summary = tf.summary.scalar('l2_global_loss', + self.l2_loss_global_summary = tf.summary.scalar('l2_global_loss_' + suffix, tf.sqrt(more_loss['global_loss']) / global_cvt_2_tf_float(atoms)) # YWolfeee: should only consider atoms with dipole, i.e. atoms @@ -114,7 +114,7 @@ def build (self, self.l2_more = more_loss self.l2_l = l2_loss - self.l2_loss_summary = tf.summary.scalar('l2_loss', tf.sqrt(l2_loss)) + self.l2_loss_summary = tf.summary.scalar('l2_loss_' + suffix, tf.sqrt(l2_loss)) return l2_loss, more_loss def eval(self, sess, feed_dict, natoms): @@ -134,64 +134,3 @@ def eval(self, sess, feed_dict, natoms): if self.global_weight > 0.0: results["rmse_gl"] = np.sqrt(error_gl) / atoms return results - - def print_header(self): # depreciated - prop_fmt = ' %11s %11s' - print_str = '' - print_str += prop_fmt % ('rmse_tst', 'rmse_trn') - if self.local_weight > 0.0: - print_str += prop_fmt % ('rmse_lc_tst', 'rmse_lc_trn') - if self.global_weight > 0.0: - print_str += prop_fmt % ('rmse_gl_tst', 'rmse_gl_trn') - return print_str - - def print_on_training(self, - tb_writer, - cur_batch, - sess, - natoms, - feed_dict_test, - feed_dict_batch) : # depreciated - - # YHT: added to calculate the atoms number - atoms = 0 - if self.type_sel is not None: - for w in self.type_sel: - atoms += natoms[2+w] - else: - atoms = natoms[0] - - run_data = [self.l2_l, self.l2_more['local_loss'], self.l2_more['global_loss']] - summary_list = [self.l2_loss_summary] - if self.local_weight > 0.0: - summary_list.append(self.l2_loss_local_summary) - if self.global_weight > 0.0: - summary_list.append(self.l2_loss_global_summary) - - # first train data - error_train = run_sess(sess, run_data, feed_dict=feed_dict_batch) - - # than test data, if tensorboard log writter is present, commpute summary - # and write tensorboard logs - if tb_writer: - #summary_merged_op = tf.summary.merge([self.l2_loss_summary]) - summary_merged_op = tf.summary.merge(summary_list) - run_data.insert(0, summary_merged_op) - - test_out = run_sess(sess, run_data, feed_dict=feed_dict_test) - - if tb_writer: - summary = test_out.pop(0) - tb_writer.add_summary(summary, cur_batch) - - error_test = test_out - - print_str = "" - prop_fmt = " %11.2e %11.2e" - print_str += prop_fmt % (np.sqrt(error_test[0]), np.sqrt(error_train[0])) - if self.local_weight > 0.0: - print_str += prop_fmt % (np.sqrt(error_test[1]), np.sqrt(error_train[1]) ) - if self.global_weight > 0.0: - print_str += prop_fmt % (np.sqrt(error_test[2])/atoms, np.sqrt(error_train[2])/atoms) - - return print_str diff --git a/deepmd/model/__init__.py b/deepmd/model/__init__.py index e50a138aec..742836bb14 100644 --- a/deepmd/model/__init__.py +++ b/deepmd/model/__init__.py @@ -3,3 +3,4 @@ from .tensor import DipoleModel from .tensor import PolarModel from .tensor import GlobalPolarModel +from .multi import MultiModel diff --git a/deepmd/model/ener.py b/deepmd/model/ener.py index 7504e22906..b07121e30b 100644 --- a/deepmd/model/ener.py +++ b/deepmd/model/ener.py @@ -5,7 +5,6 @@ from deepmd.utils.pair_tab import PairTab from deepmd.utils.graph import load_graph_def, get_tensor_by_name_from_graph from deepmd.utils.errors import GraphWithoutTensorError -from deepmd.common import ClassArg from deepmd.env import global_cvt_2_ener_float, MODEL_VERSION, GLOBAL_TF_FLOAT_PRECISION from deepmd.env import op_module from .model import Model @@ -171,7 +170,7 @@ def build (self, suffix = suffix, ) input_dict['type_embedding'] = type_embedding - input_dict['atype'] = atype_ + input_dict['atype'] = atype_ if frz_model == None: dout \ diff --git a/deepmd/model/multi.py b/deepmd/model/multi.py new file mode 100644 index 0000000000..5d4cae258c --- /dev/null +++ b/deepmd/model/multi.py @@ -0,0 +1,352 @@ +import numpy as np +from typing import Optional, Tuple, List + +from deepmd.env import tf +from deepmd.utils.pair_tab import PairTab +from deepmd.utils.graph import load_graph_def +from deepmd.env import global_cvt_2_ener_float, MODEL_VERSION, GLOBAL_TF_FLOAT_PRECISION +from deepmd.env import op_module +from .model import Model +from .model_stat import make_stat_input, merge_sys_stat + + +class MultiModel(Model): + """Multi-task model. + + Parameters + ---------- + descrpt + Descriptor + fitting_dict + Dictionary of fitting nets + fitting_type_dict + Dictionary of types of fitting nets + typeebd + Type embedding net + type_map + Mapping atom type to the name (str) of the type. + For example `type_map[1]` gives the name of the type 1. + data_stat_nbatch + Number of frames used for data statistic + data_stat_protect + Protect parameter for atomic energy regression + use_srtab + The table for the short-range pairwise interaction added on top of DP. The table is a text data file with (N_t + 1) * N_t / 2 + 1 columes. The first colume is the distance between atoms. The second to the last columes are energies for pairs of certain types. For example we have two atom types, 0 and 1. The columes from 2nd to 4th are for 0-0, 0-1 and 1-1 correspondingly. + smin_alpha + The short-range tabulated interaction will be swithed according to the distance of the nearest neighbor. This distance is calculated by softmin. This parameter is the decaying parameter in the softmin. It is only required when `use_srtab` is provided. + sw_rmin + The lower boundary of the interpolation between short-range tabulated interaction and DP. It is only required when `use_srtab` is provided. + sw_rmin + The upper boundary of the interpolation between short-range tabulated interaction and DP. It is only required when `use_srtab` is provided. + """ + model_type = 'multi-task' + + def __init__( + self, + descrpt, + fitting_dict, + fitting_type_dict, + typeebd=None, + type_map: Optional[List[str]] = None, + data_stat_nbatch: int = 10, + data_stat_protect: float = 1e-2, + use_srtab: Optional[str] = None, # all the ener fitting will do this + smin_alpha: Optional[float] = None, + sw_rmin: Optional[float] = None, + sw_rmax: Optional[float] = None + ) -> None: + """ + Constructor + """ + # descriptor + self.descrpt = descrpt + self.rcut = self.descrpt.get_rcut() + self.ntypes = self.descrpt.get_ntypes() + # fitting + self.fitting_dict = fitting_dict + self.fitting_type_dict = fitting_type_dict + self.numb_fparam_dict = {item: self.fitting_dict[item].get_numb_fparam() + for item in self.fitting_dict if self.fitting_type_dict[item] == 'ener'} + # type embedding + self.typeebd = typeebd + # other inputs + if type_map is None: + self.type_map = [] + else: + self.type_map = type_map + self.data_stat_nbatch = data_stat_nbatch + self.data_stat_protect = data_stat_protect + self.srtab_name = use_srtab + if self.srtab_name is not None: + self.srtab = PairTab(self.srtab_name) + self.smin_alpha = smin_alpha + self.sw_rmin = sw_rmin + self.sw_rmax = sw_rmax + else: + self.srtab = None + + def get_rcut(self): + return self.rcut + + def get_ntypes(self): + return self.ntypes + + def get_type_map(self): + return self.type_map + + def data_stat(self, data): + for fitting_key in data: + all_stat = make_stat_input(data[fitting_key], self.data_stat_nbatch, merge_sys=False) + m_all_stat = merge_sys_stat(all_stat) + self._compute_input_stat(m_all_stat, protection=self.data_stat_protect, + mixed_type=data[fitting_key].mixed_type, fitting_key=fitting_key) + self._compute_output_stat(all_stat, mixed_type=data[fitting_key].mixed_type, fitting_key=fitting_key) + self.descrpt.merge_input_stats(self.descrpt.stat_dict) + + def _compute_input_stat(self, all_stat, protection=1e-2, mixed_type=False, fitting_key=''): + if mixed_type: + self.descrpt.compute_input_stats(all_stat['coord'], + all_stat['box'], + all_stat['type'], + all_stat['natoms_vec'], + all_stat['default_mesh'], + all_stat, + mixed_type, + all_stat['real_natoms_vec']) + else: + self.descrpt.compute_input_stats(all_stat['coord'], + all_stat['box'], + all_stat['type'], + all_stat['natoms_vec'], + all_stat['default_mesh'], + all_stat) + if hasattr(self.fitting_dict[fitting_key], 'compute_input_stats'): + self.fitting_dict[fitting_key].compute_input_stats(all_stat, protection=protection) + + def _compute_output_stat(self, all_stat, mixed_type=False, fitting_key=''): + if hasattr(self.fitting_dict[fitting_key], 'compute_output_stats'): + if mixed_type: + self.fitting_dict[fitting_key].compute_output_stats(all_stat, mixed_type=mixed_type) + else: + self.fitting_dict[fitting_key].compute_output_stats(all_stat) + + def build(self, + coord_, + atype_, + natoms, + box, + mesh, + input_dict, + frz_model=None, + suffix='', + reuse=None): + + if input_dict is None: + input_dict = {} + with tf.variable_scope('model_attr' + suffix, reuse=reuse): + t_tmap = tf.constant(' '.join(self.type_map), + name='tmap', + dtype=tf.string) + t_mt = tf.constant(self.model_type, + name='model_type', + dtype=tf.string) + t_ver = tf.constant(MODEL_VERSION, + name='model_version', + dtype=tf.string) + t_st = {} + t_od = {} + sel_type = {} + natomsel = {} + nout = {} + for fitting_key in self.fitting_dict: + if self.fitting_type_dict[fitting_key] in ['dipole', 'polar', 'global_polar']: + sel_type[fitting_key] = self.fitting_dict[fitting_key].get_sel_type() + natomsel[fitting_key] = sum(natoms[2 + type_i] for type_i in sel_type[fitting_key]) + nout[fitting_key] = self.fitting_dict[fitting_key].get_out_size() + t_st[fitting_key] = tf.constant(sel_type[fitting_key], + name='sel_type_{}'.format(fitting_key), + dtype=tf.int32) + t_od[fitting_key] = tf.constant(nout[fitting_key], + name='output_dim_{}'.format(fitting_key), + dtype=tf.int32) + + if self.srtab is not None: + tab_info, tab_data = self.srtab.get() + self.tab_info = tf.get_variable('t_tab_info', + tab_info.shape, + dtype=tf.float64, + trainable=False, + initializer=tf.constant_initializer(tab_info, dtype=tf.float64)) + self.tab_data = tf.get_variable('t_tab_data', + tab_data.shape, + dtype=tf.float64, + trainable=False, + initializer=tf.constant_initializer(tab_data, dtype=tf.float64)) + + coord = tf.reshape(coord_, [-1, natoms[1] * 3]) + atype = tf.reshape(atype_, [-1, natoms[1]]) + input_dict['nframes'] = tf.shape(coord)[0] + + # type embedding if any + if self.typeebd is not None: + type_embedding = self.typeebd.build( + self.ntypes, + reuse=reuse, + suffix=suffix, + ) + input_dict['type_embedding'] = type_embedding + input_dict['atype'] = atype_ + + dout \ + = self.descrpt.build(coord_, + atype_, + natoms, + box, + mesh, + input_dict, + suffix=suffix, + reuse=reuse) + dout = tf.identity(dout, name='o_descriptor') + + if self.srtab is not None: + nlist, rij, sel_a, sel_r = self.descrpt.get_nlist() + nnei_a = np.cumsum(sel_a)[-1] + nnei_r = np.cumsum(sel_r)[-1] + sw_lambda, sw_deriv \ + = op_module.soft_min_switch(atype, + rij, + nlist, + natoms, + sel_a=sel_a, + sel_r=sel_r, + alpha=self.smin_alpha, + rmin=self.sw_rmin, + rmax=self.sw_rmax) + inv_sw_lambda = 1.0 - sw_lambda + # NOTICE: + # atom energy is not scaled, + # force and virial are scaled + tab_atom_ener, tab_force, tab_atom_virial \ + = op_module.pair_tab(self.tab_info, + self.tab_data, + atype, + rij, + nlist, + natoms, + sw_lambda, + sel_a=sel_a, + sel_r=sel_r) + + rot_mat = self.descrpt.get_rot_mat() + rot_mat = tf.identity(rot_mat, name='o_rot_mat' + suffix) + self.atom_ener = {} + model_dict = {} + for fitting_key in self.fitting_dict: + if self.fitting_type_dict[fitting_key] == 'ener': + atom_ener = self.fitting_dict[fitting_key].build(dout, + natoms, + input_dict, + reuse=reuse, + suffix='_{}'.format(fitting_key) + suffix) + self.atom_ener[fitting_key] = atom_ener + if self.srtab is not None: + energy_diff = tab_atom_ener - tf.reshape(atom_ener, [-1, natoms[0]]) + tab_atom_ener = tf.reshape(sw_lambda, [-1]) * tf.reshape(tab_atom_ener, [-1]) + atom_ener = tf.reshape(inv_sw_lambda, [-1]) * atom_ener + energy_raw = tab_atom_ener + atom_ener + else: + energy_raw = atom_ener + energy_raw = tf.reshape(energy_raw, [-1, natoms[0]], + name='o_atom_energy_{}'.format(fitting_key) + suffix) + energy = tf.reduce_sum(global_cvt_2_ener_float(energy_raw), axis=1, + name='o_energy_{}'.format(fitting_key) + suffix) + force, virial, atom_virial \ + = self.descrpt.prod_force_virial(atom_ener, natoms) + + if self.srtab is not None: + sw_force \ + = op_module.soft_min_force(energy_diff, + sw_deriv, + nlist, + natoms, + n_a_sel=nnei_a, + n_r_sel=nnei_r) + force = force + sw_force + tab_force + + force = tf.reshape(force, [-1, 3 * natoms[1]], name="o_force_{}".format(fitting_key) + suffix) + + if self.srtab is not None: + sw_virial, sw_atom_virial \ + = op_module.soft_min_virial(energy_diff, + sw_deriv, + rij, + nlist, + natoms, + n_a_sel=nnei_a, + n_r_sel=nnei_r) + atom_virial = atom_virial + sw_atom_virial + tab_atom_virial + virial = virial + sw_virial + tf.reduce_sum(tf.reshape(tab_atom_virial, [-1, natoms[1], 9]), axis=1) + + virial = tf.reshape(virial, [-1, 9], name="o_virial_{}".format(fitting_key) + suffix) + atom_virial = tf.reshape(atom_virial, [-1, 9 * natoms[1]], + name="o_atom_virial_{}".format(fitting_key) + suffix) + + model_dict[fitting_key] = {} + model_dict[fitting_key]['energy'] = energy + model_dict[fitting_key]['force'] = force + model_dict[fitting_key]['virial'] = virial + model_dict[fitting_key]['atom_ener'] = energy_raw + model_dict[fitting_key]['atom_virial'] = atom_virial + model_dict[fitting_key]['coord'] = coord + model_dict[fitting_key]['atype'] = atype + elif self.fitting_type_dict[fitting_key] in ['dipole', 'polar', 'global_polar']: + tensor_name = self.fitting_type_dict[fitting_key] + output = self.fitting_dict[fitting_key].build(dout, + rot_mat, + natoms, + input_dict, + reuse=reuse, + suffix='_{}'.format(fitting_key) + suffix) + framesize = nout if "global" in tensor_name else \ + natomsel[fitting_key] * nout[fitting_key] + output = tf.reshape(output, [-1, framesize], + name='o_{}_{}'.format(tensor_name, fitting_key) + suffix) + + model_dict[fitting_key] = {} + model_dict[fitting_key][tensor_name] = output + + if "global" not in tensor_name: + gname = "global_" + tensor_name + atom_out = tf.reshape(output, [-1, natomsel[fitting_key], nout[fitting_key]]) + global_out = tf.reduce_sum(atom_out, axis=1) + global_out = tf.reshape(global_out, [-1, nout[fitting_key]], + name="o_{}_{}".format(gname, fitting_key) + suffix) + + out_cpnts = tf.split(atom_out, nout[fitting_key], axis=-1) + force_cpnts = [] + virial_cpnts = [] + atom_virial_cpnts = [] + + for out_i in out_cpnts: + force_i, virial_i, atom_virial_i \ + = self.descrpt.prod_force_virial(out_i, natoms) + force_cpnts.append(tf.reshape(force_i, [-1, 3 * natoms[1]])) + virial_cpnts.append(tf.reshape(virial_i, [-1, 9])) + atom_virial_cpnts.append(tf.reshape(atom_virial_i, [-1, 9 * natoms[1]])) + + # [nframe x nout x (natom x 3)] + force = tf.concat(force_cpnts, axis=1, + name="o_force_{}".format(fitting_key) + suffix) + # [nframe x nout x 9] + virial = tf.concat(virial_cpnts, axis=1, + name="o_virial_{}".format(fitting_key) + suffix) + # [nframe x nout x (natom x 9)] + atom_virial = tf.concat(atom_virial_cpnts, axis=1, + name="o_atom_virial_{}".format(fitting_key) + suffix) + + model_dict[fitting_key][gname] = global_out + model_dict[fitting_key]["force"] = force + model_dict[fitting_key]["virial"] = virial + model_dict[fitting_key]["atom_virial"] = atom_virial + + return model_dict diff --git a/deepmd/model/tensor.py b/deepmd/model/tensor.py index 141904e9cf..26c813cfbf 100644 --- a/deepmd/model/tensor.py +++ b/deepmd/model/tensor.py @@ -2,7 +2,6 @@ from typing import Tuple, List from deepmd.env import tf -from deepmd.common import ClassArg from deepmd.env import global_cvt_2_ener_float, MODEL_VERSION, GLOBAL_TF_FLOAT_PRECISION from deepmd.env import op_module from deepmd.utils.graph import load_graph_def @@ -20,6 +19,8 @@ class TensorModel(Model) : Descriptor fitting Fitting net + typeebd + Type embedding net type_map Mapping atom type to the name (str) of the type. For example `type_map[1]` gives the name of the type 1. @@ -32,7 +33,8 @@ def __init__ ( self, tensor_name : str, descrpt, - fitting, + fitting, + typeebd=None, type_map : List[str] = None, data_stat_nbatch : int = 10, data_stat_protect : float = 1e-2, @@ -47,6 +49,8 @@ def __init__ ( self.ntypes = self.descrpt.get_ntypes() # fitting self.fitting = fitting + # type embedding + self.typeebd = typeebd # other params if type_map is None: self.type_map = [] @@ -100,6 +104,9 @@ def build (self, frz_model = None, suffix = '', reuse = None): + + if input_dict is None: + input_dict = {} with tf.variable_scope('model_attr' + suffix, reuse = reuse) : t_tmap = tf.constant(' '.join(self.type_map), name = 'tmap', @@ -120,6 +127,20 @@ def build (self, natomsel = sum(natoms[2+type_i] for type_i in self.get_sel_type()) nout = self.get_out_size() + coord = tf.reshape(coord_, [-1, natoms[1] * 3]) + atype = tf.reshape(atype_, [-1, natoms[1]]) + input_dict['nframes'] = tf.shape(coord)[0] + + # type embedding if any + if self.typeebd is not None: + type_embedding = self.typeebd.build( + self.ntypes, + reuse=reuse, + suffix=suffix, + ) + input_dict['type_embedding'] = type_embedding + input_dict['atype'] = atype_ + if frz_model == None: dout \ = self.descrpt.build(coord_, @@ -150,7 +171,8 @@ def build (self, output = self.fitting.build (dout, rot_mat, - natoms, + natoms, + input_dict, reuse = reuse, suffix = suffix) framesize = nout if "global" in self.model_type else natomsel * nout @@ -226,47 +248,20 @@ def init_variables(self, class WFCModel(TensorModel): - def __init__( - self, - descrpt, - fitting, - type_map : List[str] = None, - data_stat_nbatch : int = 10, - data_stat_protect : float = 1e-2 - ) -> None: - TensorModel.__init__(self, 'wfc', descrpt, fitting, type_map, data_stat_nbatch, data_stat_protect) + def __init__(self, *args, **kwargs) -> None: + TensorModel.__init__(self, 'wfc', *args, **kwargs) + class DipoleModel(TensorModel): - def __init__( - self, - descrpt, - fitting, - type_map : List[str] = None, - data_stat_nbatch : int = 10, - data_stat_protect : float = 1e-2 - ) -> None: - TensorModel.__init__(self, 'dipole', descrpt, fitting, type_map, data_stat_nbatch, data_stat_protect) + def __init__(self, *args, **kwargs) -> None: + TensorModel.__init__(self, 'dipole', *args, **kwargs) -class PolarModel(TensorModel): - def __init__( - self, - descrpt, - fitting, - type_map : List[str] = None, - data_stat_nbatch : int = 10, - data_stat_protect : float = 1e-2 - ) -> None: - TensorModel.__init__(self, 'polar', descrpt, fitting, type_map, data_stat_nbatch, data_stat_protect) -class GlobalPolarModel(TensorModel): - def __init__( - self, - descrpt, - fitting, - type_map : List[str] = None, - data_stat_nbatch : int = 10, - data_stat_protect : float = 1e-2 - ) -> None: - TensorModel.__init__(self, 'global_polar', descrpt, fitting, type_map, data_stat_nbatch, data_stat_protect) +class PolarModel(TensorModel): + def __init__(self, *args, **kwargs) -> None: + TensorModel.__init__(self, 'polar', *args, **kwargs) +class GlobalPolarModel(TensorModel): + def __init__(self, *args, **kwargs) -> None: + TensorModel.__init__(self, 'global_polar', *args, **kwargs) diff --git a/deepmd/nvnmd/data/data.py b/deepmd/nvnmd/data/data.py index 0013c7f226..c098d74bd8 100644 --- a/deepmd/nvnmd/data/data.py +++ b/deepmd/nvnmd/data/data.py @@ -270,11 +270,11 @@ } } NVNMD_WELCOME = ( - " _ _ __ __ _ _ __ __ ____ ", - "| \ | | \ \ / / | \ | | | \/ | | _ \ ", - "| \| | \ \ / / | \| | | |\/| | | | | |", - "| |\ | \ V / | |\ | | | | | | |_| |", - "|_| \_| \_/ |_| \_| |_| |_| |____/ ", + r" _ _ __ __ _ _ __ __ ____ ", + r"| \ | | \ \ / / | \ | | | \/ | | _ \ ", + r"| \| | \ \ / / | \| | | |\/| | | | | |", + r"| |\ | \ V / | |\ | | | | | | |_| |", + r"|_| \_| \_/ |_| \_| |_| |_| |____/ ", ) NVNMD_CITATION = ( diff --git a/deepmd/nvnmd/utils/fio.py b/deepmd/nvnmd/utils/fio.py index 5d1f43f6e9..5f411370f9 100644 --- a/deepmd/nvnmd/utils/fio.py +++ b/deepmd/nvnmd/utils/fio.py @@ -3,6 +3,7 @@ import numpy as np import json import struct +from typing import List import logging log = logging.getLogger(__name__) @@ -166,18 +167,18 @@ def load(self, file_name='', default_value=''): log.warning(f"can not find {file_name}") return default_value - def save(self, file_name: str = '', data: str = ''): + def save(self, file_name: str, data: List[str]): r"""Save hex string into binary file """ log.info(f"write binary to {file_name}") Fio().create_file_path(file_name) + + buff = [] + for si in data: + buff.extend(list(bytearray.fromhex(si))) + with open(file_name, 'wb') as fp: - for si in data: - # one byte consists of two hex chars - for ii in range(len(si) // 2): - v = int(si[2 * ii: 2 * (ii + 1)], 16) - v = struct.pack('B', v) - fp.write(v) + fp.write(struct.pack('%sB' % len(buff), *buff)) class FioTxt(): diff --git a/deepmd/train/run_options.py b/deepmd/train/run_options.py index 98ce9d3a9d..0dc13dc79b 100644 --- a/deepmd/train/run_options.py +++ b/deepmd/train/run_options.py @@ -26,12 +26,12 @@ # http://patorjk.com/software/taag. Font:Big" WELCOME = ( # noqa - " _____ _____ __ __ _____ _ _ _ ", - "| __ \ | __ \ | \/ || __ \ | | (_)| | ", - "| | | | ___ ___ | |__) || \ / || | | | ______ | | __ _ | |_ ", - "| | | | / _ \ / _ \| ___/ | |\/| || | | ||______|| |/ /| || __|", - "| |__| || __/| __/| | | | | || |__| | | < | || |_ ", - "|_____/ \___| \___||_| |_| |_||_____/ |_|\_\|_| \__|", + r" _____ _____ __ __ _____ _ _ _ ", + r"| __ \ | __ \ | \/ || __ \ | | (_)| | ", + r"| | | | ___ ___ | |__) || \ / || | | | ______ | | __ _ | |_ ", + r"| | | | / _ \ / _ \| ___/ | |\/| || | | ||______|| |/ /| || __|", + r"| |__| || __/| __/| | | | | || |__| | | < | || |_ ", + r"|_____/ \___| \___||_| |_| |_||_____/ |_|\_\|_| \__|", ) CITATION = ( @@ -89,6 +89,7 @@ def __init__( self, init_model: Optional[str] = None, init_frz_model: Optional[str] = None, + finetune: Optional[str] = None, restart: Optional[str] = None, log_path: Optional[str] = None, log_level: int = 0, @@ -96,14 +97,10 @@ def __init__( ): self._try_init_distrib() - if all((init_model, restart)): - raise RuntimeError( - "--init-model and --restart should not be set at the same time" - ) - # model init options self.restart = restart self.init_model = init_model + self.finetune = finetune self.init_mode = "init_from_scratch" if restart is not None: @@ -115,6 +112,9 @@ def __init__( elif init_frz_model is not None: self.init_frz_model = os.path.abspath(init_frz_model) self.init_mode = "init_from_frz_model" + elif finetune is not None: + self.finetune = os.path.abspath(finetune) + self.init_mode = "finetune" self._setup_logger(Path(log_path) if log_path else None, log_level, mpi_log) @@ -133,8 +133,12 @@ def print_resource_summary(self): log.info(f"node list: {self.nodelist}") log.info(f"running on: {self.nodename}") log.info(f"computing device: {self.my_device}") - env_value = os.environ.get('CUDA_VISIBLE_DEVICES', 'unset') - log.info(f"CUDA_VISIBLE_DEVICES: {env_value}") + if tf.test.is_built_with_cuda(): + env_value = os.environ.get('CUDA_VISIBLE_DEVICES', 'unset') + log.info(f"CUDA_VISIBLE_DEVICES: {env_value}") + if hasattr(tf.test, 'is_built_with_rocm') and tf.test.is_built_with_rocm(): + env_value = os.environ.get('HIP_VISIBLE_DEVICES', 'unset') + log.info(f"HIP_VISIBLE_DEVICES: {env_value}") log.info(f"Count of visible GPU: {len(self.gpus or [])}") intra, inter = get_tf_default_nthreads() log.info(f"num_intra_threads: {intra:d}") diff --git a/deepmd/train/trainer.py b/deepmd/train/trainer.py index 79038709c1..8a93110211 100644 --- a/deepmd/train/trainer.py +++ b/deepmd/train/trainer.py @@ -14,9 +14,9 @@ from deepmd.env import get_tf_session_config from deepmd.env import GLOBAL_TF_FLOAT_PRECISION from deepmd.env import GLOBAL_ENER_FLOAT_PRECISION -from deepmd.fit import EnerFitting, WFCFitting, PolarFittingLocFrame, PolarFittingSeA, GlobalPolarFittingSeA, DipoleFittingSeA +from deepmd.fit import EnerFitting, PolarFittingSeA, DipoleFittingSeA from deepmd.descriptor import Descriptor -from deepmd.model import EnerModel, WFCModel, DipoleModel, PolarModel, GlobalPolarModel +from deepmd.model import EnerModel, WFCModel, DipoleModel, PolarModel, GlobalPolarModel, MultiModel from deepmd.loss import EnerStdLoss, EnerDipoleLoss, TensorLoss from deepmd.utils.errors import GraphTooLargeError from deepmd.utils.learning_rate import LearningRateExp @@ -25,6 +25,7 @@ from deepmd.utils.type_embed import TypeEmbedNet from deepmd.utils.graph import load_graph_def, get_tensor_by_name_from_graph from deepmd.utils.argcheck import type_embedding_args +from deepmd.utils import random as dp_random from tensorflow.python.client import timeline from deepmd.env import op_module, TF_VERSION @@ -33,7 +34,7 @@ # load grad of force module import deepmd.op -from deepmd.common import j_must_have, ClassArg, data_requirement, get_precision +from deepmd.common import j_must_have, data_requirement, get_precision log = logging.getLogger(__name__) @@ -61,8 +62,10 @@ def __init__(self, def _init_param(self, jdata): # model config model_param = j_must_have(jdata, 'model') + self.multi_task_mode = 'fitting_net_dict' in model_param descrpt_param = j_must_have(model_param, 'descriptor') - fitting_param = j_must_have(model_param, 'fitting_net') + fitting_param = j_must_have(model_param, 'fitting_net') \ + if not self.multi_task_mode else j_must_have(model_param, 'fitting_net_dict') typeebd_param = model_param.get('type_embedding', None) self.model_param = model_param self.descrpt_param = descrpt_param @@ -84,36 +87,43 @@ def _init_param(self, jdata): if descrpt_param['type'] in ['se_atten']: descrpt_param['ntypes'] = len(model_param['type_map']) + if self.multi_task_mode: + descrpt_param['multi_task'] = True self.descrpt = Descriptor(**descrpt_param) # fitting net - fitting_type = fitting_param.get('type', 'ener') - self.fitting_type = fitting_type - fitting_param.pop('type', None) - fitting_param['descrpt'] = self.descrpt - if fitting_type == 'ener': - self.fitting = EnerFitting(**fitting_param) - # elif fitting_type == 'wfc': - # self.fitting = WFCFitting(fitting_param, self.descrpt) - elif fitting_type == 'dipole': - if descrpt_type == 'se_e2_a': - self.fitting = DipoleFittingSeA(**fitting_param) - else : - raise RuntimeError('fitting dipole only supports descrptors: se_e2_a') - elif fitting_type == 'polar': - # if descrpt_type == 'loc_frame': - # self.fitting = PolarFittingLocFrame(fitting_param, self.descrpt) - if descrpt_type == 'se_e2_a': - self.fitting = PolarFittingSeA(**fitting_param) - else : - raise RuntimeError('fitting polar only supports descrptors: loc_frame and se_e2_a') - elif fitting_type == 'global_polar': - if descrpt_type == 'se_e2_a': - self.fitting = GlobalPolarFittingSeA(**fitting_param) - else : - raise RuntimeError('fitting global_polar only supports descrptors: loc_frame and se_e2_a') - else : - raise RuntimeError('unknow fitting type ' + fitting_type) + def fitting_net_init(fitting_type_, descrpt_type_, params): + if fitting_type_ == 'ener': + return EnerFitting(**params) + elif fitting_type_ == 'dipole': + return DipoleFittingSeA(**params) + elif fitting_type_ == 'polar': + return PolarFittingSeA(**params) + # elif fitting_type_ == 'global_polar': + # if descrpt_type_ == 'se_e2_a': + # return GlobalPolarFittingSeA(**params) + # else: + # raise RuntimeError('fitting global_polar only supports descrptors: loc_frame and se_e2_a') + else: + raise RuntimeError('unknow fitting type ' + fitting_type_) + + if not self.multi_task_mode: + fitting_type = fitting_param.get('type', 'ener') + self.fitting_type = fitting_type + fitting_param.pop('type', None) + fitting_param['descrpt'] = self.descrpt + self.fitting = fitting_net_init(fitting_type, descrpt_type, fitting_param) + else: + self.fitting_dict = {} + self.fitting_type_dict = {} + self.nfitting = len(fitting_param) + for item in fitting_param: + item_fitting_param = fitting_param[item] + item_fitting_type = item_fitting_param.get('type', 'ener') + self.fitting_type_dict[item] = item_fitting_type + item_fitting_param.pop('type', None) + item_fitting_param['descrpt'] = self.descrpt + self.fitting_dict[item] = fitting_net_init(item_fitting_type, descrpt_type, item_fitting_param) # type embedding padding = False @@ -146,10 +156,55 @@ def _init_param(self, jdata): # init model # infer model type by fitting_type - if fitting_type == 'ener': - self.model = EnerModel( - self.descrpt, - self.fitting, + if not self.multi_task_mode: + if self.fitting_type == 'ener': + self.model = EnerModel( + self.descrpt, + self.fitting, + self.typeebd, + model_param.get('type_map'), + model_param.get('data_stat_nbatch', 10), + model_param.get('data_stat_protect', 1e-2), + model_param.get('use_srtab'), + model_param.get('smin_alpha'), + model_param.get('sw_rmin'), + model_param.get('sw_rmax') + ) + # elif fitting_type == 'wfc': + # self.model = WFCModel(model_param, self.descrpt, self.fitting) + elif self.fitting_type == 'dipole': + self.model = DipoleModel( + self.descrpt, + self.fitting, + self.typeebd, + model_param.get('type_map'), + model_param.get('data_stat_nbatch', 10), + model_param.get('data_stat_protect', 1e-2) + ) + elif self.fitting_type == 'polar': + self.model = PolarModel( + self.descrpt, + self.fitting, + self.typeebd, + model_param.get('type_map'), + model_param.get('data_stat_nbatch', 10), + model_param.get('data_stat_protect', 1e-2) + ) + # elif self.fitting_type == 'global_polar': + # self.model = GlobalPolarModel( + # self.descrpt, + # self.fitting, + # model_param.get('type_map'), + # model_param.get('data_stat_nbatch', 10), + # model_param.get('data_stat_protect', 1e-2) + # ) + else : + raise RuntimeError('get unknown fitting type when building model') + else: # multi-task mode + self.model = MultiModel( + self.descrpt, + self.fitting_dict, + self.fitting_type_dict, self.typeebd, model_param.get('type_map'), model_param.get('data_stat_nbatch', 10), @@ -159,34 +214,6 @@ def _init_param(self, jdata): model_param.get('sw_rmin'), model_param.get('sw_rmax') ) - # elif fitting_type == 'wfc': - # self.model = WFCModel(model_param, self.descrpt, self.fitting) - elif fitting_type == 'dipole': - self.model = DipoleModel( - self.descrpt, - self.fitting, - model_param.get('type_map'), - model_param.get('data_stat_nbatch', 10), - model_param.get('data_stat_protect', 1e-2) - ) - elif fitting_type == 'polar': - self.model = PolarModel( - self.descrpt, - self.fitting, - model_param.get('type_map'), - model_param.get('data_stat_nbatch', 10), - model_param.get('data_stat_protect', 1e-2) - ) - elif fitting_type == 'global_polar': - self.model = GlobalPolarModel( - self.descrpt, - self.fitting, - model_param.get('type_map'), - model_param.get('data_stat_nbatch', 10), - model_param.get('data_stat_protect', 1e-2) - ) - else : - raise RuntimeError('get unknown fitting type when building model') # learning rate lr_param = j_must_have(jdata, 'learning_rate') @@ -207,48 +234,67 @@ def _init_param(self, jdata): # loss # infer loss type by fitting_type - loss_param = jdata.get('loss', None) - loss_type = loss_param.get('type', 'ener') - - if fitting_type == 'ener': - loss_param.pop('type', None) - loss_param['starter_learning_rate'] = self.lr.start_lr() - if loss_type == 'ener': - self.loss = EnerStdLoss(**loss_param) - elif loss_type == 'ener_dipole': - self.loss = EnerDipoleLoss(**loss_param) + def loss_init(_loss_param, _fitting_type, _fitting, _lr): + _loss_type = _loss_param.get('type', 'ener') + if _fitting_type == 'ener': + _loss_param.pop('type', None) + _loss_param['starter_learning_rate'] = _lr.start_lr() + if _loss_type == 'ener': + loss = EnerStdLoss(**_loss_param) + elif _loss_type == 'ener_dipole': + loss = EnerDipoleLoss(**_loss_param) + else: + raise RuntimeError('unknow loss type') + elif _fitting_type == 'wfc': + loss = TensorLoss(_loss_param, + model=_fitting, + tensor_name='wfc', + tensor_size=_fitting.get_out_size(), + label_name='wfc') + elif _fitting_type == 'dipole': + loss = TensorLoss(_loss_param, + model=_fitting, + tensor_name='dipole', + tensor_size=3, + label_name='dipole') + elif _fitting_type == 'polar': + loss = TensorLoss(_loss_param, + model=_fitting, + tensor_name='polar', + tensor_size=9, + label_name='polarizability') + elif _fitting_type == 'global_polar': + loss = TensorLoss(_loss_param, + model=_fitting, + tensor_name='global_polar', + tensor_size=9, + atomic=False, + label_name='polarizability') else: - raise RuntimeError('unknow loss type') - elif fitting_type == 'wfc': - self.loss = TensorLoss(loss_param, - model = self.model, - tensor_name = 'wfc', - tensor_size = self.model.get_out_size(), - label_name = 'wfc') - elif fitting_type == 'dipole': - self.loss = TensorLoss(loss_param, - model = self.model, - tensor_name = 'dipole', - tensor_size = 3, - label_name = 'dipole') - elif fitting_type == 'polar': - self.loss = TensorLoss(loss_param, - model = self.model, - tensor_name = 'polar', - tensor_size = 9, - label_name = 'polarizability') - elif fitting_type == 'global_polar': - self.loss = TensorLoss(loss_param, - model = self.model, - tensor_name = 'global_polar', - tensor_size = 9, - atomic = False, - label_name = 'polarizability') - else : - raise RuntimeError('get unknown fitting type when building loss function') + raise RuntimeError('get unknown fitting type when building loss function') + return loss + + if not self.multi_task_mode: + loss_param = jdata.get('loss', {}) + self.loss = loss_init(loss_param, self.fitting_type, self.fitting, self.lr) + else: + self.loss_dict = {} + loss_param_dict = jdata.get('loss_dict', {}) + for fitting_key in self.fitting_type_dict: + loss_param = loss_param_dict.get(fitting_key, {}) + self.loss_dict[fitting_key] = loss_init(loss_param, self.fitting_type_dict[fitting_key], + self.fitting_dict[fitting_key], self.lr) # training tr_data = jdata['training'] + self.fitting_weight = tr_data.get('fitting_weight', None) + if self.multi_task_mode: + self.fitting_key_list = [] + self.fitting_prob = [] + for fitting_key in self.fitting_type_dict: + self.fitting_key_list.append(fitting_key) + # multi-task mode must have self.fitting_weight + self.fitting_prob.append(self.fitting_weight[fitting_key]) self.disp_file = tr_data.get('disp_file', 'lcurve.out') self.disp_freq = tr_data.get('disp_freq', 1000) self.save_freq = tr_data.get('save_freq', 1000) @@ -263,23 +309,38 @@ def _init_param(self, jdata): self.tensorboard_freq = tr_data.get('tensorboard_freq', 1) self.mixed_prec = tr_data.get('mixed_precision', None) if self.mixed_prec is not None: - if (self.mixed_prec['compute_prec'] != 'float16' or self.mixed_prec['output_prec'] != 'float32'): + if (self.mixed_prec['compute_prec'] not in ('float16', 'bfloat16') or self.mixed_prec['output_prec'] != 'float32'): raise RuntimeError( "Unsupported mixed precision option [output_prec, compute_prec]: [%s, %s], " - " Supported: [float32, float16], Please set mixed precision option correctly!" + " Supported: [float32, float16/bfloat16], Please set mixed precision option correctly!" % (self.mixed_prec['output_prec'], self.mixed_prec['compute_prec'])) # self.sys_probs = tr_data['sys_probs'] # self.auto_prob_style = tr_data['auto_prob'] self.useBN = False - if fitting_type == 'ener' and self.fitting.get_numb_fparam() > 0 : - self.numb_fparam = self.fitting.get_numb_fparam() - else : - self.numb_fparam = 0 + if not self.multi_task_mode: + if self.fitting_type == 'ener' and self.fitting.get_numb_fparam() > 0 : + self.numb_fparam = self.fitting.get_numb_fparam() + else: + self.numb_fparam = 0 - if tr_data.get("validation_data", None) is not None: - self.valid_numb_batch = tr_data["validation_data"].get("numb_btch", 1) + if tr_data.get("validation_data", None) is not None: + self.valid_numb_batch = tr_data["validation_data"].get("numb_btch", 1) + else: + self.valid_numb_batch = 1 else: - self.valid_numb_batch = 1 + self.numb_fparam_dict = {} + self.valid_numb_batch_dict = {} + for fitting_key in self.fitting_type_dict: + if self.fitting_type_dict[fitting_key] == 'ener' and self.fitting_dict[fitting_key].get_numb_fparam() > 0 : + self.numb_fparam_dict[fitting_key] = self.fitting_dict[fitting_key].get_numb_fparam() + else: + self.numb_fparam_dict[fitting_key] = 0 + data_dict = tr_data.get("data_dict", None) + for systems in data_dict: + if data_dict[systems].get("validation_data", None) is not None: + self.valid_numb_batch_dict[systems] = data_dict[systems]["validation_data"].get("numb_btch", 1) + else: + self.valid_numb_batch_dict[systems] = 1 # if init the graph with the frozen model self.frz_model = None @@ -289,24 +350,46 @@ def _init_param(self, jdata): def build (self, data = None, stop_batch = 0, + origin_type_map = None, suffix = "") : self.ntypes = self.model.get_ntypes() self.stop_batch = stop_batch - if not self.is_compress and data.mixed_type: - assert self.descrpt_type in ['se_atten'], 'Data in mixed_type format must use attention descriptor!' - assert self.fitting_type in ['ener'], 'Data in mixed_type format must use ener fitting!' + if not self.multi_task_mode: + if not self.is_compress and data.mixed_type: + assert self.descrpt_type in ['se_atten'], 'Data in mixed_type format must use attention descriptor!' + assert self.fitting_type in ['ener'], 'Data in mixed_type format must use ener fitting!' - if self.numb_fparam > 0 : - log.info("training with %d frame parameter(s)" % self.numb_fparam) + if self.numb_fparam > 0 : + log.info("training with %d frame parameter(s)" % self.numb_fparam) + else: + log.info("training without frame parameter") else: - log.info("training without frame parameter") + assert not self.is_compress, 'You should not reach here, multi-task input could not be compressed! ' + self.valid_fitting_key = [] + for fitting_key in data: + self.valid_fitting_key.append(fitting_key) + if data[fitting_key].mixed_type: + assert self.descrpt_type in ['se_atten'], 'Data for fitting net {} in mixed_type format ' \ + 'must use attention descriptor!'.format(fitting_key) + assert self.fitting_type_dict[fitting_key] in ['ener'], \ + 'Data for fitting net {} in mixed_type format must use ener fitting!'.format(fitting_key) + + if self.numb_fparam_dict[fitting_key] > 0: + log.info("fitting net %s training with %d frame parameter(s)" % + (fitting_key, self.numb_fparam_dict[fitting_key])) + else: + log.info("fitting net %s training without frame parameter" % fitting_key) if not self.is_compress: # Usually, the type number of the model should be equal to that of the data # However, nt_model > nt_data should be allowed, since users may only want to - # train using a dataset that only have some of elements - if self.ntypes < data.get_ntypes(): + # train using a dataset that only have some of elements + if not self.multi_task_mode: + single_data = data + else: + single_data = data[list(data.keys())[0]] + if self.ntypes < single_data.get_ntypes(): raise ValueError( "The number of types of the training data is %d, but that of the " "model is only %d. The latter must be no less than the former. " @@ -314,11 +397,16 @@ def build (self, "is given by `model/type_map` in the training parameter (if set) " "or the maximum number in the training data. The latter is given " "by `model/descriptor/sel` in the training parameter." % ( - data.get_ntypes(), self.ntypes + single_data.get_ntypes(), self.ntypes )) - self.type_map = data.get_type_map() - self.batch_size = data.get_batch_size() - if self.run_opt.init_mode not in ('init_from_model', 'restart', 'init_from_frz_model'): + self.type_map = single_data.get_type_map() + if not self.multi_task_mode: + self.batch_size = data.get_batch_size() + else: + self.batch_size = {} + for fitting_key in data: + self.batch_size[fitting_key] = data[fitting_key].get_batch_size() + if self.run_opt.init_mode not in ('init_from_model', 'restart', 'init_from_frz_model', 'finetune'): # self.saver.restore (in self._init_session) will restore avg and std variables, so data_stat is useless # init_from_frz_model will restore data_stat variables in `init_variables` method log.info("data stating... (this step may take long time)") @@ -327,17 +415,18 @@ def build (self, # config the init_frz_model command if self.run_opt.init_mode == 'init_from_frz_model': self._init_from_frz_model() - + + if self.run_opt.init_mode == 'finetune': + self._init_from_pretrained_model(data=data, origin_type_map=origin_type_map) + # neighbor_stat is moved to train.py as duplicated # TODO: this is a simple fix but we should have a clear # architecture to call neighbor stat else : graph, graph_def = load_graph_def(self.model_param['compress']['model_file']) - self.descrpt.enable_compression(self.model_param['compress']["min_nbor_dist"], self.model_param['compress']['model_file'], self.model_param['compress']['table_config'][0], self.model_param['compress']['table_config'][1], self.model_param['compress']['table_config'][2], self.model_param['compress']['table_config'][3]) - self.fitting.init_variables(graph, graph_def) + self.descrpt.enable_compression(self.model_param['compress']["min_nbor_dist"], graph, graph_def, self.model_param['compress']['table_config'][0], self.model_param['compress']['table_config'][1], self.model_param['compress']['table_config'][2], self.model_param['compress']['table_config'][3]) # for fparam or aparam settings in 'ener' type fitting net - if self.fitting_type == 'ener': - self.fitting.enable_compression(self.model_param['compress']['model_file']) + self.fitting.init_variables(graph, graph_def) if self.is_compress or self.model_type == 'compressed_model': tf.constant("compressed_model", name = 'model_type', dtype = tf.string) @@ -346,7 +435,11 @@ def build (self, if self.mixed_prec is not None: self.descrpt.enable_mixed_precision(self.mixed_prec) - self.fitting.enable_mixed_precision(self.mixed_prec) + if not self.multi_task_mode: + self.fitting.enable_mixed_precision(self.mixed_prec) + else: + for fitting_key in self.fitting_dict: + self.fitting_dict[fitting_key].enable_mixed_precision(self.mixed_prec) self._build_lr() self._build_network(data, suffix) @@ -366,7 +459,10 @@ def _build_network(self, data, suffix=""): self.place_holders[kk] = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], 't_' + kk) self._get_place_horders(data_requirement) else : - self._get_place_horders(data.get_data_dict()) + if not self.multi_task_mode: + self._get_place_horders(data.get_data_dict()) + else: + self._get_place_horders(data[list(data.keys())[0]].get_data_dict()) self.place_holders['type'] = tf.placeholder(tf.int32, [None], name='t_type') self.place_holders['natoms_vec'] = tf.placeholder(tf.int32, [self.ntypes+2], name='t_natoms') @@ -383,15 +479,29 @@ def _build_network(self, data, suffix=""): suffix = suffix, reuse = False) - self.l2_l, self.l2_more\ - = self.loss.build (self.learning_rate, - self.place_holders['natoms_vec'], - self.model_pred, - self.place_holders, - suffix = "test") + if not self.multi_task_mode: + self.l2_l, self.l2_more\ + = self.loss.build (self.learning_rate, + self.place_holders['natoms_vec'], + self.model_pred, + self.place_holders, + suffix = "test") + + if self.mixed_prec is not None: + self.l2_l = tf.cast(self.l2_l, get_precision(self.mixed_prec['output_prec'])) + else: + self.l2_l, self.l2_more = {}, {} + for fitting_key in self.fitting_type_dict: + self.l2_l[fitting_key], self.l2_more[fitting_key]\ + = self.loss_dict[fitting_key].build(self.learning_rate, + self.place_holders['natoms_vec'], + self.model_pred[fitting_key], + self.place_holders, + suffix=fitting_key) + if self.mixed_prec is not None: + self.l2_l[fitting_key] = tf.cast(self.l2_l[fitting_key], + get_precision(self.mixed_prec['output_prec'])) - if self.mixed_prec is not None: - self.l2_l = tf.cast(self.l2_l, get_precision(self.mixed_prec['output_prec'])) log.info("built network") def _build_training(self): @@ -414,12 +524,22 @@ def _build_training(self): optimizer = tf.train.experimental.enable_mixed_precision_graph_rewrite(optimizer) else: optimizer = tf.mixed_precision.enable_mixed_precision_graph_rewrite(optimizer) - apply_op = optimizer.minimize(loss=self.l2_l, - global_step=self.global_step, - var_list=trainable_variables, - name='train_step') - train_ops = [apply_op] + self._extra_train_ops - self.train_op = tf.group(*train_ops) + if not self.multi_task_mode: + apply_op = optimizer.minimize(loss=self.l2_l, + global_step=self.global_step, + var_list=trainable_variables, + name='train_step') + train_ops = [apply_op] + self._extra_train_ops + self.train_op = tf.group(*train_ops) + else: + self.train_op = {} + for fitting_key in self.fitting_type_dict: + apply_op = optimizer.minimize(loss=self.l2_l[fitting_key], + global_step=self.global_step, + var_list=trainable_variables, + name='train_step_{}'.format(fitting_key)) + train_ops = [apply_op] + self._extra_train_ops + self.train_op[fitting_key] = tf.group(*train_ops) log.info("built training") def _init_session(self): @@ -455,6 +575,11 @@ def _init_session(self): run_sess(self.sess, init_op) fp = open(self.disp_file, "w") fp.close () + elif self.run_opt.init_mode == 'finetune' : + log.info("initialize training from the frozen pretrained model") + run_sess(self.sess, init_op) + fp = open(self.disp_file, "w") + fp.close() else : raise RuntimeError ("unkown init mode") else: @@ -531,11 +656,29 @@ def train (self, train_data = None, valid_data=None) : while cur_batch < stop_batch : # first round validation: - train_batch = train_data.get_batch() + if not self.multi_task_mode: + train_batch = train_data.get_batch() + batch_train_op = self.train_op + else: + fitting_idx = dp_random.choice(np.arange(self.nfitting), p=np.array(self.fitting_prob)) + fitting_key = self.fitting_key_list[fitting_idx] + train_batch = train_data[fitting_key].get_batch() + batch_train_op = self.train_op[fitting_key] if self.display_in_training and is_first_step: if self.run_opt.is_chief: - valid_batches = [valid_data.get_batch() for ii in range(self.valid_numb_batch)] if valid_data is not None else None - self.valid_on_the_fly(fp, [train_batch], valid_batches, print_header=True) + if not self.multi_task_mode: + valid_batches = [valid_data.get_batch() for ii in range(self.valid_numb_batch)] if valid_data is not None else None + self.valid_on_the_fly(fp, [train_batch], valid_batches, print_header=True) + else: + train_batches = {} + valid_batches = {} + # valid_numb_batch_dict + for fitting_key in train_data: + train_batches[fitting_key] = [train_data[fitting_key].get_batch()] + valid_batches[fitting_key] = [valid_data[fitting_key].get_batch() + for ii in range(self.valid_numb_batch_dict[fitting_key])] \ + if fitting_key in valid_data else None + self.valid_on_the_fly(fp, train_batches, valid_batches, print_header=True) is_first_step = False if self.timing_in_training: tic = time.time() @@ -543,11 +686,11 @@ def train (self, train_data = None, valid_data=None) : # use tensorboard to visualize the training of deepmd-kit # it will takes some extra execution time to generate the tensorboard data if self.tensorboard and (cur_batch % self.tensorboard_freq == 0): - summary, _ = run_sess(self.sess, [summary_merged_op, self.train_op], feed_dict=train_feed_dict, + summary, _ = run_sess(self.sess, [summary_merged_op, batch_train_op], feed_dict=train_feed_dict, options=prf_options, run_metadata=prf_run_metadata) tb_train_writer.add_summary(summary, cur_batch) else: - run_sess(self.sess, [self.train_op], feed_dict=train_feed_dict, + run_sess(self.sess, [batch_train_op], feed_dict=train_feed_dict, options=prf_options, run_metadata=prf_run_metadata) if self.timing_in_training: toc = time.time() if self.timing_in_training: train_time += toc - tic @@ -559,8 +702,18 @@ def train (self, train_data = None, valid_data=None) : if self.timing_in_training: tic = time.time() if self.run_opt.is_chief: - valid_batches = [valid_data.get_batch() for ii in range(self.valid_numb_batch)] if valid_data is not None else None - self.valid_on_the_fly(fp, [train_batch], valid_batches) + if not self.multi_task_mode: + valid_batches = [valid_data.get_batch() for ii in range(self.valid_numb_batch)] if valid_data is not None else None + self.valid_on_the_fly(fp, [train_batch], valid_batches) + else: + train_batches = {} + valid_batches = {} + for fitting_key in train_data: + train_batches[fitting_key] = [train_data[fitting_key].get_batch()] + valid_batches[fitting_key] = [valid_data[fitting_key].get_batch() + for ii in range(self.valid_numb_batch_dict[fitting_key])] \ + if fitting_key in valid_data else None + self.valid_on_the_fly(fp, train_batches, valid_batches) if self.timing_in_training: toc = time.time() test_time = toc - tic @@ -646,60 +799,95 @@ def valid_on_the_fly(self, cur_batch = self.cur_batch current_lr = run_sess(self.sess, self.learning_rate) if print_header: - self.print_header(fp, train_results, valid_results) - self.print_on_training(fp, train_results, valid_results, cur_batch, current_lr) + self.print_header(fp, train_results, valid_results, self.multi_task_mode) + self.print_on_training(fp, train_results, valid_results, cur_batch, current_lr, self.multi_task_mode) @staticmethod - def print_header(fp, train_results, valid_results): + def print_header(fp, train_results, valid_results, multi_task_mode=False): print_str = '' print_str += "# %5s" % 'step' - if valid_results is not None: - prop_fmt = ' %11s %11s' - for k in train_results.keys(): - print_str += prop_fmt % (k + '_val', k + '_trn') + if not multi_task_mode: + if valid_results is not None: + prop_fmt = ' %11s %11s' + for k in train_results.keys(): + print_str += prop_fmt % (k + '_val', k + '_trn') + else: + prop_fmt = ' %11s' + for k in train_results.keys(): + print_str += prop_fmt % (k + '_trn') else: - prop_fmt = ' %11s' - for k in train_results.keys(): - print_str += prop_fmt % (k + '_trn') + for fitting_key in train_results: + if valid_results[fitting_key] is not None: + prop_fmt = ' %11s %11s' + for k in train_results[fitting_key].keys(): + print_str += prop_fmt % (k + '_val', k + '_trn') + else: + prop_fmt = ' %11s' + for k in train_results[fitting_key].keys(): + print_str += prop_fmt % (k + '_trn') print_str += ' %8s\n' % 'lr' fp.write(print_str) fp.flush() @staticmethod - def print_on_training(fp, train_results, valid_results, cur_batch, cur_lr): + def print_on_training(fp, train_results, valid_results, cur_batch, cur_lr, multi_task_mode=False): print_str = '' print_str += "%7d" % cur_batch - if valid_results is not None: - prop_fmt = " %11.2e %11.2e" - for k in valid_results.keys(): - # assert k in train_results.keys() - print_str += prop_fmt % (valid_results[k], train_results[k]) + if not multi_task_mode: + if valid_results is not None: + prop_fmt = " %11.2e %11.2e" + for k in valid_results.keys(): + # assert k in train_results.keys() + print_str += prop_fmt % (valid_results[k], train_results[k]) + else: + prop_fmt = " %11.2e" + for k in train_results.keys(): + print_str += prop_fmt % (train_results[k]) else: - prop_fmt = " %11.2e" - for k in train_results.keys(): - print_str += prop_fmt % (train_results[k]) + for fitting_key in train_results: + if valid_results[fitting_key] is not None: + prop_fmt = " %11.2e %11.2e" + for k in valid_results[fitting_key].keys(): + # assert k in train_results[fitting_key].keys() + print_str += prop_fmt % (valid_results[fitting_key][k], train_results[fitting_key][k]) + else: + prop_fmt = " %11.2e" + for k in train_results[fitting_key].keys(): + print_str += prop_fmt % (train_results[fitting_key][k]) print_str += " %8.1e\n" % cur_lr fp.write(print_str) fp.flush() - def get_evaluation_results(self, batch_list): - if batch_list is None: return None - numb_batch = len(batch_list) - - sum_results = {} # sum of losses on all atoms + @staticmethod + def eval_single_list(single_batch_list, loss, sess, get_feed_dict_func, prefix=''): + if single_batch_list is None: + return None + numb_batch = len(single_batch_list) + sum_results = {} # sum of losses on all atoms sum_natoms = 0 for i in range(numb_batch): - batch = batch_list[i] + batch = single_batch_list[i] natoms = batch["natoms_vec"] - feed_dict = self.get_feed_dict(batch, is_training=False) - results = self.loss.eval(self.sess, feed_dict, natoms) + feed_dict = get_feed_dict_func(batch, is_training=False) + results = loss.eval(sess, feed_dict, natoms) for k, v in results.items(): if k == "natoms": sum_natoms += v else: sum_results[k] = sum_results.get(k, 0.) + v * results["natoms"] - avg_results = {k: v / sum_natoms for k, v in sum_results.items() if not k == "natoms"} + single_results = {prefix + k: v / sum_natoms for k, v in sum_results.items() if not k == "natoms"} + return single_results + + def get_evaluation_results(self, batch_list): + if not self.multi_task_mode: + avg_results = self.eval_single_list(batch_list, self.loss, self.sess, self.get_feed_dict) + else: + avg_results = {} + for fitting_key in batch_list: + avg_results[fitting_key] = \ + self.eval_single_list(batch_list[fitting_key], self.loss_dict[fitting_key], self.sess, + self.get_feed_dict, prefix='{}_'.format(fitting_key)) return avg_results def save_compressed(self): @@ -742,3 +930,51 @@ def _init_from_frz_model(self): if self.model_type == 'compressed_model': self.frz_model = self.run_opt.init_frz_model self.model.init_variables(graph, graph_def, model_type=self.model_type) + + def _init_from_pretrained_model(self, data, origin_type_map=None, bias_shift='delta'): + """ + Init the embedding net variables with the given frozen model + + Parameters + ---------- + data : DeepmdDataSystem + The training data. + origin_type_map : list + The original type_map in dataset, they are targets to change the energy bias. + bias_shift : str + The mode for changing energy bias : ['delta', 'statistic'] + 'delta' : perform predictions on energies of target dataset, + and do least sqaure on the errors to obtain the target shift as bias. + 'statistic' : directly use the statistic energy bias in the target dataset. + """ + try: + graph, graph_def = load_graph_def(self.run_opt.finetune) + except FileNotFoundError as e: + # throw runtime error if there's no frozen model + raise RuntimeError( + "The input frozen pretrained model %s (%s) does not exist! " + "Please check the path of the frozen pretrained model. " % (self.run_opt.finetune, + os.path.abspath(self.run_opt.finetune)) + ) from e + # get the model type from the frozen model(self.run_opt.finetune) + try: + t_model_type = get_tensor_by_name_from_graph(graph, 'model_type') + except GraphWithoutTensorError as e: + # throw runtime error if the frozen_model has no model type information... + raise RuntimeError( + "The input frozen pretrained model: %s has no 'model_type' information, " + "which is not supported by the 'dp train finetune' interface. " % self.run_opt.finetune + ) from e + else: + self.model_type = bytes.decode(t_model_type) + assert self.model_type != 'compressed_model', "Compressed models are not supported for finetuning!" + self.model.init_variables(graph, graph_def, model_type=self.model_type) + log.info("Changing energy bias in pretrained model for types {}... " + "(this step may take long time)".format(str(origin_type_map))) + self._change_energy_bias(data, self.run_opt.finetune, origin_type_map, bias_shift) + + def _change_energy_bias(self, data, frozen_model, origin_type_map, bias_shift='delta'): + full_type_map = data.get_type_map() + assert self.fitting_type == 'ener', "energy bias changing only supports 'ener' fitting net!" + self.model.fitting.change_energy_bias(data, frozen_model, origin_type_map, full_type_map, bias_shift=bias_shift, + ntest=self.model_param.get('data_bias_nsample', 10)) diff --git a/deepmd/utils/__init__.py b/deepmd/utils/__init__.py index e81b474095..c49afa752f 100644 --- a/deepmd/utils/__init__.py +++ b/deepmd/utils/__init__.py @@ -1,10 +1,6 @@ # from .data import DeepmdData from .data_system import DeepmdDataSystem - -# out-of-dated -from .data import DataSets -from .data_system import DataSystem from .pair_tab import PairTab from .learning_rate import LearningRateExp from .plugin import Plugin, PluginVariant diff --git a/deepmd/utils/argcheck.py b/deepmd/utils/argcheck.py index ce7710d116..83cf5d8c00 100644 --- a/deepmd/utils/argcheck.py +++ b/deepmd/utils/argcheck.py @@ -1,3 +1,4 @@ +import logging from typing import List, Callable from dargs import dargs, Argument, Variant, ArgumentEncoder @@ -8,6 +9,7 @@ from deepmd.nvnmd.utils.argcheck import nvnmd_args +log = logging.getLogger(__name__) def list_to_doc(xx): items = [] for ii in xx: @@ -107,9 +109,9 @@ def descrpt_local_frame_args (): - axis_rule[i*6+0]: class of the atom defining the first axis of type-i atom. 0 for neighbors with full coordinates and 1 for neighbors only with relative distance.\n\n\ - axis_rule[i*6+1]: type of the atom defining the first axis of type-i atom.\n\n\ - axis_rule[i*6+2]: index of the axis atom defining the first axis. Note that the neighbors with the same class and type are sorted according to their relative distance.\n\n\ -- axis_rule[i*6+3]: class of the atom defining the first axis of type-i atom. 0 for neighbors with full coordinates and 1 for neighbors only with relative distance.\n\n\ +- axis_rule[i*6+3]: class of the atom defining the second axis of type-i atom. 0 for neighbors with full coordinates and 1 for neighbors only with relative distance.\n\n\ - axis_rule[i*6+4]: type of the atom defining the second axis of type-i atom.\n\n\ -- axis_rule[i*6+5]: class of the atom defining the second axis of type-i atom. 0 for neighbors with full coordinates and 1 for neighbors only with relative distance.' +- axis_rule[i*6+5]: index of the axis atom defining the second axis. Note that the neighbors with the same class and type are sorted according to their relative distance.' return [ Argument("sel_a", list, optional = False, doc = doc_sel_a), @@ -450,9 +452,11 @@ def model_args (): doc_type_map = 'A list of strings. Give the name to each type of atoms. It is noted that the number of atom type of training system must be less than 128 in a GPU environment.' doc_data_stat_nbatch = 'The model determines the normalization from the statistics of the data. This key specifies the number of `frames` in each `system` used for statistics.' doc_data_stat_protect = 'Protect parameter for atomic energy regression.' + doc_data_bias_nsample = 'The number of training samples in a system to compute and change the energy bias.' doc_type_embedding = "The type embedding." doc_descrpt = 'The descriptor of atomic environment.' doc_fitting = 'The fitting of physical properties.' + doc_fitting_net_dict = 'The dictionary of multiple fitting nets in multi-task mode. Each fitting_net_dict[fitting_key] is the single definition of fitting of physical properties with user-defined name `fitting_key`.' doc_modifier = 'The modifier of model output.' doc_use_srtab = 'The table for the short-range pairwise interaction added on top of DP. The table is a text data file with (N_t + 1) * N_t / 2 + 1 columes. The first colume is the distance between atoms. The second to the last columes are energies for pairs of certain types. For example we have two atom types, 0 and 1. The columes from 2nd to 4th are for 0-0, 0-1 and 1-1 correspondingly.' doc_smin_alpha = 'The short-range tabulated interaction will be swithed according to the distance of the nearest neighbor. This distance is calculated by softmin. This parameter is the decaying parameter in the softmin. It is only required when `use_srtab` is provided.' @@ -464,13 +468,15 @@ def model_args (): [Argument("type_map", list, optional = True, doc = doc_type_map), Argument("data_stat_nbatch", int, optional = True, default = 10, doc = doc_data_stat_nbatch), Argument("data_stat_protect", float, optional = True, default = 1e-2, doc = doc_data_stat_protect), + Argument("data_bias_nsample", int, optional=True, default=10, doc=doc_data_bias_nsample), Argument("use_srtab", str, optional = True, doc = doc_use_srtab), Argument("smin_alpha", float, optional = True, doc = doc_smin_alpha), Argument("sw_rmin", float, optional = True, doc = doc_sw_rmin), Argument("sw_rmax", float, optional = True, doc = doc_sw_rmax), Argument("type_embedding", dict, type_embedding_args(), [], optional = True, doc = doc_type_embedding), Argument("descriptor", dict, [], [descrpt_variant_type_args()], doc = doc_descrpt), - Argument("fitting_net", dict, [], [fitting_variant_type_args()], doc = doc_fitting), + Argument("fitting_net", dict, [], [fitting_variant_type_args()], optional=True, doc=doc_fitting), + Argument("fitting_net_dict", dict, optional=True, doc=doc_fitting_net_dict), Argument("modifier", dict, [], [modifier_variant_type_args()], optional = True, doc = doc_modifier), Argument("compress", dict, [], [model_compression_type_args()], optional = True, doc = doc_compress_config) ]) @@ -532,7 +538,7 @@ def loss_ener(): doc_start_pref_pf = start_pref('atom_pref') doc_limit_pref_pf = limit_pref('atom_pref') doc_relative_f = 'If provided, relative force error will be used in the loss. The difference of force will be normalized by the magnitude of the force in the label with a shift given by `relative_f`, i.e. DF_i / ( || F || + relative_f ) with DF denoting the difference between prediction and label and || F || denoting the L2 norm of the label.' - doc_enable_atom_ener_coeff = "If true, the energy will be computed as \sum_i c_i E_i. c_i should be provided by file atom_ener_coeff.npy in each data system, otherwise it's 1." + doc_enable_atom_ener_coeff = "If true, the energy will be computed as \\sum_i c_i E_i. c_i should be provided by file atom_ener_coeff.npy in each data system, otherwise it's 1." return [ Argument("start_pref_e", [float,int], optional = True, default = 0.02, doc = doc_start_pref_e), Argument("limit_pref_e", [float,int], optional = True, default = 1.00, doc = doc_limit_pref_e), @@ -561,7 +567,7 @@ def loss_tensor(): def loss_variant_type_args(): - doc_loss = 'The type of the loss. When the fitting type is `ener`, the loss type should be set to `ener` or left unset. When the fitting type is `dipole` or `polar`, the loss type should be set to `tensor`. \n\.' + doc_loss = 'The type of the loss. When the fitting type is `ener`, the loss type should be set to `ener` or left unset. When the fitting type is `dipole` or `polar`, the loss type should be set to `tensor`.' return Variant("type", @@ -576,7 +582,7 @@ def loss_variant_type_args(): def loss_args(): - doc_loss = 'The definition of loss function. The loss type should be set to `tensor`, `ener` or left unset.\n\.' + doc_loss = 'The definition of loss function. The loss type should be set to `tensor`, `ener` or left unset.' ca = Argument('loss', dict, [], [loss_variant_type_args()], optional = True, @@ -584,6 +590,15 @@ def loss_args(): return ca +def loss_dict_args(): + doc_loss_dict = 'The dictionary of definitions of multiple loss functions in multi-task mode. ' \ + 'Each loss_dict[fitting_key], with user-defined name `fitting_key` in `model/fitting_net_dict`, is the single definition of loss function, whose type should be set to `tensor`, `ener` or left unset.\n' + ca = Argument('loss_dict', dict, [], [], + optional = True, + doc = doc_loss_dict) + return ca + + # --- Training configurations: --- # def training_data_args(): # ! added by Ziyao: new specification style for data systems. link_sys = make_link("systems", "training/training_data/systems") @@ -615,7 +630,7 @@ def training_data_args(): # ! added by Ziyao: new specification style for data ] doc_training_data = "Configurations of training data." - return Argument("training_data", dict, optional=False, + return Argument("training_data", dict, optional=True, sub_fields=args, sub_variants=[], doc=doc_training_data) @@ -661,7 +676,7 @@ def mixed_precision_args(): # ! added by Denghui. "supported options are float32 only currently.' doc_compute_prec = 'The precision for mixed precision compute. " \ "The compute precision during the mixed precision training process, "" \ - "supported options are float16 only currently.' + "supported options are float16 and bfloat16 currently.' args = [ Argument("output_prec", str, optional=True, default="float32", doc=doc_output_prec), @@ -688,6 +703,14 @@ def training_args(): # ! modified by Ziyao: data configuration isolated. doc_tensorboard = 'Enable tensorboard' doc_tensorboard_log_dir = 'The log directory of tensorboard outputs' doc_tensorboard_freq = 'The frequency of writing tensorboard events.' + doc_data_dict = 'The dictionary of multi DataSystems in multi-task mode. ' \ + 'Each data_dict[fitting_key], with user-defined name `fitting_key` in `model/fitting_net_dict`, ' \ + 'contains training data and optional validation data definitions.' + doc_fitting_weight = 'Each fitting_weight[fitting_key], with user-defined name `fitting_key` in `model/fitting_net_dict`, ' \ + 'is the training weight of fitting net `fitting_key`. ' \ + 'Fitting nets with higher weights will be selected with higher probabilities to be trained in one step. ' \ + 'Weights will be normalized and minus ones will be ignored. ' \ + 'If not set, each fitting net will be equally selected when training.' arg_training_data = training_data_args() arg_validation_data = validation_data_args() @@ -711,6 +734,8 @@ def training_args(): # ! modified by Ziyao: data configuration isolated. Argument("tensorboard", bool, optional=True, default=False, doc=doc_tensorboard), Argument("tensorboard_log_dir", str, optional=True, default='log', doc=doc_tensorboard_log_dir), Argument("tensorboard_freq", int, optional=True, default=1, doc=doc_tensorboard_freq), + Argument("data_dict", dict, optional=True, doc=doc_data_dict), + Argument("fitting_weight", dict, optional=True, doc=doc_fitting_weight), ] doc_training = 'The training options.' @@ -730,11 +755,13 @@ def gen_doc(*, make_anchor=True, make_link=True, **kwargs): ma = model_args() lra = learning_rate_args() la = loss_args() + lda = loss_dict_args() ta = training_args() nvnmda = nvnmd_args() ptr = [] ptr.append(ma.gen_doc(make_anchor=make_anchor, make_link=make_link, **kwargs)) ptr.append(la.gen_doc(make_anchor=make_anchor, make_link=make_link, **kwargs)) + ptr.append(lda.gen_doc(make_anchor=make_anchor, make_link=make_link, **kwargs)) ptr.append(lra.gen_doc(make_anchor=make_anchor, make_link=make_link, **kwargs)) ptr.append(ta.gen_doc(make_anchor=make_anchor, make_link=make_link, **kwargs)) ptr.append(nvnmda.gen_doc(make_anchor=make_anchor, make_link=make_link, **kwargs)) @@ -752,10 +779,19 @@ def gen_json(**kwargs): model_args(), learning_rate_args(), loss_args(), + loss_dict_args(), training_args(), nvnmd_args(), ), cls=ArgumentEncoder) +def gen_args(**kwargs): + return [model_args(), + learning_rate_args(), + loss_args(), + loss_dict_args(), + training_args(), + nvnmd_args()] + def normalize_hybrid_list(hy_list): new_list = [] base = Argument("base", dict, [], [descrpt_variant_type_args()], doc = "") @@ -765,19 +801,143 @@ def normalize_hybrid_list(hy_list): new_list.append(data) return new_list +def normalize_multi_task(data): + # single-task or multi-task mode + single_fitting_net = "fitting_net" in data["model"].keys() + single_training_data = "training_data" in data["training"].keys() + single_valid_data = "validation_data" in data["training"].keys() + single_loss = "loss" in data.keys() + multi_fitting_net = "fitting_net_dict" in data["model"].keys() + multi_training_data = "data_dict" in data["training"].keys() + multi_loss = "loss_dict" in data.keys() + multi_fitting_weight = "fitting_weight" in data["training"].keys() + assert (single_fitting_net == single_training_data) and \ + (multi_fitting_net == multi_training_data), \ + "In single-task mode, 'model/fitting_net' and 'training/training_data' must be defined at the same time! " \ + "While in multi-task mode, 'model/fitting_net_dict', 'training/data_dict' " \ + "must be defined at the same time! Please check your input script. " + assert not (single_fitting_net and multi_fitting_net), \ + "Single-task mode and multi-task mode can not be performed together. " \ + "Please check your input script and choose just one format! " + assert single_fitting_net or multi_fitting_net, "Please define your fitting net and training data! " + if multi_fitting_net: + assert not single_valid_data, "In multi-task mode, 'training/validation_data' should not appear " \ + "outside 'training/data_dict'! Please check your input script." + assert not single_loss, "In multi-task mode, please use 'model/loss_dict' in stead of 'model/loss'! " + assert "type_map" in data["model"], "In multi-task mode, 'model/type_map' must be defined! " + data["model"]["fitting_net_dict"] = normalize_fitting_net_dict(data["model"]["fitting_net_dict"]) + data["training"]["data_dict"] = normalize_data_dict(data["training"]["data_dict"]) + data["loss_dict"] = normalize_loss_dict(data["model"]["fitting_net_dict"].keys(), + data["loss_dict"]) if multi_loss else {} + fitting_weight = data["training"]["fitting_weight"] if multi_fitting_weight else None + data["training"]["fitting_weight"] = \ + normalize_fitting_weight(data["model"]["fitting_net_dict"].keys(), + data["training"]["data_dict"].keys(), + fitting_weight=fitting_weight) + else: + assert not multi_loss, "In single-task mode, please use 'model/loss' in stead of 'model/loss_dict'! " + return data + + +def normalize_fitting_net_dict(fitting_net_dict): + new_dict = {} + base = Argument("base", dict, [], [fitting_variant_type_args()], doc="") + for fitting_key_item in fitting_net_dict: + data = base.normalize_value(fitting_net_dict[fitting_key_item], trim_pattern="_*") + base.check_value(data, strict=True) + new_dict[fitting_key_item] = data + return new_dict + + +def normalize_data_dict(data_dict): + new_dict = {} + base = Argument("base", dict, [training_data_args(), validation_data_args()], [], doc="") + for data_system_key_item in data_dict: + data = base.normalize_value(data_dict[data_system_key_item], trim_pattern="_*") + base.check_value(data, strict=True) + new_dict[data_system_key_item] = data + return new_dict + + +def normalize_loss_dict(fitting_keys, loss_dict): + # check the loss dict + failed_loss_keys = [item for item in loss_dict if item not in fitting_keys] + assert not failed_loss_keys, \ + "Loss dict key(s) {} not have corresponding fitting keys in {}! ".format( + str(failed_loss_keys), str(list(fitting_keys))) + new_dict = {} + base = Argument('base', dict, [], [loss_variant_type_args()], doc="") + for item in loss_dict: + data = base.normalize_value(loss_dict[item], trim_pattern="_*") + base.check_value(data, strict=True) + new_dict[item] = data + return new_dict + + +def normalize_fitting_weight(fitting_keys, data_keys, fitting_weight=None): + # check the mapping + failed_data_keys = [item for item in data_keys if item not in fitting_keys] + assert not failed_data_keys, \ + "Data dict key(s) {} not have corresponding fitting keys in {}! ".format( + str(failed_data_keys), str(list(fitting_keys))) + empty_fitting_keys = [] + valid_fitting_keys = [] + for item in fitting_keys: + if item not in data_keys: + empty_fitting_keys.append(item) + else: + valid_fitting_keys.append(item) + if empty_fitting_keys: + log.warning("Fitting net(s) {} have no data and will not be used in training.".format(str(empty_fitting_keys))) + num_pair = len(valid_fitting_keys) + assert num_pair > 0, "No valid training data systems for fitting nets!" + + # check and normalize the fitting weight + new_weight = {} + if fitting_weight is None: + equal_weight = 1. / num_pair + for item in fitting_keys: + new_weight[item] = equal_weight if item in valid_fitting_keys else 0. + else: + failed_weight_keys = [item for item in fitting_weight if item not in fitting_keys] + assert not failed_weight_keys, \ + "Fitting weight key(s) {} not have corresponding fitting keys in {}! ".format( + str(failed_weight_keys), str(list(fitting_keys))) + sum_prob = 0. + for item in fitting_keys: + if item in valid_fitting_keys: + if item in fitting_weight \ + and isinstance(fitting_weight[item], (int, float)) and fitting_weight[item] > 0.: + sum_prob += fitting_weight[item] + new_weight[item] = fitting_weight[item] + else: + valid_fitting_keys.pop(item) + log.warning("Fitting net '{}' has zero or invalid weight " + "and will not be used in training.".format(item)) + new_weight[item] = 0. + else: + new_weight[item] = 0. + assert sum_prob > 0., "No valid training weight for fitting nets!" + # normalize + for item in new_weight: + new_weight[item] /= sum_prob + return new_weight + def normalize(data): if "hybrid" == data["model"]["descriptor"]["type"]: data["model"]["descriptor"]["list"] \ = normalize_hybrid_list(data["model"]["descriptor"]["list"]) + data = normalize_multi_task(data) ma = model_args() lra = learning_rate_args() la = loss_args() + lda = loss_dict_args() ta = training_args() nvnmda = nvnmd_args() - base = Argument("base", dict, [ma, lra, la, ta, nvnmda]) + base = Argument("base", dict, [ma, lra, la, lda, ta, nvnmda]) data = base.normalize_value(data, trim_pattern="_*") base.check_value(data, strict=True) diff --git a/deepmd/utils/batch_size.py b/deepmd/utils/batch_size.py index 27b6a830a4..d89784e9cf 100644 --- a/deepmd/utils/batch_size.py +++ b/deepmd/utils/batch_size.py @@ -1,22 +1,33 @@ +import os import logging from typing import Callable, Tuple import numpy as np +from deepmd.env import tf from deepmd.utils.errors import OutOfMemoryError + +log = logging.getLogger(__name__) + + class AutoBatchSize: """This class allows DeePMD-kit to automatically decide the maximum batch size that will not cause an OOM error. Notes ----- - We assume all OOM error will raise :class:`OutOfMemoryError`. + In some CPU environments, the program may be directly killed when OOM. In + this case, by default the batch size will not be increased for CPUs. The + environment variable `DP_INFER_BATCH_SIZE` can be set as the batch size. + + In other cases, we assume all OOM error will raise :class:`OutOfMemoryError`. Parameters ---------- initial_batch_size : int, default: 1024 - initial batch size (number of total atoms) + initial batch size (number of total atoms) when DP_INFER_BATCH_SIZE + is not set factor : float, default: 2. increased factor @@ -33,8 +44,23 @@ def __init__(self, initial_batch_size: int = 1024, factor: float = 2.) -> None: # See also PyTorchLightning/pytorch-lightning#1638 # TODO: discuss a proper initial batch size self.current_batch_size = initial_batch_size - self.maximum_working_batch_size = 0 - self.minimal_not_working_batch_size = 2**31 + DP_INFER_BATCH_SIZE = int(os.environ.get('DP_INFER_BATCH_SIZE', 0)) + if DP_INFER_BATCH_SIZE > 0: + self.current_batch_size = DP_INFER_BATCH_SIZE + self.maximum_working_batch_size = DP_INFER_BATCH_SIZE + self.minimal_not_working_batch_size = self.maximum_working_batch_size + 1 + else: + self.maximum_working_batch_size = initial_batch_size + if tf.test.is_gpu_available(): + self.minimal_not_working_batch_size = 2**31 + else: + self.minimal_not_working_batch_size = self.maximum_working_batch_size + 1 + log.warning( + "You can use the environment variable DP_INFER_BATCH_SIZE to" + "control the inference batch size (nframes * natoms). " + "The default value is %d." % initial_batch_size + ) + self.factor = factor def execute(self, callable: Callable, start_index: int, natoms: int) -> Tuple[int, tuple]: @@ -86,7 +112,7 @@ def execute(self, callable: Callable, start_index: int, natoms: int) -> Tuple[in def _adjust_batch_size(self, factor: float): old_batch_size = self.current_batch_size self.current_batch_size = int(self.current_batch_size * factor) - logging.info("Adjust batch size from %d to %d" % (old_batch_size, self.current_batch_size)) + log.info("Adjust batch size from %d to %d" % (old_batch_size, self.current_batch_size)) def execute_all(self, callable: Callable, total_size: int, natoms: int, *args, **kwargs) -> Tuple[np.ndarray]: """Excuate a method with all given data. diff --git a/deepmd/utils/convert.py b/deepmd/utils/convert.py index 6fbc9a36ac..70f9c24d0e 100644 --- a/deepmd/utils/convert.py +++ b/deepmd/utils/convert.py @@ -4,25 +4,6 @@ from google.protobuf import text_format -def convert_13_to_21(input_model: str, output_model: str): - """Convert DP 1.3 graph to 2.1 graph. - - Parameters - ---------- - input_model : str - filename of the input graph - output_model : str - filename of the output graph - """ - convert_pb_to_pbtxt(input_model, 'frozen_model.pbtxt') - convert_dp13_to_dp20('frozen_model.pbtxt') - convert_dp20_to_dp21('frozen_model.pbtxt') - convert_pbtxt_to_pb('frozen_model.pbtxt', output_model) - if os.path.isfile('frozen_model.pbtxt'): - os.remove('frozen_model.pbtxt') - print("the converted output model (2.1 support) is saved in %s" % output_model) - - def convert_13_to_21(input_model: str, output_model: str): """Convert DP 1.3 graph to 2.1 graph. @@ -157,7 +138,7 @@ def convert_pbtxt_to_pb(pbtxtfile: str, pbfile: str): def convert_dp012_to_dp10(file: str): - """Convert DP 1.0 graph text to 1.1 graph text. + """Convert DP 0.12 graph text to 1.0 graph text. Parameters ---------- @@ -225,6 +206,29 @@ def convert_dp012_to_dp10(file: str): } } """) + file_content += textwrap.dedent("""\ + node { + name: "model_attr/tmap" + op: "Const" + attr { + key: "dtype" + value { + type: DT_STRING + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_STRING + tensor_shape { + } + string_val: "" + } + } + } + } + """) with open(file, 'w') as fp: fp.write(file_content) diff --git a/deepmd/utils/data.py b/deepmd/utils/data.py index e3dea5b04e..9202872f76 100644 --- a/deepmd/utils/data.py +++ b/deepmd/utils/data.py @@ -30,6 +30,8 @@ class DeepmdData() : If the test data are shuffled type_map Gives the name of different atom types + optional_type_map + If the type_map.raw in each system is optional modifier Data modifier that has the method `modify_data` trn_all_set @@ -39,7 +41,8 @@ def __init__ (self, sys_path : str, set_prefix : str = 'set', shuffle_test : bool = True, - type_map : List[str] = None, + type_map : List[str] = None, + optional_type_map : bool = True, modifier = None, trn_all_set : bool = False) : """ @@ -57,6 +60,8 @@ def __init__ (self, self.atom_type_mix = self._load_type_mix(self.dirs[0]) # load atom type map self.type_map = self._load_type_map(root) + assert optional_type_map or self.type_map is not None, \ + 'System {} must have type_map.raw in this mode! '.format(sys_path) if self.type_map is not None: assert(len(self.type_map) >= max(self.atom_type)+1) # check pbc @@ -560,268 +565,3 @@ def _check_pbc(self, sys_path: DPPath): def _check_mode(self, set_path: DPPath): return (set_path / 'real_atom_types.npy').is_file() - - -class DataSets (object): - """ - Outdated class for one data system. - - .. deprecated:: 2.0.0 - This class is not maintained any more. - """ - def __init__ (self, - sys_path, - set_prefix, - seed = None, - shuffle_test = True) : - self.dirs = glob.glob (os.path.join(sys_path, set_prefix + ".*")) - self.dirs.sort() - # load atom type - self.atom_type, self.idx_map, self.idx3_map = self.load_type (sys_path) - # load atom type map - self.type_map = self.load_type_map(sys_path) - if self.type_map is not None: - assert(len(self.type_map) >= max(self.atom_type)+1) - # train dirs - self.test_dir = self.dirs[-1] - if len(self.dirs) == 1 : - self.train_dirs = self.dirs - else : - self.train_dirs = self.dirs[:-1] - # check fparam - has_fparam = [ os.path.isfile(os.path.join(ii, 'fparam.npy')) for ii in self.dirs ] - if any(has_fparam) and (not all(has_fparam)) : - raise RuntimeError("system %s: if any set has frame parameter, then all sets should have frame parameter" % sys_path) - if all(has_fparam) : - self.has_fparam = 0 - else : - self.has_fparam = -1 - # check aparam - has_aparam = [ os.path.isfile(os.path.join(ii, 'aparam.npy')) for ii in self.dirs ] - if any(has_aparam) and (not all(has_aparam)) : - raise RuntimeError("system %s: if any set has frame parameter, then all sets should have frame parameter" % sys_path) - if all(has_aparam) : - self.has_aparam = 0 - else : - self.has_aparam = -1 - # energy norm - self.eavg = self.stats_energy() - # load sets - self.set_count = 0 - self.load_batch_set (self.train_dirs[self.set_count % self.get_numb_set()]) - self.load_test_set (self.test_dir, shuffle_test) - - def check_batch_size (self, batch_size) : - for ii in self.train_dirs : - tmpe = np.load(os.path.join(ii, "coord.npy")) - if tmpe.shape[0] < batch_size : - return ii, tmpe.shape[0] - return None - - def check_test_size (self, test_size) : - tmpe = np.load(os.path.join(self.test_dir, "coord.npy")) - if tmpe.shape[0] < test_size : - return self.test_dir, tmpe.shape[0] - else : - return None - - def load_type (self, sys_path) : - atom_type = np.loadtxt (os.path.join(sys_path, "type.raw"), dtype=np.int32, ndmin=1) - natoms = atom_type.shape[0] - idx = np.arange (natoms) - idx_map = np.lexsort ((idx, atom_type)) - atom_type3 = np.repeat(atom_type, 3) - idx3 = np.arange (natoms * 3) - idx3_map = np.lexsort ((idx3, atom_type3)) - return atom_type, idx_map, idx3_map - - def load_type_map(self, sys_path) : - fname = os.path.join(sys_path, 'type_map.raw') - if os.path.isfile(fname) : - with open(os.path.join(sys_path, 'type_map.raw')) as fp: - return fp.read().split() - else : - return None - - def get_type_map(self) : - return self.type_map - - def get_numb_set (self) : - return len (self.train_dirs) - - def stats_energy (self) : - eners = np.array([]) - for ii in self.train_dirs: - ener_file = os.path.join(ii, "energy.npy") - if os.path.isfile(ener_file) : - ei = np.load(ener_file) - eners = np.append(eners, ei) - if eners.size == 0 : - return 0 - else : - return np.average(eners) - - def load_energy(self, - set_name, - nframes, - nvalues, - energy_file, - atom_energy_file) : - """ - return : coeff_ener, ener, coeff_atom_ener, atom_ener - """ - # load atom_energy - coeff_atom_ener, atom_ener = self.load_data(set_name, atom_energy_file, [nframes, nvalues], False) - # ignore energy_file - if coeff_atom_ener == 1: - ener = np.sum(atom_ener, axis = 1) - coeff_ener = 1 - # load energy_file - else: - coeff_ener, ener = self.load_data(set_name, energy_file, [nframes], False) - return coeff_ener, ener, coeff_atom_ener, atom_ener - - def load_data(self, set_name, data_name, shape, is_necessary = True): - path = os.path.join(set_name, data_name+".npy") - if os.path.isfile (path) : - data = np.load(path) - data = np.reshape(data, shape) - if is_necessary: - return data - return 1, data - elif is_necessary: - raise OSError("%s not found!" % path) - else: - data = np.zeros(shape) - return 0, data - - def load_set(self, set_name, shuffle = True): - data = {} - data["box"] = self.load_data(set_name, "box", [-1, 9]) - nframe = data["box"].shape[0] - data["coord"] = self.load_data(set_name, "coord", [nframe, -1]) - ncoord = data["coord"].shape[1] - if self.has_fparam >= 0: - data["fparam"] = self.load_data(set_name, "fparam", [nframe, -1]) - if self.has_fparam == 0 : - self.has_fparam = data["fparam"].shape[1] - else : - assert self.has_fparam == data["fparam"].shape[1] - if self.has_aparam >= 0: - data["aparam"] = self.load_data(set_name, "aparam", [nframe, -1]) - if self.has_aparam == 0 : - self.has_aparam = data["aparam"].shape[1] // (ncoord//3) - else : - assert self.has_aparam == data["aparam"].shape[1] // (ncoord//3) - data["prop_c"] = np.zeros(5) - data["prop_c"][0], data["energy"], data["prop_c"][3], data["atom_ener"] \ - = self.load_energy (set_name, nframe, ncoord // 3, "energy", "atom_ener") - data["prop_c"][1], data["force"] = self.load_data(set_name, "force", [nframe, ncoord], False) - data["prop_c"][2], data["virial"] = self.load_data(set_name, "virial", [nframe, 9], False) - data["prop_c"][4], data["atom_pref"] = self.load_data(set_name, "atom_pref", [nframe, ncoord//3], False) - data["atom_pref"] = np.repeat(data["atom_pref"], 3, axis=1) - # shuffle data - if shuffle: - idx = np.arange (nframe) - dp_random.shuffle(idx) - for ii in data: - if ii != "prop_c": - data[ii] = data[ii][idx] - data["type"] = np.tile (self.atom_type, (nframe, 1)) - # sort according to type - for ii in ["type", "atom_ener"]: - data[ii] = data[ii][:, self.idx_map] - for ii in ["coord", "force", "atom_pref"]: - data[ii] = data[ii][:, self.idx3_map] - return data - - def load_batch_set (self, - set_name) : - self.batch_set = self.load_set(set_name, True) - self.reset_iter () - - def load_test_set (self, - set_name, - shuffle_test) : - self.test_set = self.load_set(set_name, shuffle_test) - - def reset_iter (self) : - self.iterator = 0 - self.set_count += 1 - - def get_set(self, data, idx = None) : - new_data = {} - for ii in data: - dd = data[ii] - if ii == "prop_c": - new_data[ii] = dd.astype(np.float32) - else: - if idx is not None: - dd = dd[idx] - if ii == "type": - new_data[ii] = dd - else: - new_data[ii] = dd.astype(GLOBAL_NP_FLOAT_PRECISION) - return new_data - - def get_test (self) : - """ - returned property prefector [4] in order: - energy, force, virial, atom_ener - """ - return self.get_set(self.test_set) - - def get_batch (self, - batch_size) : - """ - returned property prefector [4] in order: - energy, force, virial, atom_ener - """ - set_size = self.batch_set["energy"].shape[0] - # assert (batch_size <= set_size), "batch size should be no more than set size" - if self.iterator + batch_size > set_size : - self.load_batch_set (self.train_dirs[self.set_count % self.get_numb_set()]) - set_size = self.batch_set["energy"].shape[0] - # print ("%d %d %d" % (self.iterator, self.iterator + batch_size, set_size)) - iterator_1 = self.iterator + batch_size - if iterator_1 >= set_size : - iterator_1 = set_size - idx = np.arange (self.iterator, iterator_1) - self.iterator += batch_size - return self.get_set(self.batch_set, idx) - - def get_natoms (self) : - sample_type = self.batch_set["type"][0] - natoms = len(sample_type) - return natoms - - def get_natoms_2 (self, ntypes) : - sample_type = self.batch_set["type"][0] - natoms = len(sample_type) - natoms_vec = np.zeros (ntypes).astype(int) - for ii in range (ntypes) : - natoms_vec[ii] = np.count_nonzero(sample_type == ii) - return natoms, natoms_vec - - def get_natoms_vec (self, ntypes) : - natoms, natoms_vec = self.get_natoms_2 (ntypes) - tmp = [natoms, natoms] - tmp = np.append (tmp, natoms_vec) - return tmp.astype(np.int32) - - def set_numb_batch (self, - batch_size) : - return self.batch_set["energy"].shape[0] // batch_size - - def get_sys_numb_batch (self, batch_size) : - return self.set_numb_batch(batch_size) * self.get_numb_set() - - def get_ener (self) : - return self.eavg - - def numb_fparam(self) : - return self.has_fparam - - def numb_aparam(self) : - return self.has_aparam - diff --git a/deepmd/utils/data_system.py b/deepmd/utils/data_system.py index 88578749f2..a4faf4cc22 100644 --- a/deepmd/utils/data_system.py +++ b/deepmd/utils/data_system.py @@ -8,7 +8,6 @@ from typing import Tuple, List from deepmd.utils import random as dp_random -from deepmd.utils.data import DataSets from deepmd.utils.data import DeepmdData log = logging.getLogger(__name__) @@ -28,6 +27,7 @@ def __init__ (self, set_prefix : str = 'set', shuffle_test : bool = True, type_map : List[str] = None, + optional_type_map : bool = True, modifier = None, trn_all_set = False, sys_probs = None, @@ -51,6 +51,8 @@ def __init__ (self, If the test data are shuffled type_map Gives the name of different atom types + optional_type_map + If the type_map.raw in each system is optional modifier Data modifier that has the method `modify_data` trn_all_set @@ -80,7 +82,8 @@ def __init__ (self, ii, set_prefix=set_prefix, shuffle_test=shuffle_test, - type_map = type_map, + type_map = type_map, + optional_type_map = optional_type_map, modifier = modifier, trn_all_set = trn_all_set )) @@ -529,217 +532,3 @@ def _prob_sys_size_ext(self, keywords): tmp_prob = [float(i) for i in nbatch_block] / np.sum(nbatch_block) sys_probs[block_stt[ii]:block_end[ii]] = tmp_prob * block_probs[ii] return sys_probs - - - -class DataSystem (object) : - """ - Outdated class for the data systems. - - .. deprecated:: 2.0.0 - This class is not maintained any more. - """ - def __init__ (self, - systems, - set_prefix, - batch_size, - test_size, - rcut, - run_opt = None) : - self.system_dirs = systems - self.nsystems = len(self.system_dirs) - self.batch_size = batch_size - if isinstance(self.batch_size, int) : - self.batch_size = self.batch_size * np.ones(self.nsystems, dtype=int) - assert(isinstance(self.batch_size, (list,np.ndarray))) - assert(len(self.batch_size) == self.nsystems) - self.data_systems = [] - self.ntypes = [] - self.natoms = [] - self.natoms_vec = [] - self.nbatches = [] - for ii in self.system_dirs : - self.data_systems.append(DataSets(ii, set_prefix)) - sys_all_types = np.loadtxt(os.path.join(ii, "type.raw")).astype(int) - self.ntypes.append(np.max(sys_all_types) + 1) - self.sys_ntypes = max(self.ntypes) - type_map = [] - for ii in range(self.nsystems) : - self.natoms.append(self.data_systems[ii].get_natoms()) - self.natoms_vec.append(self.data_systems[ii].get_natoms_vec(self.sys_ntypes).astype(int)) - self.nbatches.append(self.data_systems[ii].get_sys_numb_batch(self.batch_size[ii])) - type_map.append(self.data_systems[ii].get_type_map()) - self.type_map = self.check_type_map_consistency(type_map) - - # check frame parameters - has_fparam = [ii.numb_fparam() for ii in self.data_systems] - for ii in has_fparam : - if ii != has_fparam[0] : - raise RuntimeError("if any system has frame parameter, then all systems should have the same number of frame parameter") - self.has_fparam = has_fparam[0] - - # check the size of data if they satisfy the requirement of batch and test - for ii in range(self.nsystems) : - chk_ret = self.data_systems[ii].check_batch_size(self.batch_size[ii]) - if chk_ret is not None : - raise RuntimeError ("system %s required batch size %d is larger than the size %d of the dataset %s" % \ - (self.system_dirs[ii], self.batch_size[ii], chk_ret[1], chk_ret[0])) - chk_ret = self.data_systems[ii].check_test_size(test_size) - if chk_ret is not None : - print("WARNNING: system %s required test size %d is larger than the size %d of the dataset %s" % \ - (self.system_dirs[ii], test_size, chk_ret[1], chk_ret[0])) - - if run_opt is not None: - self.print_summary(run_opt) - - self.prob_nbatches = [ float(i) for i in self.nbatches] / np.sum(self.nbatches) - - self.test_data = collections.defaultdict(list) - self.default_mesh = [] - for ii in range(self.nsystems) : - test_system_data = self.data_systems[ii].get_test () - for nn in test_system_data: - self.test_data[nn].append(test_system_data[nn]) - cell_size = np.max (rcut) - avg_box = np.average (test_system_data["box"], axis = 0) - avg_box = np.reshape (avg_box, [3,3]) - ncell = (np.linalg.norm(avg_box, axis=1)/ cell_size).astype(np.int32) - ncell[ncell < 2] = 2 - default_mesh = np.zeros (6, dtype = np.int32) - default_mesh[3:6] = ncell - self.default_mesh.append(default_mesh) - self.pick_idx = 0 - - - def check_type_map_consistency(self, type_map_list): - ret = [] - for ii in type_map_list: - if ii is not None: - min_len = min([len(ii), len(ret)]) - for idx in range(min_len) : - if ii[idx] != ret[idx] : - raise RuntimeError('inconsistent type map: %s %s' % (str(ret), str(ii))) - if len(ii) > len(ret) : - ret = ii - return ret - - - def get_type_map(self): - return self.type_map - - - def format_name_length(self, name, width) : - if len(name) <= width: - return '{: >{}}'.format(name, width) - else : - name = name[-(width-3):] - name = '-- ' + name - return name - - def print_summary(self) : - tmp_msg = "" - # width 65 - sys_width = 42 - tmp_msg += "---Summary of DataSystem-----------------------------------------\n" - tmp_msg += "find %d system(s):\n" % self.nsystems - tmp_msg += "%s " % self.format_name_length('system', sys_width) - tmp_msg += "%s %s %s\n" % ('natoms', 'bch_sz', 'n_bch') - for ii in range(self.nsystems) : - tmp_msg += ("%s %6d %6d %5d\n" % - (self.format_name_length(self.system_dirs[ii], sys_width), - self.natoms[ii], - self.batch_size[ii], - self.nbatches[ii]) ) - tmp_msg += "-----------------------------------------------------------------\n" - log.info(tmp_msg) - - def compute_energy_shift(self) : - sys_ener = np.array([]) - for ss in self.data_systems : - sys_ener = np.append(sys_ener, ss.get_ener()) - sys_tynatom = np.array(self.natoms_vec, dtype = float) - sys_tynatom = np.reshape(sys_tynatom, [self.nsystems,-1]) - sys_tynatom = sys_tynatom[:,2:] - energy_shift,resd,rank,s_value \ - = np.linalg.lstsq(sys_tynatom, sys_ener, rcond = 1e-3) - return energy_shift - - def process_sys_weights(self, sys_weights) : - sys_weights = np.array(sys_weights) - type_filter = sys_weights >= 0 - assigned_sum_prob = np.sum(type_filter * sys_weights) - assert assigned_sum_prob <= 1, "the sum of assigned probability should be less than 1" - rest_sum_prob = 1. - assigned_sum_prob - rest_nbatch = (1 - type_filter) * self.nbatches - rest_prob = rest_sum_prob * rest_nbatch / np.sum(rest_nbatch) - ret_prob = rest_prob + type_filter * sys_weights - assert np.sum(ret_prob) == 1, "sum of probs should be 1" - return ret_prob - - def get_batch (self, - sys_idx = None, - sys_weights = None, - style = "prob_sys_size") : - if sys_idx is not None : - self.pick_idx = sys_idx - else : - if sys_weights is None : - if style == "prob_sys_size" : - prob = self.prob_nbatches - elif style == "prob_uniform" : - prob = None - else : - raise RuntimeError("unkown get_batch style") - else : - prob = self.process_sys_weights(sys_weights) - self.pick_idx = dp_random.choice(np.arange(self.nsystems), p=prob) - b_data = self.data_systems[self.pick_idx].get_batch(self.batch_size[self.pick_idx]) - b_data["natoms_vec"] = self.natoms_vec[self.pick_idx] - b_data["default_mesh"] = self.default_mesh[self.pick_idx] - return b_data - - def get_test (self, - sys_idx = None) : - if sys_idx is not None : - idx = sys_idx - else : - idx = self.pick_idx - test_system_data = {} - for nn in self.test_data: - test_system_data[nn] = self.test_data[nn][idx] - test_system_data["natoms_vec"] = self.natoms_vec[idx] - test_system_data["default_mesh"] = self.default_mesh[idx] - return test_system_data - - def get_nbatches (self) : - return self.nbatches - - def get_ntypes (self) : - return self.sys_ntypes - - def get_nsystems (self) : - return self.nsystems - - def get_sys (self, sys_idx) : - return self.data_systems[sys_idx] - - def get_batch_size(self) : - return self.batch_size - - def numb_fparam(self) : - return self.has_fparam - -def _main () : - sys = ['/home/wanghan/study/deep.md/results.01/data/mos2/only_raws/20', - '/home/wanghan/study/deep.md/results.01/data/mos2/only_raws/30', - '/home/wanghan/study/deep.md/results.01/data/mos2/only_raws/38', - '/home/wanghan/study/deep.md/results.01/data/mos2/only_raws/MoS2', - '/home/wanghan/study/deep.md/results.01/data/mos2/only_raws/Pt_cluster'] - set_prefix = 'set' - ds = DataSystem (sys, set_prefix, 4, 6) - r = ds.get_batch() - print(r[1][0]) - -if __name__ == '__main__': - _main() - diff --git a/deepmd/utils/finetune.py b/deepmd/utils/finetune.py new file mode 100644 index 0000000000..a06962ea1f --- /dev/null +++ b/deepmd/utils/finetune.py @@ -0,0 +1,82 @@ +import logging +import json +import numpy as np +import deepmd +from typing import Callable +from typing import Tuple, List, Dict, Any +from functools import lru_cache +from scipy.special import comb +from deepmd.env import tf +from deepmd.env import op_module +from deepmd.common import ACTIVATION_FN_DICT +from deepmd.utils.graph import get_tensor_by_name +from deepmd.utils.errors import GraphWithoutTensorError +from deepmd.descriptor import Descriptor + +log = logging.getLogger(__name__) + + +def replace_model_params_with_pretrained_model(jdata: Dict[str, Any], pretrained_model: str): + """Replace the model params in input script according to pretrained model. + + Parameters + ---------- + jdata: Dict[str, Any] + input script + pretrained_model: str + filename of the pretrained model + """ + # Get the input script from the pretrained model + try: + t_jdata = get_tensor_by_name(pretrained_model, 'train_attr/training_script') + except GraphWithoutTensorError as e: + raise RuntimeError( + "The input frozen pretrained model: %s has no training script, " + "which is not supported to perform finetuning. " + "Please use the model pretrained with v2.1.5 or higher version of DeePMD-kit." % input + ) from e + pretrained_jdata = json.loads(t_jdata) + + # Check the model type + assert pretrained_jdata['model']['descriptor']['type'] in ['se_atten'] and \ + pretrained_jdata['model']['fitting_net']['type'] in ['ener'], \ + "The finetune process only supports models pretrained with 'se_atten' descriptor and 'ener' fitting_net!" + + # Check the type map + pretrained_type_map = pretrained_jdata['model']['type_map'] + cur_type_map = jdata['model'].get("type_map", []) + out_line_type = [] + for i in cur_type_map: + if i not in pretrained_type_map: + out_line_type.append(i) + assert not out_line_type, "{} type(s) not contained in the pretrained model! " \ + "Please choose another suitable one.".format(str(out_line_type)) + if cur_type_map != pretrained_type_map: + log.info("Change the type_map from {} to {}.".format(str(cur_type_map), str(pretrained_type_map))) + jdata['model']['type_map'] = pretrained_type_map + + # Change model configurations + log.info("Change the model configurations according to the pretrained one...") + for config_key in ['type_embedding', 'descriptor', 'fitting_net']: + if config_key not in jdata['model'].keys() and config_key in pretrained_jdata['model'].keys(): + log.info("Add the '{}' from pretrained model: {}.".format( + config_key, str(pretrained_jdata['model'][config_key]))) + jdata['model'][config_key] = pretrained_jdata['model'][config_key] + elif config_key == 'type_embedding' and \ + config_key in jdata['model'].keys() and config_key not in pretrained_jdata['model'].keys(): + # 'type_embedding' can be omitted using 'se_atten' descriptor, and the activation_function will be None. + cur_para = jdata['model'].pop(config_key) + if 'trainable' in cur_para and not cur_para['trainable']: + jdata['model'][config_key] = {'trainable': False, 'activation_function': 'None'} + log.info("The type_embeddings from pretrained model will be frozen.") + elif config_key in jdata['model'].keys() and config_key in pretrained_jdata['model'].keys() and \ + jdata['model'][config_key] != pretrained_jdata['model'][config_key]: + target_para = pretrained_jdata['model'][config_key] + cur_para = jdata['model'][config_key] + # keep some params that are irrelevant to model structures (need to discuss) TODO + if 'trainable' in cur_para.keys(): + target_para['trainable'] = cur_para['trainable'] + log.info("Change the '{}' from {} to {}.".format(config_key, str(cur_para), str(target_para))) + jdata['model'][config_key] = target_para + + return jdata, cur_type_map diff --git a/deepmd/utils/learning_rate.py b/deepmd/utils/learning_rate.py index 8019e1b2bd..e51b2497bb 100644 --- a/deepmd/utils/learning_rate.py +++ b/deepmd/utils/learning_rate.py @@ -1,6 +1,5 @@ import numpy as np from deepmd.env import tf -from deepmd.common import ClassArg class LearningRateExp (object) : r""" @@ -36,12 +35,6 @@ def __init__ (self, """ Constructor """ - # args = ClassArg()\ - # .add('decay_steps', int, must = False)\ - # .add('decay_rate', float, must = False)\ - # .add('start_lr', float, must = True)\ - # .add('stop_lr', float, must = False) - # self.cd = args.parse(jdata) self.cd = {} self.cd['start_lr'] = start_lr self.cd['stop_lr'] = stop_lr diff --git a/deepmd/utils/parallel_op.py b/deepmd/utils/parallel_op.py index 91f3d6d743..4fe652f064 100644 --- a/deepmd/utils/parallel_op.py +++ b/deepmd/utils/parallel_op.py @@ -1,4 +1,4 @@ -from typing import Callable, Generator, Tuple, Dict, Any +from typing import Optional, Callable, Generator, Tuple, Dict, Any from deepmd.env import tf from deepmd.utils.sess import run_sess @@ -32,7 +32,7 @@ class ParallelOp: >>> print(*p.generate(tf.Session(), feed())) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] """ - def __init__(self, builder: Callable[..., Tuple[Dict[str, tf.Tensor], Tuple[tf.Tensor]]], nthreads: int = None, config: tf.ConfigProto = None) -> None: + def __init__(self, builder: Callable[..., Tuple[Dict[str, tf.Tensor], Tuple[tf.Tensor]]], nthreads: Optional[int] = None, config: Optional[tf.ConfigProto] = None) -> None: if nthreads is not None: self.nthreads = nthreads elif config is not None: diff --git a/deepmd/utils/path.py b/deepmd/utils/path.py index 43f2e741ec..b5dab4b135 100644 --- a/deepmd/utils/path.py +++ b/deepmd/utils/path.py @@ -1,6 +1,6 @@ import os from abc import ABC, abstractmethod -from typing import List +from typing import Optional, List from pathlib import Path from functools import lru_cache @@ -246,7 +246,7 @@ def load_numpy(self) -> np.ndarray: """ return self.root[self.name][:] - def load_txt(self, dtype: np.dtype = None, **kwargs) -> np.ndarray: + def load_txt(self, dtype: Optional[np.dtype] = None, **kwargs) -> np.ndarray: """Load NumPy array from text. Returns diff --git a/deepmd/utils/random.py b/deepmd/utils/random.py index 7e7e91aa21..f0512cf321 100644 --- a/deepmd/utils/random.py +++ b/deepmd/utils/random.py @@ -1,10 +1,12 @@ +from typing import Optional + import numpy as np _RANDOM_GENERATOR = np.random.RandomState() -def choice(a: np.ndarray, p: np.ndarray = None): +def choice(a: np.ndarray, p: Optional[np.ndarray] = None): """Generates a random sample from a given 1-D array. Parameters @@ -38,7 +40,7 @@ def random(size=None): return _RANDOM_GENERATOR.random_sample(size) -def seed(val: int = None): +def seed(val: Optional[int] = None): """Seed the generator. Parameters diff --git a/deepmd/utils/tabulate.py b/deepmd/utils/tabulate.py index 47e9e301dd..14696f4137 100644 --- a/deepmd/utils/tabulate.py +++ b/deepmd/utils/tabulate.py @@ -8,7 +8,7 @@ from deepmd.env import tf from deepmd.env import op_module from deepmd.common import ACTIVATION_FN_DICT -from deepmd.utils.graph import get_tensor_by_name_from_graph, load_graph_def +from deepmd.utils.graph import get_tensor_by_name_from_graph from deepmd.utils.graph import get_embedding_net_nodes_from_graph_def from deepmd.descriptor import Descriptor @@ -19,7 +19,7 @@ class DPTabulate(): Class for tabulation. Compress a model, which including tabulating the embedding-net. - The table is composed of fifth-order polynomial coefficients and is assembled from two sub-tables. The first table takes the stride(parameter) as it\'s uniform stride, while the second table takes 10 * stride as it\s uniform stride + The table is composed of fifth-order polynomial coefficients and is assembled from two sub-tables. The first table takes the stride(parameter) as it\'s uniform stride, while the second table takes 10 * stride as it\'s uniform stride The range of the first table is automatically detected by deepmd-kit, while the second table ranges from the first table\'s upper boundary(upper) to the extrapolate(parameter) * upper. Parameters @@ -27,9 +27,11 @@ class DPTabulate(): descrpt Descriptor of the original model neuron - Number of neurons in each hidden layers of the embedding net :math:`\mathcal{N}` - model_file - The frozen model + Number of neurons in each hidden layers of the embedding net :math:`\\mathcal{N}` + graph : tf.Graph + The graph of the original model + graph_def : tf.GraphDef + The graph_def of the original model type_one_side Try to build N_types tables. Otherwise, building N_types^2 tables exclude_types : List[List[int]] @@ -43,7 +45,8 @@ class DPTabulate(): def __init__(self, descrpt : Descriptor, neuron : List[int], - model_file : str, + graph: tf.Graph, + graph_def: tf.GraphDef, type_one_side : bool = False, exclude_types : List[List[int]] = [], activation_fn : Callable[[tf.Tensor], tf.Tensor] = tf.nn.tanh, @@ -54,7 +57,8 @@ def __init__(self, """ self.descrpt = descrpt self.neuron = neuron - self.model_file = model_file + self.graph = graph + self.graph_def = graph_def self.type_one_side = type_one_side self.exclude_types = exclude_types self.suffix = suffix @@ -76,7 +80,6 @@ def __init__(self, raise RuntimeError("Unknown actication function type!") self.activation_fn = activation_fn - self.graph, self.graph_def = load_graph_def(self.model_file) #self.sess = tf.Session(graph = self.graph) self.sub_graph, self.sub_graph_def = self._load_sub_graph() @@ -143,7 +146,7 @@ def build(self, stride1 The uniform stride of the second table neuron - Number of neurons in each hidden layers of the embedding net :math:`\mathcal{N}` + Number of neurons in each hidden layers of the embedding net :math:`\\mathcal{N}` Returns ---------- diff --git a/deepmd/utils/type_embed.py b/deepmd/utils/type_embed.py index fcd890e224..d1023176cf 100644 --- a/deepmd/utils/type_embed.py +++ b/deepmd/utils/type_embed.py @@ -1,5 +1,5 @@ import numpy as np -from typing import Tuple, List, Union +from typing import Optional, Tuple, List, Union from deepmd.env import tf from deepmd.utils.network import one_layer @@ -61,7 +61,7 @@ class TypeEmbedNet(): Number of neurons in each hidden layers of the embedding net resnet_dt Time-step `dt` in the resnet construction: - y = x + dt * \phi (Wx + b) + y = x + dt * \\phi (Wx + b) activation_function The activation function in the embedding net. Supported options are |ACTIVATION_FN| precision @@ -82,7 +82,7 @@ def __init__( activation_function: Union[str, None] = 'tanh', precision: str = 'default', trainable: bool = True, - seed: int = None, + seed: Optional[int] = None, uniform_seed: bool = False, padding: bool = False, )->None: diff --git a/doc/application-examples.md b/doc/application-examples.md deleted file mode 100644 index bfbc9472a1..0000000000 --- a/doc/application-examples.md +++ /dev/null @@ -1,13 +0,0 @@ -# Application Examples - -## Dipole and polarizability model training - -## Training with non-periodic systems - -## MD on different hardware platforms - -There is a scheme to generate doc html from python scripts provided in the ../examples/ directory, so that each case in doc has a counter part in ../examples. - -This scheme is implemented with sphinx-gallery. - -Do we want to use this ??? diff --git a/doc/conf.py b/doc/conf.py index c4ac170be0..c0d473cf07 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -166,6 +166,7 @@ def setup(app): # } breathe_projects = { "cc": "_build/cc/xml/", + "c": "_build/c/xml/", "core": "_build/core/xml/", } breathe_default_project = "cc" @@ -187,10 +188,16 @@ def setup(app): "rootFileTitle": "C++ API", "rootFileName": "api_cc.rst", }, + "c": { + "containmentFolder": "./api_c", + "exhaleDoxygenStdin": "INPUT = ../source/api_c/include/", + "rootFileTitle": "C API", + "rootFileName": "api_c.rst", + }, "core": { "containmentFolder": "./api_core", "exhaleDoxygenStdin": """INPUT = ../source/lib/include/ - PREDEFINED = GOOGLE_CUDA + PREDEFINED += GOOGLE_CUDA TENSORFLOW_USE_ROCM """, "rootFileTitle": "Core API", diff --git a/doc/data/data-conv.md b/doc/data/data-conv.md index ee98ecf556..574c15143e 100644 --- a/doc/data/data-conv.md +++ b/doc/data/data-conv.md @@ -1,10 +1,10 @@ # Formats of a system -Two binaray formats, NumPy and HDF5, are supported for training. The raw format is not directly supported, but a tool is provided to convert data from the raw format to the NumPy format. +Two binary formats, NumPy and HDF5, are supported for training. The raw format is not directly supported, but a tool is provided to convert data from the raw format to the NumPy format. ## NumPy format -In a system with the Numpy format, the system properties are stored as text files ending with `.raw`, such as `type.raw` amd `type_map.raw`, under the system directory. If one needs to train a non-periodic system, an empty `nopbc` file should be put under the system directory. Both input and labeled frame properties are saved as the [NumPy binary data (NPY) files](https://numpy.org/doc/stable/reference/generated/numpy.lib.format.html#npy-format) ending with `.npy` in each of the `set.*` directories. Take an example, a system may contain the following files: +In a system with the Numpy format, the system properties are stored as text files ending with `.raw`, such as `type.raw` and `type_map.raw`, under the system directory. If one needs to train a non-periodic system, an empty `nopbc` file should be put under the system directory. Both input and labeled frame properties are saved as the [NumPy binary data (NPY) files](https://numpy.org/doc/stable/reference/generated/numpy.lib.format.html#npy-format) ending with `.npy` in each of the `set.*` directories. Take an example, a system may contain the following files: ``` type.raw type_map.raw @@ -23,7 +23,7 @@ $ cat type.raw 0 1 ``` -Sometimes one needs to map the integer types to atom name. The mapping can be given by the file `type_map.raw`. For example +Sometimes one needs to map the integer types to atom names. The mapping can be given by the file `type_map.raw`. For example ```bash $ cat type_map.raw O H @@ -34,19 +34,19 @@ For training models with descriptor `se_atten`, a [new system format](../model/t ## HDF5 format -A system with the HDF5 format has the same strucutre as the Numpy format, but in a HDF5 file, a system is organized as an [HDF5 group](https://docs.h5py.org/en/stable/high/group.html). The file name of a Numpy file is the key in a HDF5 file, and the data is the value to the key. One need to use `#` in a DP path to divide the path to the HDF5 file and the HDF5 key: +A system with the HDF5 format has the same structure as the Numpy format, but in an HDF5 file, a system is organized as an [HDF5 group](https://docs.h5py.org/en/stable/high/group.html). The file name of a Numpy file is the key in an HDF5 file, and the data is the value of the key. One needs to use `#` in a DP path to divide the path to the HDF5 file and the HDF5 path: ``` -/path/to/data.hdf5#H2O +/path/to/data.hdf5#/H2O ``` -Here, `/path/to/data.hdf5` is the path and `H2O` is the key. There should be some data in the `H2O` group, such as `H2O/type.raw` and `H2O/set.000/force.npy`. +Here, `/path/to/data.hdf5` is the file path and `/H2O` is the HDF5 path. All HDF5 paths should start with `/`. There should be some data in the `H2O` group, such as `/H2O/type.raw` and `/H2O/set.000/force.npy`. -A HDF5 files with a large number of systems has better performance than multiple NumPy files in a large cluster. +An HDF5 file with a large number of systems has better performance than multiple NumPy files in a large cluster. ## Raw format and data conversion A raw file is a plain text file with each information item written in one file and one frame written on one line. **It's not directly supported**, but we provide a tool to convert them. -In the raw format, the property of one frame are provided per line, ending with `.raw`. Take an example, the default files that provide box, coordinate, force, energy and virial are `box.raw`, `coord.raw`, `force.raw`, `energy.raw` and `virial.raw`, respectively. Here is an example of `force.raw`: +In the raw format, the property of one frame is provided per line, ending with `.raw`. Take an example, the default files that provide box, coordinate, force, energy and virial are `box.raw`, `coord.raw`, `force.raw`, `energy.raw` and `virial.raw`, respectively. Here is an example of `force.raw`: ```bash $ cat force.raw -0.724 2.039 -0.951 0.841 -0.464 0.363 @@ -69,4 +69,4 @@ making set 2 ... $ ls box.raw coord.raw energy.raw force.raw set.000 set.001 set.002 type.raw virial.raw ``` -It generates three sets `set.000`, `set.001` and `set.002`, with each set contains 2000 frames with the Numpy format. +It generates three sets `set.000`, `set.001` and `set.002`, with each set containing 2000 frames in the Numpy format. diff --git a/doc/data/dpdata.md b/doc/data/dpdata.md index f7fc3822ee..31679f0060 100644 --- a/doc/data/dpdata.md +++ b/doc/data/dpdata.md @@ -1,6 +1,6 @@ # Prepare data with dpdata -One can use the a convenient tool [`dpdata`](https://github.com/deepmodeling/dpdata) to convert data directly from the output of first principle packages to the DeePMD-kit format. +One can use a convenient tool [`dpdata`](https://github.com/deepmodeling/dpdata) to convert data directly from the output of first principle packages to the DeePMD-kit format. To install one can execute ```bash @@ -23,4 +23,4 @@ dsys.to('deepmd/npy', 'deepmd_data', set_size = dsys.get_nframes()) The data in DeePMD-kit format is stored in the folder `deepmd_data`. -A list of all [supported data format](https://github.com/deepmodeling/dpdata#load-data) and more nice features of `dpdata` can be found at the [official website](https://github.com/deepmodeling/dpdata). +A list of all [supported data format](https://github.com/deepmodeling/dpdata#load-data) and more nice features of `dpdata` can be found on the [official website](https://github.com/deepmodeling/dpdata). diff --git a/doc/data/index.md b/doc/data/index.md index 256b263aac..838265427b 100644 --- a/doc/data/index.md +++ b/doc/data/index.md @@ -1,8 +1,8 @@ # Data -In this section, we will introduce how to convert the DFT labeled data into the data format used by DeePMD-kit. +In this section, we will introduce how to convert the DFT-labeled data into the data format used by DeePMD-kit. -The DeePMD-kit organize data in `systems`. Each `system` is composed by a number of `frames`. One may roughly view a `frame` as a snap shot on an MD trajectory, but it does not necessary come from an MD simulation. A `frame` records the coordinates and types of atoms, cell vectors if the periodic boundary condition is assumed, energy, atomic forces and virial. It is noted that the `frames` in one `system` share the same number of atoms with the same type. +The DeePMD-kit organizes data in `systems`. Each `system` is composed of a number of `frames`. One may roughly view a `frame` as a snapshot of an MD trajectory, but it does not necessarily come from an MD simulation. A `frame` records the coordinates and types of atoms, cell vectors if the periodic boundary condition is assumed, energy, atomic forces and virials. It is noted that the `frames` in one `system` share the same number of atoms with the same type. - [System](system.md) - [Formats of a system](data-conv.md) diff --git a/doc/data/index.rst b/doc/data/index.rst index c9af5011af..7c73cf5d4a 100644 --- a/doc/data/index.rst +++ b/doc/data/index.rst @@ -1,8 +1,8 @@ Data ==== -In this section, we will introduce how to convert the DFT labeled data into the data format used by DeePMD-kit. +In this section, we will introduce how to convert the DFT-labeled data into the data format used by DeePMD-kit. -The DeePMD-kit organize data in :code:`systems`. Each :code:`system` is composed by a number of :code:`frames`. One may roughly view a :code:`frame` as a snap shot on an MD trajectory, but it does not necessary come from an MD simulation. A :code:`frame` records the coordinates and types of atoms, cell vectors if the periodic boundary condition is assumed, energy, atomic forces and virial. It is noted that the :code:`frames` in one :code:`system` share the same number of atoms with the same type. +The DeePMD-kit organizes data in :code:`systems`. Each :code:`system` is composed of a number of :code:`frames`. One may roughly view a :code:`frame` as a snapshot of an MD trajectory, but it does not necessarily come from an MD simulation. A :code:`frame` records the coordinates and types of atoms, cell vectors if the periodic boundary condition is assumed, energy, atomic forces and virials. It is noted that the :code:`frames` in one :code:`system` share the same number of atoms with the same type. .. toctree:: :maxdepth: 1 diff --git a/doc/data/system.md b/doc/data/system.md index d94c325cf5..1742807f76 100644 --- a/doc/data/system.md +++ b/doc/data/system.md @@ -1,6 +1,6 @@ # System -DeePMD-kit takes a **system** as data structure. A snapshot of a system is called a **frame**. A system may contain multiple frames with the same atom types and numbers, i.e. the same formula (like `H2O`). To contains data with different formula, one usually need to divide data into multiple systems, which may sometimes result in sparse-frame systems. See a [new system format](../model/train-se-atten.md#data-format) to further combine different systems with the same atom numbers, when training with descriptor `se_atten`. +DeePMD-kit takes a **system** as the data structure. A snapshot of a system is called a **frame**. A system may contain multiple frames with the same atom types and numbers, i.e. the same formula (like `H2O`). To contains data with different formulas, one usually needs to divide data into multiple systems, which may sometimes result in sparse-frame systems. See a [new system format](../model/train-se-atten.md#data-format) to further combine different systems with the same atom numbers, when training with descriptor `se_atten`. A system should contain system properties, input frame properties, and labeled frame properties. The system property contains the following property: @@ -10,7 +10,7 @@ type | Atom type indexes | type.raw | Required | Natom type_map | Atom type names | type_map.raw | Optional | Ntypes | Atom names that map to atom type, which is unnecessart to be contained in the periodic table nopbc | Non-periodic system | nopbc | Optional | 1 | If True, this system is non-periodic; otherwise it's periodic -The input frame properties contains the following property, the first axis of which is the number of frames: +The input frame properties contain the following property, the first axis of which is the number of frames: ID | Property | Raw file | Unit | Required/Optional | Shape | Description -------- | ---------------------- | -------------- | ---- | -------------------- | ----------------------- | ----------- diff --git a/doc/development/cmake.md b/doc/development/cmake.md new file mode 100644 index 0000000000..3073327856 --- /dev/null +++ b/doc/development/cmake.md @@ -0,0 +1,19 @@ +# Find DeePMD-kit C/C++ library from CMake + +After DeePMD-kit C/C++ library is installed, one can find DeePMD-kit from CMake: + +```cmake +find_package(DeePMD REQUIRED) +``` + +Note that you may need to add ${deepmd_root} to the cached CMake variable `CMAKE_PREFIX_PATH`. + +To link against the C interface library, using +```cmake +target_link_libraries(some_library PRIVATE DeePMD::deepmd_c) +``` + +To link against the C++ interface library, using +```cmake +target_link_libraries(some_library PRIVATE DeePMD::deepmd_cc) +``` diff --git a/doc/development/coding-conventions.rst b/doc/development/coding-conventions.rst index 856634cbef..2a3cfc3866 100644 --- a/doc/development/coding-conventions.rst +++ b/doc/development/coding-conventions.rst @@ -7,27 +7,27 @@ Coding Conventions Preface ======= -The aim of these coding standards is to help create a codebase with defined and +The aim of these coding standards is to help create a codebase with a defined and consistent coding style that every contributor can get easily familiar with. This will in enhance code readability as there will be no different coding styles from -different contributors and everything will be documented. Also PR diffs will be smaller -because of unified coding style. Finally static typing will help in hunting down +different contributors and everything will be documented. Also, PR diffs will be smaller +because of the unified coding style. Finally, static typing will help in hunting down potential bugs before the code is even run. Contributed code will not be refused merely because it does not strictly adhere to these conditions; as long as it's internally consistent, clean, and correct, it probably will be accepted. But -don't be surprised if the "offending" code gets fiddled over time to +don't be surprised if the "offending" code gets fiddled with overtime to conform to these conventions. -There are also github actions CI checks for python code style which will annotate the +There are also GitHub actions CI checks for python code style which will annotate the PR diff for you to see the areas where your code is lacking compared to the set standard. Rules ===== The code must be compatible with the oldest supported version of python -which is 3.6 +which is 3.7 The project follows the generic coding conventions as specified in the `Style Guide for Python Code`_, `Docstring @@ -41,8 +41,8 @@ Conventions`_ and `Typing Conventions`_ PEPs, clarified and extended as follows: * No one-liner compound statements (i.e., no ``if x: return``: use two lines). -* Maximum line length is 88 characters as recomended by - `black `_ wich is less strict than +* Maximum line length is 88 characters as recommended by + `black `_ which is less strict than `Docstring Conventions`_ suggests. * Use "StudlyCaps" for class names. @@ -88,7 +88,7 @@ Python is not C/C++ so whitespace should be used sparingly to maintain code rea * You should have blank spaces after commas, colons, and semi-colons if it isn’t trailing next to the end of a bracket, brace, or parentheses. -* With any operators you should use a space in on both sides of the operator. +* With any operators you should use space on both sides of the operator. * Colons for slicing are considered a binary operator, and should not have any spaces between them. @@ -130,7 +130,7 @@ Here is an example of how to write good docstrings: https://github.com/numpy/numpy/blob/master/doc/example.py -The numpy doctring documentation can be found `here `_ +The NumPy docstring documentation can be found `here `_ It is a good practice to run `pydocstyle `_ check on your code or use a text editor that does it automatically): @@ -182,7 +182,7 @@ Run black on your code Another method of enforcing PEP8_ is using a tool such as `black `_. These tools tend to be -very effective at cleaning up code, but should be used carefully and code +very effective at cleaning up code but should be used carefully and code should be retested after cleaning it. Try: .. code-block:: bash diff --git a/doc/development/create-a-model.md b/doc/development/create-a-model.md index b3eeffee30..69a93973aa 100644 --- a/doc/development/create-a-model.md +++ b/doc/development/create-a-model.md @@ -1,9 +1,9 @@ # Create a model -If you'd like to create a new model that isn't covered by the existing DeePMD-kit library, but reuse DeePMD-kit's other efficient module such as data processing, trainner, etc, you may want to read this section. +If you'd like to create a new model that isn't covered by the existing DeePMD-kit library, but reuse DeePMD-kit's other efficient modules such as data processing, trainner, etc, you may want to read this section. To incorporate your custom model you'll need to: -1. Register and implement new components (e.g. descriptor) in a Python file. You may also want to regiester new TensorFlow OPs if necessary. +1. Register and implement new components (e.g. descriptor) in a Python file. You may also want to register new TensorFlow OPs if necessary. 2. Register new arguments for user inputs. 3. Package new codes into a Python package. 4. Test new models. @@ -24,7 +24,7 @@ class SomeDescript(Descriptor): ## Register new arguments -To let some one uses your new component in their input file, you need to create a new methods that returns some `Argument` of your new component, and then register new arguments. For example, the code below +To let someone uses your new component in their input file, you need to create a new method that returns some `Argument` of your new component, and then register new arguments. For example, the code below ```py from typing import List @@ -50,11 +50,11 @@ allows one to use your new descriptor as below: } ``` -The arguments here should be consistent with the class arguments of your new componenet. +The arguments here should be consistent with the class arguments of your new component. ## Package new codes -You may use `setuptools` to package new codes into a new Python package. It's crirical to add your new component to `entry_points['deepmd']` in `setup.py`: +You may use `setuptools` to package new codes into a new Python package. It's crucial to add your new component to `entry_points['deepmd']` in `setup.py`: ```py entry_points={ diff --git a/doc/development/type-embedding.md b/doc/development/type-embedding.md index c1136bf94d..40de2c5867 100644 --- a/doc/development/type-embedding.md +++ b/doc/development/type-embedding.md @@ -1,9 +1,9 @@ # Atom Type Embedding ## Overview -Here is an overview of the deepmd-kit algorithm. Given a specific centric atom, we can obtain the matrix describing its local environment, named as $\mathcal R$. It is consist of the distance between centric atom and its neighbors, as well as a direction vector. We can embed each distance into a vector of $M_1$ dimension by an `embedding net`, so the environment matrix $\mathcal R$ can be embed into matrix $\mathcal G$. We can thus extract a descriptor vector (of $M_1 \times M_2$ dim) of the centric atom from the $\mathcal G$ by some matrix multiplication, and put the descriptor into `fitting net` to get predicted energy $E$. The vanilla version of deepmd-kit build `embedding net` and `fitting net` relying on the atom type, resulting in $O(N)$ memory usage. After applying atom type embedding, in deepmd-kit v2.0, we can share one `embedding net` and one `fitting net` in total, which decline training complexity largely. +Here is an overview of the DeePMD-kit algorithm. Given a specific centric atom, we can obtain the matrix describing its local environment, named $\mathcal R$. It is consist of the distance between the centric atom and its neighbors, as well as a direction vector. We can embed each distance into a vector of $M_1$ dimension by an `embedding net`, so the environment matrix $\mathcal R$ can be embedded into matrix $\mathcal G$. We can thus extract a descriptor vector (of $M_1 \times M_2$ dim) of the centric atom from the $\mathcal G$ by some matrix multiplication, and put the descriptor into `fitting net` to get predicted energy $E$. The vanilla version of DeePMD-kit builds `embedding net` and `fitting net` relying on the atom type, resulting in $O(N)$ memory usage. After applying atom type embedding, in DeePMD-kit v2.0, we can share one `embedding net` and one `fitting net` in total, which decline training complexity largely. ## Preliminary -In the following chart, you can find the meaning of symbols used to clarify the atom type embedding algorithm. +In the following chart, you can find the meaning of symbols used to clarify the atom-type embedding algorithm. $i$: Type of centric atom @@ -22,14 +22,14 @@ $F_i(\cdot)$: Origin fitting net, take the descriptor vector as input and output $F(\cdot)$: Shared fitting net -$A(\cdot)$: Atom type embedding net, input is atom type, output is type embedding vector of dim `nchanl` +$A(\cdot)$: Atom type embedding net, input is atom type, the output is type embedding vector of dim `nchanl` So, we can formulate the training process as follows. -Vanilla deepmd-kit algorithm: +Vanilla DeePMD-kit algorithm: $$E = F_i( \text{Multi}( \mathcal G_{ij}( s_{ij} ) ) )$$ -Deepmd-kit applying atom type embedding: +DeePMD-kit applying atom type embedding: $$E = F( [ \text{Multi}( \mathcal G( [s_{ij}, A(i), A(j)] ) ), A(j)] )$$ @@ -37,10 +37,10 @@ or $$E = F( [ \text{Multi}( \mathcal G( [s_{ij}, A(j)] ) ), A(j)] )$$ -The difference between two variants above is whether using the information of centric atom when generating the descriptor. Users can choose by modifying the `type_one_side` hyper-parameter in the input json file. +The difference between the two variants above is whether using the information of centric atom when generating the descriptor. Users can choose by modifying the `type_one_side` hyper-parameter in the input JSON file. ## How to use -A detailed introduction can be found at [`se_e2_a_tebd`](../model/train-se-e2-a-tebd.md). Looking for a fast start up, you can simply add a `type_embedding` section in the input json file as displayed in the following, and the algorithm will adopt atom type embedding algorithm automatically. +A detailed introduction can be found at [`se_e2_a_tebd`](../model/train-se-e2-a-tebd.md). Looking for a fast start-up, you can simply add a `type_embedding` section in the input JSON file as displayed in the following, and the algorithm will adopt the atom type embedding algorithm automatically. An example of `type_embedding` is like ```json "type_embedding":{ @@ -52,14 +52,14 @@ An example of `type_embedding` is like ## Code Modification -Atom type embedding can be applied to varied `embedding net` and `fitting net`, as a result we build a class `TypeEmbedNet` to support this free combination. In the following, we will go through the execution process of the code to explain our code modification. +Atom-type embedding can be applied to varied `embedding net` and `fitting net`, as a result, we build a class `TypeEmbedNet` to support this free combination. In the following, we will go through the execution process of the code to explain our code modification. ### trainer (train/trainer.py) -In trainer.py, it will parse the parameter from the input json file. If a `type_embedding` section is detected, it will build a `TypeEmbedNet`, which will be later input in the `model`. `model` will be built in the function `_build_network`. +In trainer.py, it will parse the parameter from the input JSON file. If a `type_embedding` section is detected, it will build a `TypeEmbedNet`, which will be later input in the `model`. `model` will be built in the function `_build_network`. ### model (model/ener.py) When building the operation graph of the `model` in `model.build`. If a `TypeEmbedNet` is detected, it will build the operation graph of `type embed net`, `embedding net` and `fitting net` by order. The building process of `type embed net` can be found in `TypeEmbedNet.build`, which output the type embedding vector of each atom type (of [$\text{ntypes} \times \text{nchanl}$] dimensions). We then save the type embedding vector into `input_dict`, so that they can be fetched later in `embedding net` and `fitting net`. ### embedding net (descriptor/se*.py) -In `embedding net`, we shall take local environment $\mathcal R$ as input and output matrix $\mathcal G$. Functions called in this process by order is +In `embedding net`, we shall take local environment $\mathcal R$ as input and output matrix $\mathcal G$. Functions called in this process by the order is ``` build -> _pass_filter -> _filter -> _filter_lower ``` @@ -67,12 +67,12 @@ build -> _pass_filter -> _filter -> _filter_lower `_filter`: It will call `_filter_lower` function to obtain the result of matrix multiplication ($\mathcal G^T\cdot \mathcal R$), do further multiplication involved in $\text{Multi}(\cdot)$, and finally output the result of descriptor vector of $M_1 \times M_2$ dim. -`_filter_lower`: The main function handling input modification. If type embedding exists, it will call `_concat_type_embedding` function to concat the first column of input $\mathcal R$ (the column of $s_{ij}$) with the atom type embedding information. It will decide whether using the atom type embedding vector of centric atom according to the value of `type_one_side` (if set **True**, then we only use the vector of the neighbor atom). The modified input will be put into the `fitting net` to get $\mathcal G$ for further matrix multiplication stage. +`_filter_lower`: The main function handling input modification. If type embedding exists, it will call `_concat_type_embedding` function to concat the first column of input $\mathcal R$ (the column of $s_{ij}$) with the atom type embedding information. It will decide whether to use the atom type embedding vector of the centric atom according to the value of `type_one_side` (if set **True**, then we only use the vector of the neighbor atom). The modified input will be put into the `fitting net` to get $\mathcal G$ for further matrix multiplication stage. ### fitting net (fit/ener.py) -In `fitting net`, it take the descriptor vector as input, whose dimension is [natoms, $M_1\times M_2$]. Because we need to involve information of centric atom in this step, we need to generate a matrix named as `atype_embed` (of dim [natoms, nchanl]), in which each row is the type embedding vector of the specific centric atom. The input is sorted by type of centric atom, we also know the number of a particular atom type (stored in `natoms[2+i]`), thus we get the type vector of centric atom. In the build phrase of fitting net, it will check whether type embedding exist in `input_dict` and fetch them. After that calling `embed_atom_type` function to lookup embedding vector for type vector of centric atom to obtain `atype_embed`, and concat input with it ([input, atype_embed]). The modified input go through `fitting net` to get predicted energy. +In `fitting net`, it takes the descriptor vector as input, whose dimension is [natoms, $M_1\times M_2$]. Because we need to involve information on the centric atom in this step, we need to generate a matrix named `atype_embed` (of dim [natoms, nchanl]), in which each row is the type embedding vector of the specific centric atom. The input is sorted by type of centric atom, we also know the number of a particular atom type (stored in `natoms[2+i]`), thus we get the type vector of the centric atom. In the build phase of the fitting net, it will check whether type embedding exists in `input_dict` and fetch them. After that, call `embed_atom_type` function to look up the embedding vector for the type vector of the centric atom to obtain `atype_embed`, and concat input with it ([input, atype_embed]). The modified input goes through `fitting` net` to get predicted energy. :::{note} -You can't apply compression method while using atom type embedding. +You can't apply the compression method while using atom-type embedding. ::: diff --git a/doc/freeze/compress.md b/doc/freeze/compress.md index 5cd6016d32..ec71de9e97 100644 --- a/doc/freeze/compress.md +++ b/doc/freeze/compress.md @@ -1,6 +1,6 @@ # Compress a model -Once the frozen model is obtained from deepmd-kit, we can get the neural network structure and its parameters (weights, biases, etc.) from the trained model, and compress it in the following way: +Once the frozen model is obtained from DeePMD-kit, we can get the neural network structure and its parameters (weights, biases, etc.) from the trained model, and compress it in the following way: ```bash dp compress -i graph.pb -o graph-compress.pb ``` @@ -67,22 +67,22 @@ optional arguments: ``` **Parameter explanation** -Model compression, which including tabulating the embedding-net. -The table is composed of fifth-order polynomial coefficients and is assembled from two sub-tables. For model descriptor with `se_e2_a` type, the first sub-table takes the stride(parameter) as it's uniform stride, while the second sub-table takes 10 * stride as it's uniform stride; For model descriptor with `se_e3` type, the first sub-table takes 10 * stride as it's uniform stride, while the second sub-table takes 100 * stride as it's uniform stride. -The range of the first table is automatically detected by deepmd-kit, while the second table ranges from the first table's upper boundary(upper) to the extrapolate(parameter) * upper. -Finally, we added a check frequency parameter. It indicates how often the program checks for overflow(if the input environment matrix overflow the first or second table range) during the MD inference. +Model compression, which includes tabulating the embedding net. +The table is composed of fifth-order polynomial coefficients and is assembled from two sub-tables. For model descriptor with `se_e2_a` type, the first sub-table takes the stride(parameter) as its uniform stride, while the second sub-table takes 10 * stride as its uniform stride; For model descriptor with `se_e3` type, the first sub-table takes 10 * stride as it's uniform stride, while the second sub-table takes 100 * stride as it's uniform stride. +The range of the first table is automatically detected by DeePMD-kit, while the second table ranges from the first table's upper boundary(upper) to the extrapolate(parameter) * upper. +Finally, we added a check frequency parameter. It indicates how often the program checks for overflow(if the input environment matrix overflows the first or second table range) during the MD inference. **Justification of model compression** -Model compression, with little loss of accuracy, can greatly speed up MD inference time. According to different simulation systems and training parameters, the speedup can reach more than 10 times at both CPU and GPU devices. At the same time, model compression can greatly change the memory usage, reducing as much as 20 times under the same hardware conditions. +Model compression, with little loss of accuracy, can greatly speed up MD inference time. According to different simulation systems and training parameters, the speedup can reach more than 10 times at both CPU and GPU devices. At the same time, model compression can greatly change memory usage, reducing as much as 20 times under the same hardware conditions. **Acceptable original model version** -The model compression interface requires the version of deepmd-kit used in original model generation should be `2.0.0-alpha.0` or above. If one has a frozen 1.2 or 1.3 model, one can upgrade it through the `dp convert-from` interface.(eg: ```dp convert-from 1.2/1.3 -i old_frozen_model.pb -o new_frozen_model.pb```) +The model compression interface requires the version of DeePMD-kit used in the original model generation should be `2.0.0-alpha.0` or above. If one has a frozen 1.2 or 1.3 model, one can upgrade it through the `dp convert-from` interface. (eg: ```dp convert-from 1.2/1.3 -i old_frozen_model.pb -o new_frozen_model.pb```) **Acceptable descriptor type** -Descriptors with `se_e2_a`,`se_e3`, `se_e2_r` type are supported by the model compression feature. Hybrid mixed with above descriptors is also supported. +Descriptors with `se_e2_a`, `se_e3`, and `se_e2_r` types are supported by the model compression feature. `Hybrid` mixed with the above descriptors is also supported. **Available activation functions for descriptor:** diff --git a/doc/freeze/freeze.md b/doc/freeze/freeze.md index fdb2f2cc97..92cfb29c00 100644 --- a/doc/freeze/freeze.md +++ b/doc/freeze/freeze.md @@ -1,7 +1,11 @@ # Freeze a model -The trained neural network is extracted from a checkpoint and dumped into a database. This process is called "freezing" a model. The idea and part of our code are from [Morgan](https://blog.metaflow.fr/tensorflow-how-to-freeze-a-model-and-serve-it-with-a-python-api-d4f3596b3adc). To freeze a model, typically one does +The trained neural network is extracted from a checkpoint and dumped into a protobuf(.pb) file. This process is called "freezing" a model. The idea and part of our code are from [Morgan](https://blog.metaflow.fr/tensorflow-how-to-freeze-a-model-and-serve-it-with-a-python-api-d4f3596b3adc). To freeze a model, typically one does ```bash $ dp freeze -o graph.pb ``` -in the folder where the model is trained. The output database is called `graph.pb`. \ No newline at end of file +in the folder where the model is trained. The output model is called `graph.pb`. + +In [multi-task mode](../train/multi-task-training.md), this process will output several models, each of which contains the common descriptor and +one of the user-defined fitting nets in {ref}`fitting_net_dict `, let's name it `fitting_key`, together frozen in `graph_{fitting_key}.pb`. +Those frozen models are exactly the same as single-task output with fitting net `fitting_key`. \ No newline at end of file diff --git a/doc/index.rst b/doc/index.rst index b8b4d6862b..048dfd1f25 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -7,7 +7,7 @@ DeePMD-kit's documentation ========================== -DeePMD-kit is a package written in Python/C++, designed to minimize the effort required to build deep learning based model of interatomic potential energy and force field and to perform molecular dynamics (MD). This brings new hopes to addressing the accuracy-versus-efficiency dilemma in molecular simulations. Applications of DeePMD-kit span from finite molecules to extended systems and from metallic systems to chemically bonded systems. +DeePMD-kit is a package written in Python/C++, designed to minimize the effort required to build deep learning-based models of interatomic potential energy and force field and to perform molecular dynamics (MD). This brings new hopes to addressing the accuracy-versus-efficiency dilemma in molecular simulations. Applications of DeePMD-kit span from finite molecules to extended systems and from metallic systems to chemically bonded systems. .. Important:: The project DeePMD-kit is licensed under `GNU LGPLv3.0 `_. If you use this code in any future publications, please cite this using *Han Wang, Linfeng Zhang, Jiequn Han, and Weinan E. "DeePMD-kit: A deep learning package for many-body potential energy representation and molecular dynamics." Computer Physics Communications 228 (2018): 178-184.* @@ -60,6 +60,7 @@ DeePMD-kit is a package written in Python/C++, designed to minimize the effort r api_py/api_py api_op API_CC/api_cc + api_c/api_c api_core/api_core diff --git a/doc/inference/cxx.md b/doc/inference/cxx.md index 746164df23..6a1fc49c47 100644 --- a/doc/inference/cxx.md +++ b/doc/inference/cxx.md @@ -1,5 +1,6 @@ -# C++ interface -The C++ interface of DeePMD-kit is also avaiable for model interface, which is considered faster than Python interface. An example `infer_water.cpp` is given below: +# C/C++ interface +## C++ interface +The C++ interface of DeePMD-kit is also available for the model interface, which is considered faster than the Python interface. An example `infer_water.cpp` is given below: ```cpp #include "deepmd/DeepPot.h" @@ -14,12 +15,116 @@ int main(){ } ``` where `e`, `f` and `v` are predicted energy, force and virial of the system, respectively. +See {cpp:class}`deepmd::DeepPot` for details. You can compile `infer_water.cpp` using `gcc`: ```sh -gcc infer_water.cpp -D HIGH_PREC -L $deepmd_root/lib -L $tensorflow_root/lib -I $deepmd_root/include -Wl,--no-as-needed -ldeepmd_cc -lstdc++ -ltensorflow_cc -Wl,-rpath=$deepmd_root/lib -Wl,-rpath=$tensorflow_root/lib -o infer_water +gcc infer_water.cpp -L $deepmd_root/lib -L $tensorflow_root/lib -I $deepmd_root/include -Wl,--no-as-needed -ldeepmd_cc -lstdc++ -ltensorflow_cc -Wl,-rpath=$deepmd_root/lib -Wl,-rpath=$tensorflow_root/lib -o infer_water ``` and then run the program: ```sh ./infer_water ``` + +## C interface + +Although C is harder to write, the C library will not be affected by different versions of C++ compilers. + +An example `infer_water.c` is given below: +```cpp +#include +#include +#include "deepmd/c_api.h" + +int main(){ + const char* model = "graph.pb"; + double coord[] = {1., 0., 0., 0., 0., 1.5, 1. ,0. ,3.}; + double cell[] = {10., 0., 0., 0., 10., 0., 0., 0., 10.}; + int atype[] = {1, 0, 1}; + // init C pointers with given memory + double* e = malloc(sizeof(*e)); + double* f = malloc(sizeof(*f) * 9); // natoms * 3 + double* v = malloc(sizeof(*v) * 9); + double* ae = malloc(sizeof(*ae) * 9); // natoms + double* av = malloc(sizeof(*av) * 27); // natoms * 9 + // DP model + DP_DeepPot* dp = DP_NewDeepPot(model); + DP_DeepPotCompute (dp, 3, coord, atype, cell, e, f, v, ae, av); + // print results + printf("energy: %f\n", *e); + for (int ii = 0; ii < 9; ++ii) + printf("force[%d]: %f\n", ii, f[ii]); + for (int ii = 0; ii < 9; ++ii) + printf("force[%d]: %f\n", ii, v[ii]); + // free memory + free(e); + free(f); + free(v); + free(ae); + free(av); + free(dp); +} +``` + +where `e`, `f` and `v` are predicted energy, force and virial of the system, respectively. +`ae` and `av` are atomic energy and atomic virials, respectively. +See {cpp:func}`DP_DeepPotCompute` for details. + +You can compile `infer_water.c` using `gcc`: +```sh +gcc infer_water.c -L $deepmd_root/lib -L $tensorflow_root/lib -I $deepmd_root/include -Wl,--no-as-needed -ldeepmd_c -Wl,-rpath=$deepmd_root/lib -Wl,-rpath=$tensorflow_root/lib -o infer_water +``` +and then run the program: +```sh +./infer_water +``` + +## Header-only C++ library interface (recommended) + +The header-only C++ library is built based on the C library. +Thus, it has the same ABI compatibility as the C library but provides a powerful C++ interface. +To use it, include `deepmd/deepmd.hpp`. + +```cpp +#include "deepmd/deepmd.hpp" + +int main(){ + deepmd::hpp::DeepPot dp ("graph.pb"); + std::vector coord = {1., 0., 0., 0., 0., 1.5, 1. ,0. ,3.}; + std::vector cell = {10., 0., 0., 0., 10., 0., 0., 0., 10.}; + std::vector atype = {1, 0, 1}; + double e; + std::vector f, v; + dp.compute (e, f, v, coord, atype, cell); +} +``` + +Note that the feature of the header-only C++ library is still limited compared to the original C++ library. +See {cpp:class}`deepmd::hpp::DeepPot` for details. + +You can compile `infer_water_hpp.cpp` using `gcc`: +```sh +gcc infer_water_hpp.hpp -L $deepmd_root/lib -L $tensorflow_root/lib -I $deepmd_root/include -Wl,--no-as-needed -ldeepmd_c -Wl,-rpath=$deepmd_root/lib -Wl,-rpath=$tensorflow_root/lib -o infer_water_hpp +``` +and then run the program: +```sh +./infer_water_hpp +``` + +In some cases, one may want to pass the custom neighbor list instead of the native neighbor list. The above code can be revised as follows: + +```cpp + // neighbor list + std::vector> nlist_vec = { + {1, 2}, + {0, 2}, + {0, 1} + }; + std::vector ilist(3), numneigh(3); + std::vector firstneigh(3); + InputNlist nlist(3, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(nlist, nlist_vec); + dp.compute (e, f, v, coord, atype, cell, 0, nlist, 0); +``` + +Here, `nlist_vec` means the neighbors of atom 0 are atom 1 and atom 2, the neighbors of atom 1 are atom 0 and atom 2, and the neighbors of atom 2 are atom 0 and atom 1. diff --git a/doc/inference/python.md b/doc/inference/python.md index bdf9074a86..fd4cb6fc43 100644 --- a/doc/inference/python.md +++ b/doc/inference/python.md @@ -12,7 +12,7 @@ e, f, v = dp.eval(coord, cell, atype) ``` where `e`, `f` and `v` are predicted energy, force and virial of the system, respectively. -Furthermore, one can use the python interface to calulate model deviation. +Furthermore, one can use the python interface to calculate model deviation. ```python from deepmd.infer import calc_model_devi from deepmd.infer import DeepPot as DP @@ -23,4 +23,6 @@ cell = np.diag(10 * np.ones(3)).reshape([1, -1]) atype = [1,0,1] graphs = [DP("graph.000.pb"), DP("graph.001.pb")] model_devi = calc_model_devi(coord, cell, atype, graphs) -``` \ No newline at end of file +``` + +Note that if the model inference or model deviation is performed cyclically, one should avoid calling the same model multiple times. Otherwise, tensorFlow will never release the memory and this may lead to an out-of-memory (OOM) error. diff --git a/doc/install/build-conda.md b/doc/install/build-conda.md index 253de51e96..41c9f90a6e 100644 --- a/doc/install/build-conda.md +++ b/doc/install/build-conda.md @@ -2,7 +2,7 @@ One may want to keep both convenience and personalization of the DeePMD-kit. To achieve this goal, one can consider building conda packages. We provide building scripts in [deepmd-kit-recipes organization](https://github.com/deepmd-kit-recipes/). These building tools are driven by [conda-build](https://github.com/conda/conda-build) and [conda-smithy](https://github.com/conda-forge/conda-smithy). -For example, if one wants to turn on `MPIIO` package in LAMMPS, go to [`lammps-feedstock`](https://github.com/deepmd-kit-recipes/lammps-feedstock/) repository and modify `recipe/build.sh`. `-D PKG_MPIIO=OFF` should be changed to `-D PKG_MPIIO=ON`. Then go to the main directory and executing +For example, if one wants to turn on `MPIIO` package in LAMMPS, go to [`lammps-feedstock`](https://github.com/deepmd-kit-recipes/lammps-feedstock/) repository and modify `recipe/build.sh`. `-D PKG_MPIIO=OFF` should be changed to `-D PKG_MPIIO=ON`. Then go to the main directory and execute ```sh ./build-locally.py diff --git a/doc/install/easy-install.md b/doc/install/easy-install.md index 243c099eb8..9e5e955332 100644 --- a/doc/install/easy-install.md +++ b/doc/install/easy-install.md @@ -11,6 +11,7 @@ Note: The off-line packages and conda packages require the [GNU C Library](https - [Install off-line packages](#install-off-line-packages) - [Install with conda](#install-with-conda) - [Install with docker](#install-with-docker) +- [Install Python interface with pip](#install-python-interface-with-pip) ## Install off-line packages @@ -29,6 +30,8 @@ conda activate /path/to/deepmd-kit ## Install with conda DeePMD-kit is avaiable with [conda](https://github.com/conda/conda). Install [Anaconda](https://www.anaconda.com/distribution/#download-section) or [Miniconda](https://docs.conda.io/en/latest/miniconda.html) first. +### Offical channel + One may create an environment that contains the CPU version of DeePMD-kit and LAMMPS: ```bash conda create -n deepmd deepmd-kit=*=*cpu libdeepmd=*=*cpu lammps -c https://conda.deepmodeling.com -c defaults @@ -40,7 +43,7 @@ conda create -n deepmd deepmd-kit=*=*gpu libdeepmd=*=*gpu lammps cudatoolkit=11. ``` One could change the CUDA Toolkit version from `10.2` or `11.6`. -One may speficy the DeePMD-kit version such as `2.1.1` using +One may specify the DeePMD-kit version such as `2.1.1` using ```bash conda create -n deepmd deepmd-kit=2.1.1=*cpu libdeepmd=2.1.1=*cpu lammps horovod -c https://conda.deepmodeling.com -c defaults ``` @@ -50,6 +53,17 @@ One may enable the environment using conda activate deepmd ``` +### conda-forge channel + +DeePMD-kit is also available on the [conda-forge](https://conda-forge.org/) channel: + +```bash +conda create -n deepmd deepmd-kit lammps -c conda-forge +``` + +The supported platform includes Linux x86-64, macOS x86-64, and macOS arm64. +Read [conda-forge FAQ](https://conda-forge.org/docs/user/tipsandtricks.html#installing-cuda-enabled-packages-like-tensorflow-and-pytorch) to learn how to install CUDA-enabled packages. + ## Install with docker A docker for installing the DeePMD-kit is available [here](https://github.com/orgs/deepmodeling/packages/container/package/deepmd-kit). @@ -67,3 +81,30 @@ To pull the ROCm version: ```bash docker pull deepmodeling/dpmdkit-rocm:dp2.0.3-rocm4.5.2-tf2.6-lmp29Sep2021 ``` + +## Install Python interface with pip + +If you have no existing TensorFlow installed, you can use `pip` to install the pre-built package of the Python interface with CUDA 11 supported: + +```bash +pip install deepmd-kit[gpu] +``` + +Or install the CPU version without CUDA supported: +```bash +pip install deepmd-kit[cpu] +``` + +[LAMMPS module](../third-party/lammps-command.md) is only provided on Linux and macOS. To enable it, add `lmp` to extras: +```bash +pip install deepmd-kit[gpu,lmp] +``` +MPICH is required for parallel running. + +It is suggested to install the package into an isolated environment. +The supported platform includes Linux x86-64 and aarch64 with GNU C Library 2.28 or above, macOS x86-64, and Windows x86-64. +A specific version of TensorFlow which is compatible with DeePMD-kit will be also installed. + +:::{Warning} +If your platform is not supported, or want to build against the installed TensorFlow, or want to enable ROCM support, please [build from source](install-from-source.md). +::: diff --git a/doc/install/install-from-source.md b/doc/install/install-from-source.md index 81a7520653..eb318b5c43 100644 --- a/doc/install/install-from-source.md +++ b/doc/install/install-from-source.md @@ -1,6 +1,6 @@ # Install from source code -Please follow our [github](https://github.com/deepmodeling/deepmd-kit) webpage to download the [latest released version](https://github.com/deepmodeling/deepmd-kit/tree/master) and [development version](https://github.com/deepmodeling/deepmd-kit/tree/devel). +Please follow our [GitHub](https://github.com/deepmodeling/deepmd-kit) webpage to download the [latest released version](https://github.com/deepmodeling/deepmd-kit/tree/master) and [development version](https://github.com/deepmodeling/deepmd-kit/tree/devel). Or get the DeePMD-kit source code by `git clone` ```bash @@ -9,27 +9,27 @@ git clone --recursive https://github.com/deepmodeling/deepmd-kit.git deepmd-kit ``` The `--recursive` option clones all [submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) needed by DeePMD-kit. -For convenience, you may want to record the location of source to a variable, saying `deepmd_source_dir` by +For convenience, you may want to record the location of the source to a variable, saying `deepmd_source_dir` by ```bash cd deepmd-kit deepmd_source_dir=`pwd` ``` ## Install the python interface -### Install the Tensorflow's python interface +### Install Tensorflow's python interface First, check the python version on your machine ```bash python --version ``` -We follow the virtual environment approach to install TensorFlow's Python interface. The full instruction can be found on the official [TensorFlow website](https://www.tensorflow.org/install/pip). TensorFlow 1.8 or later is supported. Now we assume that the Python interface will be installed to virtual environment directory `$tensorflow_venv` +We follow the virtual environment approach to install TensorFlow's Python interface. The full instruction can be found on the official [TensorFlow website](https://www.tensorflow.org/install/pip). TensorFlow 1.8 or later is supported. Now we assume that the Python interface will be installed to the virtual environment directory `$tensorflow_venv` ```bash virtualenv -p python3 $tensorflow_venv source $tensorflow_venv/bin/activate pip install --upgrade pip pip install --upgrade tensorflow ``` -It is important that everytime a new shell is started and one wants to use `DeePMD-kit`, the virtual environment should be activated by +It is important that every time a new shell is started and one wants to use `DeePMD-kit`, the virtual environment should be activated by ```bash source $tensorflow_venv/bin/activate ``` @@ -37,11 +37,11 @@ if one wants to skip out of the virtual environment, he/she can do ```bash deactivate ``` -If one has multiple python interpreters named like python3.x, it can be specified by, for example +If one has multiple python interpreters named something like python3.x, it can be specified by, for example ```bash virtualenv -p python3.7 $tensorflow_venv ``` -If one does not need the GPU support of deepmd-kit and is concerned about package size, the CPU-only version of TensorFlow should be installed by +If one does not need the GPU support of DeePMD-kit and is concerned about package size, the CPU-only version of TensorFlow should be installed by ```bash pip install --upgrade tensorflow-cpu ``` @@ -49,9 +49,9 @@ To verify the installation, run ```bash python -c "import tensorflow as tf;print(tf.reduce_sum(tf.random.normal([1000, 1000])))" ``` -One should remember to activate the virtual environment every time he/she uses deepmd-kit. +One should remember to activate the virtual environment every time he/she uses DeePMD-kit. -One can also [build TensorFlow Python interface from source](https://www.tensorflow.org/install/source) for custom hardward optimization, such as CUDA, ROCM, or OneDNN support. +One can also [build the TensorFlow Python interface from source](https://www.tensorflow.org/install/source) for custom hardware optimization, such as CUDA, ROCM, or OneDNN support. ### Install the DeePMD-kit's python interface @@ -61,7 +61,7 @@ Check the compiler version on your machine gcc --version ``` -The compiler gcc 4.8 or later is supported in the DeePMD-kit. Note that TensorFlow may have specific requirement of the compiler version. It is recommended to use the same compiler version as TensorFlow, which can be printed by `python -c "import tensorflow;print(tensorflow.version.COMPILER_VERSION)"`. +The compiler GCC 4.8 or later is supported in the DeePMD-kit. Note that TensorFlow may have specific requirements for the compiler version. It is recommended to use the same compiler version as TensorFlow, which can be printed by `python -c "import tensorflow;print(tensorflow.version.COMPILER_VERSION)"`. Execute ```bash @@ -76,8 +76,10 @@ One may set the following environment variables before executing `pip`: | DP_VARIANT | `cpu`, `cuda`, `rocm` | `cpu` | Build CPU variant or GPU variant with CUDA or ROCM support. | | CUDA_TOOLKIT_ROOT_DIR | Path | Detected automatically | The path to the CUDA toolkit directory. CUDA 7.0 or later is supported. NVCC is required. | | ROCM_ROOT | Path | Detected automatically | The path to the ROCM toolkit directory. | +| TENSORFLOW_ROOT | Path | Detected automatically | The path to TensorFlow Python library. By default the installer only finds TensorFlow under user site-package directory (`site.getusersitepackages()`) or system site-package directory (`sysconfig.get_path("purelib")`) due to limitation of [PEP-517](https://peps.python.org/pep-0517/). If not found, the latest TensorFlow (or the environment variable `TENSORFLOW_VERSION` if given) from PyPI will be built against.| +| DP_ENABLE_NATIVE_OPTIMIZATION | 0, 1 | 0 | Enable compilation optimization for the native machine's CPU type. Do not enable it if generated code will run on different CPUs. | -To test the installation, one should firstly jump out of the source directory +To test the installation, one should first jump out of the source directory ``` cd /some/other/workspace ``` @@ -104,13 +106,13 @@ Valid subcommands: ### Install horovod and mpi4py -[Horovod](https://github.com/horovod/horovod) and [mpi4py](https://github.com/mpi4py/mpi4py) is used for parallel training. For better performance on GPU, please follow tuning steps in [Horovod on GPU](https://github.com/horovod/horovod/blob/master/docs/gpus.rst). +[Horovod](https://github.com/horovod/horovod) and [mpi4py](https://github.com/mpi4py/mpi4py) are used for parallel training. For better performance on GPU, please follow the tuning steps in [Horovod on GPU](https://github.com/horovod/horovod/blob/master/docs/gpus.rst). ```bash # With GPU, prefer NCCL as a communicator. HOROVOD_WITHOUT_GLOO=1 HOROVOD_WITH_TENSORFLOW=1 HOROVOD_GPU_OPERATIONS=NCCL HOROVOD_NCCL_HOME=/path/to/nccl pip install horovod mpi4py ``` -If your work in CPU environment, please prepare runtime as below: +If your work in a CPU environment, please prepare runtime as below: ```bash # By default, MPI is used as communicator. HOROVOD_WITHOUT_GLOO=1 HOROVOD_WITH_TENSORFLOW=1 pip install horovod mpi4py @@ -140,33 +142,33 @@ Available Tensor Operations: [X] Gloo ``` -From version 2.0.1, Horovod and mpi4py with MPICH support is shipped with the installer. +From version 2.0.1, Horovod and mpi4py with MPICH support are shipped with the installer. -If you don't install horovod, DeePMD-kit will fall back to serial mode. +If you don't install Horovod, DeePMD-kit will fall back to serial mode. ## Install the C++ interface If one does not need to use DeePMD-kit with Lammps or I-Pi, then the python interface installed in the previous section does everything and he/she can safely skip this section. -### Install the Tensorflow's C++ interface +### Install Tensorflow's C++ interface -The C++ interface of DeePMD-kit was tested with compiler gcc >= 4.8. It is noticed that the I-Pi support is only compiled with gcc >= 4.8. Note that TensorFlow may have specific requirement of the compiler version. +The C++ interface of DeePMD-kit was tested with compiler GCC >= 4.8. It is noticed that the I-Pi support is only compiled with GCC >= 4.8. Note that TensorFlow may have specific requirements for the compiler version. -First the C++ interface of Tensorflow should be installed. It is noted that the version of Tensorflow should be consistent with the python interface. You may follow [the instruction](install-tf.2.8.md) or run the script `$deepmd_source_dir/source/install/build_tf.py` to install the corresponding C++ interface. +First, the C++ interface of Tensorflow should be installed. It is noted that the version of Tensorflow should be consistent with the python interface. You may follow [the instruction](install-tf.2.8.md) or run the script `$deepmd_source_dir/source/install/build_tf.py` to install the corresponding C++ interface. -### Install the DeePMD-kit's C++ interface +### Install DeePMD-kit's C++ interface -Now go to the source code directory of DeePMD-kit and make a build place. +Now go to the source code directory of DeePMD-kit and make a building place. ```bash cd $deepmd_source_dir/source mkdir build cd build ``` -I assume you want to install DeePMD-kit into path `$deepmd_root`, then execute cmake +I assume you want to install DeePMD-kit into path `$deepmd_root`, then execute CMake ```bash cmake -DTENSORFLOW_ROOT=$tensorflow_root -DCMAKE_INSTALL_PREFIX=$deepmd_root .. ``` -where the variable `tensorflow_root` stores the location where the TensorFlow's C++ interface is installed. +where the variable `tensorflow_root` stores the location where TensorFlow's C++ interface is installed. One may add the following arguments to `cmake`: @@ -177,18 +179,17 @@ One may add the following arguments to `cmake`: | -DUSE_CUDA_TOOLKIT=<value> | `TRUE` or `FALSE` | `FALSE` | If `TRUE`, Build GPU support with CUDA toolkit. | | -DCUDA_TOOLKIT_ROOT_DIR=<value> | Path | Detected automatically | The path to the CUDA toolkit directory. CUDA 7.0 or later is supported. NVCC is required. | | -DUSE_ROCM_TOOLKIT=<value> | `TRUE` or `FALSE` | `FALSE` | If `TRUE`, Build GPU support with ROCM toolkit. | -| -DROCM_ROOT=<value> | Path | Detected automatically | The path to the ROCM toolkit directory. | -| -DLAMMPS_VERSION_NUMBER=<value> | Number | `20220723` | Only neccessary for LAMMPS built-in mode. The version number of LAMMPS (yyyymmdd). LAMMPS 29Oct2020 (20201029) or later is supported. | +| -DCMAKE_HIP_COMPILER_ROCM_ROOT=<value> | Path | Detected automatically | The path to the ROCM toolkit directory. | | -DLAMMPS_SOURCE_ROOT=<value> | Path | - | Only neccessary for LAMMPS plugin mode. The path to the [LAMMPS source code](install-lammps.md). LAMMPS 8Apr2021 or later is supported. If not assigned, the plugin mode will not be enabled. | | -DUSE_TF_PYTHON_LIBS=<value> | `TRUE` or `FALSE` | `FALSE` | If `TRUE`, Build C++ interface with TensorFlow's Python libraries(TensorFlow's Python Interface is required). And there's no need for building TensorFlow's C++ interface.| +| -DENABLE_NATIVE_OPTIMIZATION | `TRUE` or `FALSE` | `FALSE` | Enable compilation optimization for the native machine's CPU type. Do not enable it if generated code will run on different CPUs. | - -If the cmake has been executed successfully, then run the following make commands to build the package: +If the CMake has been executed successfully, then run the following make commands to build the package: ```bash make -j4 make install ``` -The option `-j4` means using 4 processes in parallel. You may want to use a different number according to your hardware. +Option `-j4` means using 4 processes in parallel. You may want to use a different number according to your hardware. If everything works fine, you will have the following executable and libraries installed in `$deepmd_root/bin` and `$deepmd_root/lib` ```bash diff --git a/doc/install/install-gromacs.md b/doc/install/install-gromacs.md index cf4a9356f4..489c263239 100644 --- a/doc/install/install-gromacs.md +++ b/doc/install/install-gromacs.md @@ -3,19 +3,19 @@ Before following this section, [DeePMD-kit C++ interface](install-from-source.md) should have be installed. ## Patch source code of GROMACS -Download source code of a supported gromacs version (2020.2) from https://manual.gromacs.org/2020.2/download.html. Run the following command: +Download the source code of a supported GROMACS version (2020.2) from https://manual.gromacs.org/2020.2/download.html. Run the following command: ```bash export PATH=$PATH:$deepmd_kit_root/bin dp_gmx_patch -d $gromacs_root -v $version -p ``` -where `deepmd_kit_root` is the directory where the latest version of deepmd-kit is installed, and `gromacs_root` refers to the source code directory of gromacs. And `version` represents the version of gromacs, **only support 2020.2 now**. If attempting to patch another version of gromacs you will still need to set `version` to `2020.2` as this is the only supported version, we cannot guarantee that patching other versions of gromacs will work. +where `deepmd_kit_root` is the directory where the latest version of DeePMD-kit is installed, and `gromacs_root` refers to the source code directory of GROMACS. And `version` represents the version of GROMACS, where **only 2020.2 is supported now**. If attempting to patch another version of GROMACS you will still need to set `version` to `2020.2` as this is the only supported version, we cannot guarantee that patching other versions of GROMACS will work. ## Compile GROMACS with deepmd-kit -The C++ interface of `deepmd-kit 2.x` and `tensorflow 2.x` are required. And be aware that only deepmd-kit with **high precision** is supported now, since we cannot ensure single precision is enough for a GROMACS simulation. Here is a sample compile script: +The C++ interface of `Deepmd-kit 2.x` and `TensorFlow 2.x` are required. And be aware that only DeePMD-kit with **high precision** is supported now since we cannot ensure single precision is enough for a GROMACS simulation. Here is a sample compile script: ```bash #!/bin/bash export CC=/usr/bin/gcc diff --git a/doc/install/install-ipi.md b/doc/install/install-ipi.md index 9e29b3cc30..cabbf0fa62 100644 --- a/doc/install/install-ipi.md +++ b/doc/install/install-ipi.md @@ -1,5 +1,5 @@ # Install i-PI -The i-PI works in a client-server model. The i-PI provides the server for integrating the replica positions of atoms, while the DeePMD-kit provides a client named `dp_ipi` that computes the interactions (including energy, force and virial). The server and client communicate via the Unix domain socket or the Internet socket. Full documentation for i-PI can be found [here](http://ipi-code.org/). The source code and a complete installation guide for i-PI can be found [here](https://github.com/i-pi/i-pi). +The i-PI works in a client-server model. The i-PI provides the server for integrating the replica positions of atoms, while the DeePMD-kit provides a client named `dp_ipi` that computes the interactions (including energy, forces and virials). The server and client communicate via the Unix domain socket or the Internet socket. Full documentation for i-PI can be found [here](http://ipi-code.org/). The source code and a complete installation guide for i-PI can be found [here](https://github.com/i-pi/i-pi). To use i-PI with already existing drivers, install and update using Pip: ```bash pip install -U i-PI diff --git a/doc/install/install-lammps.md b/doc/install/install-lammps.md index 1903ba5ad2..0be0b1ddb1 100644 --- a/doc/install/install-lammps.md +++ b/doc/install/install-lammps.md @@ -5,23 +5,24 @@ There are two ways to install LAMMPS: the built-in mode and the plugin mode. The ## Install LAMMPS's DeePMD-kit module (built-in mode) Before following this section, [DeePMD-kit C++ interface](install-from-source.md) should have be installed. -DeePMD-kit provides a module for running MD simulation with LAMMPS. Now make the DeePMD-kit module for LAMMPS. +DeePMD-kit provides a module for running MD simulations with LAMMPS. Now make the DeePMD-kit module for LAMMPS. ```bash cd $deepmd_source_dir/source/build make lammps ``` -DeePMD-kit will generate a module called `USER-DEEPMD` in the `build` directory. If you need the low precision version, move `env_low.sh` to `env.sh` in the directory. Now download the LAMMPS code, and uncompress it. The LAMMPS version should be the same as what is specified as the CMAKE argument `LAMMPS_VERSION_NUMBER`. +DeePMD-kit will generate a module called `USER-DEEPMD` in the `build` directory. If you need the low-precision version, move `env_low.sh` to `env.sh` in the directory. Now download the LAMMPS code, and uncompress it. ```bash cd /some/workspace -wget https://github.com/lammps/lammps/archive/stable_23Jun2022_update1.tar.gz -tar xf stable_23Jun2022_update1.tar.gz +wget https://github.com/lammps/lammps/archive/stable_23Jun2022_update2.tar.gz +tar xf stable_23Jun2022_update2.tar.gz ``` -The source code of LAMMPS is stored in directory `lammps-stable_23Jun2022_update1`. Now go into the LAMMPS code and copy the DeePMD-kit module like this +The source code of LAMMPS is stored in the directory `lammps-stable_23Jun2022_update2`. Now go into the LAMMPS code and copy the DeePMD-kit module like this ```bash -cd lammps-stable_23Jun2022_update1/src/ +cd lammps-stable_23Jun2022_update2/src/ cp -r $deepmd_source_dir/source/build/USER-DEEPMD . make yes-kspace +make yes-extra-fix make yes-user-deepmd ``` You can enable any other package you want. Now build LAMMPS @@ -34,7 +35,7 @@ If everything works fine, you will end up with an executable `lmp_mpi`. ./lmp_mpi -h ``` -The DeePMD-kit module can be removed from LAMMPS source code by +The DeePMD-kit module can be removed from the LAMMPS source code by ```bash make no-user-deepmd ``` @@ -45,17 +46,17 @@ Starting from `8Apr2021`, LAMMPS also provides a plugin mode, allowing one to bu Now download the LAMMPS code (`8Apr2021` or later), and uncompress it: ```bash cd /some/workspace -wget https://github.com/lammps/lammps/archive/stable_23Jun2022_update1.tar.gz -tar xf stable_23Jun2022_update1.tar.gz +wget https://github.com/lammps/lammps/archive/stable_23Jun2022_update2.tar.gz +tar xf stable_23Jun2022_update2.tar.gz ``` -The source code of LAMMPS is stored in directory `lammps-stable_23Jun2022_update1`. The directory of the source code should be specified as the CMAKE argument `LAMMPS_SOURCE_ROOT` during installation of the DeePMD-kit C++ interface. Now go into the LAMMPS directory and create a directory called `build` +The source code of LAMMPS is stored in the directory `lammps-stable_23Jun2022_update2`. The directory of the source code should be specified as the CMAKE argument `LAMMPS_SOURCE_ROOT` during installation of the DeePMD-kit C++ interface. Now go into the LAMMPS directory and create a directory called `build` ```bash -mkdir -p lammps-stable_23Jun2022_update1/build/ -cd lammps-stable_23Jun2022_update1/build/ +mkdir -p lammps-stable_23Jun2022_update2/build/ +cd lammps-stable_23Jun2022_update2/build/ ``` -Now build LAMMPS. Note that `PLUGIN` and `KSPACE` package must be enabled, and `BUILD_SHARED_LIBS` must be set to `yes`. You can install any other package you want. +Now build LAMMPS. Note that `PLUGIN` and `KSPACE` packages must be enabled, and `BUILD_SHARED_LIBS` must be set to `yes`. You can install any other package you want. ```bash cmake -D PKG_PLUGIN=ON -D PKG_KSPACE=ON -D LAMMPS_INSTALL_RPATH=ON -D BUILD_SHARED_LIBS=yes -D CMAKE_INSTALL_PREFIX=${deepmd_root} -D CMAKE_INSTALL_LIBDIR=lib -D CMAKE_INSTALL_FULL_LIBDIR=${deepmd_root}/lib ../cmake make -j4 @@ -66,3 +67,11 @@ If everything works fine, you will end up with an executable `${deepmd_root}/bin ```bash ${deepmd_root}/bin/lmp -h ``` + +:::{note} +If `${tensorflow_root}` or `${deepmd_root}` is different from the prefix of LAMMPS, you need to append the library path to [`RUNPATH`](https://man7.org/linux/man-pages/man8/ld.so.8.html) of `liblammps.so`. For example, + +```sh +patchelf --set-rpath "${tensorflow_root}/lib" liblammps.so +``` +::: diff --git a/doc/install/install-tf.1.12.md b/doc/install/install-tf.1.12.md index b54582d1a7..7d18529e5b 100644 --- a/doc/install/install-tf.1.12.md +++ b/doc/install/install-tf.1.12.md @@ -1,5 +1,5 @@ -# Install tensorflow's C++ interface -The tensorflow's C++ interface will be compiled from the source code. Firstly one installs bazel. It is highly recommended that the bazel version 0.15.0 is used. A full instruction of bazel installation can be found [here](https://docs.bazel.build/versions/master/install.html). +# Install TensorFlow's C++ interface +The TensorFlow's C++ interface will be compiled from the source code. Firstly one installs bazel. It is highly recommended that the bazel version 0.15.0 is used. A full instruction of bazel installation can be found [here](https://docs.bazel.build/versions/master/install.html). ```bash cd /some/workspace wget https://github.com/bazelbuild/bazel/releases/download/0.15.0/bazel-0.15.0-dist.zip @@ -10,34 +10,34 @@ unzip ../bazel-0.15.0-dist.zip export PATH=`pwd`/output:$PATH ``` -Firstly get the source code of the tensorflow +Firstly get the source code of the TensorFlow ```bash cd /some/workspace git clone https://github.com/tensorflow/tensorflow tensorflow -b v1.12.0 --depth=1 cd tensorflow ``` -DeePMD-kit is compiled by cmake, so we need to compile and integrate tensorflow with cmake projects. The rest of this section basically follows [the instruction provided by Tuatini](http://tuatini.me/building-tensorflow-as-a-standalone-project/). Now execute +DeePMD-kit is compiled by CMake, so we need to compile and integrate TensorFlow with CMake projects. The rest of this section follows [the instruction provided by Tuatini](http://tuatini.me/building-tensorflow-as-a-standalone-project/). Now execute ```bash ./configure ``` -You will answer a list of questions that help configure the building of tensorflow. It is recommended to build for Python3. You may want to answer the question like this (please replace `$tensorflow_venv` by the virtual environment directory): +You will answer a list of questions that help configure the building of TensorFlow. It is recommended to build for Python3. You may want to answer the question like this (please replace `$tensorflow_venv` with the virtual environment directory): ```bash Please specify the location of python. [Default is $tensorflow_venv/bin/python]: ``` The library path for Python should be set accordingly. -Now build the shared library of tensorflow: +Now build the shared library of TensorFlow: ```bash bazel build -c opt --verbose_failures //tensorflow:libtensorflow_cc.so ``` -You may want to add options `--copt=-msse4.2`, `--copt=-mavx`, `--copt=-mavx2` and `--copt=-mfma` to enable SSE4.2, AVX, AVX2 and FMA SIMD accelerations, respectively. It is noted that these options should be chosen according to the CPU architecture. If the RAM becomes an issue of your machine, you may limit the RAM usage by using `--local_resources 2048,.5,1.0`. +You may want to add options `--copt=-msse4.2`, `--copt=-mavx`, `--copt=-mavx2` and `--copt=-mfma` to enable SSE4.2, AVX, AVX2 and FMA SIMD accelerations, respectively. It is noted that these options should be chosen according to the CPU architecture. If the RAM becomes an issue for your machine, you may limit the RAM usage by using `--local_resources 2048,.5,1.0`. -Now I assume you want to install tensorflow in directory `$tensorflow_root`. Create the directory if it does not exists +Now I assume you want to install TensorFlow in directory `$tensorflow_root`. Create the directory if it does not exist ```bash mkdir -p $tensorflow_root ``` -Before moving on, we need to compile the dependencies of tensorflow, including Protobuf, Eigen, nsync and absl. Firstly, protobuf +Before moving on, we need to compile the dependencies of TensorFlow, including Protobuf, Eigen, nsync and absl. Firstly, protobuf ```bash mkdir /tmp/proto sed -i 's;PROTOBUF_URL=.*;PROTOBUF_URL=\"https://mirror.bazel.build/github.com/google/protobuf/archive/v3.6.0.tar.gz\";g' tensorflow/contrib/makefile/download_dependencies.sh diff --git a/doc/install/install-tf.1.14-gpu.md b/doc/install/install-tf.1.14-gpu.md index 066f51b99d..ffaf0eb262 100644 --- a/doc/install/install-tf.1.14-gpu.md +++ b/doc/install/install-tf.1.14-gpu.md @@ -1,5 +1,5 @@ -# Install tensorflow-gpu's C++ interface -The tensorflow's C++ interface will be compiled from the source code. Firstly one installs bazel. It is highly recommended that the bazel version 0.24.1 is used. A full instruction of bazel installation can be found [here](https://docs.bazel.build/versions/master/install.html). +# Install TensorFlow-GPU's C++ interface +TensorFlow's C++ interface will be compiled from the source code. Firstly one installs Bazel. It is highly recommended that the Bazel version 0.24.1 is used. Full instructions on Bazel installation can be found [here](https://docs.bazel.build/versions/master/install.html). ```bash cd /some/workspace wget https://github.com/bazelbuild/bazel/releases/download/0.24.1/bazel-0.24.1-dist.zip @@ -10,16 +10,16 @@ unzip ../bazel-0.24.1-dist.zip export PATH=`pwd`/output:$PATH ``` -Firstly get the source code of the tensorflow +Firstly get the source code of the TensorFlow ```bash cd /some/workspace git clone https://github.com/tensorflow/tensorflow tensorflow -b v1.14.0 --depth=1 cd tensorflow ``` -DeePMD-kit is compiled by cmake, so we need to compile and integrate tensorflow with cmake projects. The rest of this section basically follows [the instruction provided by Tuatini](http://tuatini.me/building-tensorflow-as-a-standalone-project/). Now execute +DeePMD-kit is compiled by CMake, so we need to compile and integrate TensorFlow with CMake projects. The rest of this section follows [the instruction provided by Tuatini](http://tuatini.me/building-tensorflow-as-a-standalone-project/). Now execute -You will answer a list of questions that help configure the building of tensorflow. It is recommended to build for Python3. You may want to answer the question like this (please replace `$tensorflow_venv` by the virtual environment directory): +You will answer a list of questions that help configure the building of TensorFlow. It is recommended to build for Python3. You may want to answer the question like this (please replace `$tensorflow_venv` with the virtual environment directory): ```bash ./configure Please specify the location of python. [Default is xxx]: @@ -92,17 +92,17 @@ Configuration finished The library path for Python should be set accordingly. -Now build the shared library of tensorflow: +Now build the shared library of TensorFlow: ```bash bazel build -c opt --verbose_failures //tensorflow:libtensorflow_cc.so ``` -You may want to add options `--copt=-msse4.2`, `--copt=-mavx`, `--copt=-mavx2` and `--copt=-mfma` to enable SSE4.2, AVX, AVX2 and FMA SIMD accelerations, respectively. It is noted that these options should be chosen according to the CPU architecture. If the RAM becomes an issue of your machine, you may limit the RAM usage by using `--local_resources 2048,.5,1.0`. +You may want to add options `--copt=-msse4.2`, `--copt=-mavx`, `--copt=-mavx2` and `--copt=-mfma` to enable SSE4.2, AVX, AVX2 and FMA SIMD accelerations, respectively. It is noted that these options should be chosen according to the CPU architecture. If the RAM becomes an issue for your machine, you may limit the RAM usage by using `--local_resources 2048,.5,1.0`. -Now I assume you want to install tensorflow in directory `$tensorflow_root`. Create the directory if it does not exists +Now I assume you want to install TensorFlow in directory `$tensorflow_root`. Create the directory if it does not exist ```bash mkdir -p $tensorflow_root ``` -Now, copy the libraries to the tensorflow's installation directory: +Now, copy the libraries to the TensorFlow's installation directory: ```bash mkdir $tensorflow_root/lib cp -d bazel-bin/tensorflow/libtensorflow_cc.so* $tensorflow_root/lib/ @@ -131,7 +131,7 @@ find . -name "*.cc" -type f -delete ```bash git: unknown command -C ... ``` -This may be your git version issue, because low version of git does not support this command. Upgrading your git maybe helpful. +This may be your git version issue because the low version of Git does not support this command. Upgrading your Git may be helpful. ```bash CMake Error: The following variables are used in this project, but they are set to NOTFOUND. @@ -139,11 +139,11 @@ Please set them or make sure they are set and tested correctly in the CMake file FFTW_LIB (ADVANCED) linked by target "FFTW" in directory xxx ``` -Currently, when building eigen package, you can delete the FFTW in the cmake file. +Currently, when building the Eigen package, you can delete the FFTW in the CMake file. ```bash fatal error: absl/numeric/int128_have_intrinsic.inc: No such file or directory ``` -Basicly, you could build an empty file named "int128_have_intrinsic.inc" at the same directory of "int128.h". +Basically, you could build an empty file named "int128_have_intrinsic.inc" in the same directory of "int128.h". diff --git a/doc/install/install-tf.1.8.md b/doc/install/install-tf.1.8.md index 8c7902f044..6247edf087 100644 --- a/doc/install/install-tf.1.8.md +++ b/doc/install/install-tf.1.8.md @@ -10,34 +10,34 @@ unzip ../bazel-0.10.0-dist.zip export PATH=`pwd`/output:$PATH ``` -Firstly get the source code of the tensorflow +Firstly get the source code of the TensorFlow ```bash cd /some/workspace git clone https://github.com/tensorflow/tensorflow tensorflow -b v1.8.0 --depth=1 cd tensorflow ``` -DeePMD-kit is compiled by cmake, so we need to compile and integrate tensorflow with cmake projects. The rest of this section basically follows [the instruction provided by Tuatini](http://tuatini.me/building-tensorflow-as-a-standalone-project/). Now execute +DeePMD-kit is compiled by CMake, so we need to compile and integrate TensorFlow with CMake projects. The rest of this section basically follows [the instruction provided by Tuatini](http://tuatini.me/building-tensorflow-as-a-standalone-project/). Now execute ```bash ./configure ``` -You will answer a list of questions that help configure the building of tensorflow. It is recommended to build for Python3. You may want to answer the question like this (please replace `$tensorflow_venv` by the virtual environment directory): +You will answer a list of questions that help configure the building of TensorFlow. It is recommended to build for Python3. You may want to answer the question like this (please replace `$tensorflow_venv` with the virtual environment directory): ```bash Please specify the location of python. [Default is $tensorflow_venv/bin/python]: ``` The library path for Python should be set accordingly. -Now build the shared library of tensorflow: +Now build the shared library of TensorFlow: ```bash bazel build -c opt --verbose_failures //tensorflow:libtensorflow_cc.so ``` You may want to add options `--copt=-msse4.2`, `--copt=-mavx`, `--copt=-mavx2` and `--copt=-mfma` to enable SSE4.2, AVX, AVX2 and FMA SIMD accelerations, respectively. It is noted that these options should be chosen according to the CPU architecture. If the RAM becomes an issue of your machine, you may limit the RAM usage by using `--local_resources 2048,.5,1.0`. -Now I assume you want to install tensorflow in directory `$tensorflow_root`. Create the directory if it does not exists +Now I assume you want to install TensorFlow in directory `$tensorflow_root`. Create the directory if it does not exist ```bash mkdir -p $tensorflow_root ``` -Before moving on, we need to compile the dependencies of tensorflow, including Protobuf, Eigen and nsync. Firstly, protobuf +Before moving on, we need to compile the dependencies of TensorFlow, including Protobuf, Eigen and nsync. Firstly, protobuf ```bash mkdir /tmp/proto tensorflow/contrib/makefile/download_dependencies.sh @@ -67,7 +67,7 @@ make make install cd ../../../../../.. ``` -Now, copy the libraries to the tensorflow's installation directory: +Now, copy the libraries to the TensorFlow's installation directory: ```bash mkdir $tensorflow_root/lib cp bazel-bin/tensorflow/libtensorflow_cc.so $tensorflow_root/lib/ diff --git a/doc/install/install-tf.2.8.md b/doc/install/install-tf.2.8.md index fec90446f9..f6fa082eaf 100644 --- a/doc/install/install-tf.2.8.md +++ b/doc/install/install-tf.2.8.md @@ -1,5 +1,5 @@ # Install TensorFlow's C++ interface -The tensorflow's C++ interface will be compiled from the source code. Firstly one installs bazel. [bazelisk](https://github.com/bazelbuild/bazelisk) can be lanuched to use [bazel](https://github.com/bazelbuild/bazel). +TensorFlow's C++ interface will be compiled from the source code. Firstly one installs Bazel. [bazelisk](https://github.com/bazelbuild/bazelisk) can be lanuched to use [bazel](https://github.com/bazelbuild/bazel). ```bash wget https://github.com/bazelbuild/bazelisk/releases/download/v1.11.0/bazelisk-linux-amd64 -O /some/workspace/bazel/bin/bazel @@ -73,17 +73,17 @@ Configuration finished The library path for Python should be set accordingly. -Now build the shared library of tensorflow: +Now build the shared library of TensorFlow: ```bash bazel build -c opt --verbose_failures //tensorflow:libtensorflow_cc.so ``` -You may want to add options `--copt=-msse4.2`, `--copt=-mavx`, `--copt=-mavx2` and `--copt=-mfma` to enable SSE4.2, AVX, AVX2 and FMA SIMD accelerations, respectively. It is noted that these options should be chosen according to the CPU architecture. If the RAM becomes an issue of your machine, you may limit the RAM usage by using `--local_resources 2048,.5,1.0`. If you want to enable [oneDNN optimization](https://www.oneapi.io/blog/tensorflow-and-onednn-in-partnership/), add `--config=mkl`. +You may want to add options `--copt=-msse4.2`, `--copt=-mavx`, `--copt=-mavx2` and `--copt=-mfma` to enable SSE4.2, AVX, AVX2 and FMA SIMD accelerations, respectively. It is noted that these options should be chosen according to the CPU architecture. If the RAM becomes an issue for your machine, you may limit the RAM usage by using `--local_resources 2048,.5,1.0`. If you want to enable [oneDNN optimization](https://www.oneapi.io/blog/tensorflow-and-onednn-in-partnership/), add `--config=mkl`. Now I assume you want to install TensorFlow in directory `$tensorflow_root`. Create the directory if it does not exist ```bash mkdir -p $tensorflow_root ``` -Now, copy the libraries to the tensorflow's installation directory: +Now, copy the libraries to the TensorFlow's installation directory: ```bash mkdir -p $tensorflow_root/lib cp -d bazel-bin/tensorflow/libtensorflow_cc.so* $tensorflow_root/lib/ @@ -112,4 +112,4 @@ cp -d bazel-out/k8-opt/bin/external/llvm_openmp/libiomp5.so $tensorflow_root/lib ```bash git: unknown command -C ... ``` -This may be an issue with your git version issue. Early versions of git do not support this command, in this case upgrading your git to a newer version may resolve any issues. +This may be an issue with your Git version issue. Early versions of Git do not support this command, in this case upgrading your Git to a newer version may resolve any issues. diff --git a/doc/model/dplr.md b/doc/model/dplr.md index 4661cbcdf7..bb6ea66084 100644 --- a/doc/model/dplr.md +++ b/doc/model/dplr.md @@ -4,11 +4,11 @@ Notice: **The interfaces of DPLR are not stable and subject to change** The method of DPLR is described in [this paper][1]. One is recommended to read the paper before using the DPLR. -In the following, we take the DPLR model for example to introduce the training and LAMMPS simulation with the DPLR model. The DPLR model is training in two steps. +In the following, we take the DPLR model for example to introduce the training and LAMMPS simulation with the DPLR model. The DPLR model is trained in two steps. ## Train a deep Wannier model for Wannier centroids -We use the deep Wannier model (DW) to represent the relative position of the Wannier centroid (WC) with the atom to which it is associated. One may consult the introduction of the [dipole model](train-fitting-tensor.md) for a detailed introduction. An example input `wc.json` and a small dataset `data` for tutorial purposes can be found in +We use the deep Wannier model (DW) to represent the relative position of the Wannier centroid (WC) with the atom with which it is associated. One may consult the introduction of the [dipole model](train-fitting-tensor.md) for a detailed introduction. An example input `wc.json` and a small dataset `data` for tutorial purposes can be found in ```bash $deepmd_source_dir/examples/water/dplr/train/ ``` @@ -22,7 +22,7 @@ Two settings make the training input script different from an energy training in "seed": 1 }, ``` -The type of fitting is set to {ref}`dipole `. The dipole is associate to type 0 atoms (oxygens), by the setting `"dipole_type": [0]`. What we trained is the displacement of the WC from the corresponding oxygen atom. It shares the same training input as atomic dipole because both are 3-dimensional vectors defined on atoms. +The type of fitting is set to {ref}`dipole `. The dipole is associated with type 0 atoms (oxygens), by the setting `"dipole_type": [0]`. What we trained is the displacement of the WC from the corresponding oxygen atom. It shares the same training input as the atomic dipole because both are 3-dimensional vectors defined on atoms. The loss section is provided as follows ```json "loss": { @@ -31,7 +31,7 @@ The loss section is provided as follows "pref_atomic": 1.0 }, ``` -so that the atomic dipole is trained as labels. Note that the numpy compressed file `atomic_dipole.npy` should be provided in each dataset. +so that the atomic dipole is trained as labels. Note that the NumPy compressed file `atomic_dipole.npy` should be provided in each dataset. The training and freezing can be started from the example directory by ```bash @@ -51,7 +51,7 @@ The training of the DPLR model is very similar to the standard short-range DP mo "ewald_beta": 0.40 }, ``` -The {ref}`model_name ` specifies which DW model is used to predict the position of WCs. {ref}`model_charge_map ` gives the amount of charge assigned to WCs. {ref}`sys_charge_map ` provides the nuclear charge of oxygen (type 0) and hydrogen (type 1) atoms. {ref}`ewald_beta ` (unit $\text{Å}^{-1}$) gives the spread parameter controls the spread of Gaussian charges, and {ref}`ewald_h ` (unit Å) assigns the grid size of Fourier transform. +The {ref}`model_name ` specifies which DW model is used to predict the position of WCs. {ref}`model_charge_map ` gives the amount of charge assigned to WCs. {ref}`sys_charge_map ` provides the nuclear charge of oxygen (type 0) and hydrogen (type 1) atoms. {ref}`ewald_beta ` (unit $\text{Å}^{-1}$) gives the spread parameter controls the spread of Gaussian charges, and {ref}`ewald_h ` (unit Å) assigns the grid size of Fourier transformation. The DPLR model can be trained and frozen by (from the example directory) ```bash dp train ener.json && dp freeze -o ener.pb @@ -61,12 +61,12 @@ dp train ener.json && dp freeze -o ener.pb In MD simulations, the long-range part of the DPLR is calculated by the LAMMPS `kspace` support. Then the long-range interaction is back-propagated to atoms by DeePMD-kit. This setup is commonly used in classical molecular dynamics simulations as the "virtual site". Unfortunately, LAMMPS does not natively support virtual sites, so we have to hack the LAMMPS code, which makes the input configuration and script a little wired. -An example of input configuration file and script can be found in +An example of an input configuration file and script can be found in ```bash $deepmd_source_dir/examples/water/dplr/lmp/ ``` -We use `atom_style full` for DPLR simulations. the coordinates of the WCs are explicitly written to the configuration file. Moreover, a virtual bond is established between the oxygens and the WCs to indicate they are associated together. The configuration file containing 128 H2O molecules is thus written as +We use `atom_style full` for DPLR simulations. the coordinates of the WCs are explicitly written in the configuration file. Moreover, a virtual bond is established between the oxygens and the WCs to indicate they are associated together. The configuration file containing 128 H2O molecules is thus written as ``` 512 atoms @@ -162,9 +162,9 @@ lmp -i in.lammps ``` If LAMMPS complains that no model file `ener.pb` exists, it can be copied from the training example directory. -The MD simulation lasts for only 20 steps. If one runs a longer simulation, it will blow up, because the model is trained with a very limited dataset for a very short training steps, thus is of poor quality. +The MD simulation lasts for only 20 steps. If one runs a longer simulation, it will blow up, because the model is trained with a very limited dataset for very short training steps, thus is of poor quality. -Another restriction should be noted is that the energies printed at the zero step is not correct. This is because at the zero step the position of the WC has not been updated with the DW model. The energies printed in later steps are correct. +Another restriction that should be noted is that the energies printed at the zero steps are not correct. This is because at the zero steps the position of the WC has not been updated with the DW model. The energies printed in later steps are correct. diff --git a/doc/model/overall.md b/doc/model/overall.md index fd043a162b..98b7745ad9 100644 --- a/doc/model/overall.md +++ b/doc/model/overall.md @@ -14,16 +14,16 @@ A model has two parts, a descriptor that maps atomic configuration to a set of s ``` The two subsections, {ref}`descriptor ` and {ref}`fitting_net `, define the descriptor and the fitting net, respectively. -The {ref}`type_map ` is optional, which provides the element names (but not necessarily same with the actual name of the element) of the corresponding atom types. A model for water, as in this example, has two kinds of atoms. The atom types are internally recorded as integers, e.g., `0` for oxygen and `1` for hydrogen here. A mapping from the atom type to their names is provided by {ref}`type_map `. +The {ref}`type_map ` is optional, which provides the element names (but not necessarily same as the actual name of the element) of the corresponding atom types. A water model, as in this example, has two kinds of atoms. The atom types are internally recorded as integers, e.g., `0` for oxygen and `1` for hydrogen here. A mapping from the atom type to their names is provided by {ref}`type_map `. DeePMD-kit implements the following descriptors: 1. [`se_e2_a`](train-se-e2-a.md): DeepPot-SE constructed from all information (both angular and radial) of atomic configurations. The embedding takes the distance between atoms as input. 2. [`se_e2_r`](train-se-e2-r.md): DeepPot-SE constructed from radial information of atomic configurations. The embedding takes the distance between atoms as input. 3. [`se_e3`](train-se-e3.md): DeepPot-SE constructed from all information (both angular and radial) of atomic configurations. The embedding takes angles between two neighboring atoms as input. -4. `loc_frame`: Defines a local frame at each atom, and the compute the descriptor as local coordinates under this frame. +4. `loc_frame`: Defines a local frame at each atom and compute the descriptor as local coordinates under this frame. 5. [`hybrid`](train-hybrid.md): Concate a list of descriptors to form a new descriptor. -The fitting of the following physical properties are supported +The fitting of the following physical properties is supported 1. [`ener`](train-energy.md): Fit the energy of the system. The force (derivative with atom positions) and the virial (derivative with the box tensor) can also be trained. 2. [`dipole`](train-fitting-tensor.md): The dipole moment. 3. [`polar`](train-fitting-tensor.md): The polarizability. diff --git a/doc/model/sel.md b/doc/model/sel.md index dce1b8f860..f4a3cf6c09 100644 --- a/doc/model/sel.md +++ b/doc/model/sel.md @@ -10,4 +10,4 @@ dp neighbor-stat -s data -r 6.0 -t O H ``` where `data` is the directory of data, `6.0` is the cutoff radius, and `O` and `H` is the type map. The program will give the `max_nbor_size`. For example, `max_nbor_size` of the water example is `[38, 72]`, meaning an atom may have 38 O neighbors and 72 H neighbors in the training data. -The `sel` should be set to a higher value than that of the training data, considering there may be some extreme geometries during MD simulations. As a result, we set to `[46, 92]` in the water example. +The `sel` should be set to a higher value than that of the training data, considering there may be some extreme geometries during MD simulations. As a result, we set `sel` to `[46, 92]` in the water example. diff --git a/doc/model/train-energy.md b/doc/model/train-energy.md index 20f173bc9d..a56f03fec4 100644 --- a/doc/model/train-energy.md +++ b/doc/model/train-energy.md @@ -4,7 +4,7 @@ In this section, we will take `$deepmd_source_dir/examples/water/se_e2_a/input.j ## The fitting network -The construction of the fitting net is give by section {ref}`fitting_net ` +The construction of the fitting net is given by section {ref}`fitting_net ` ```json "fitting_net" : { "neuron": [240, 240, 240], @@ -22,11 +22,11 @@ The loss function $L$ for training energy is given by $$L = p_e L_e + p_f L_f + p_v L_v$$ -where $L_e$, $L_f$, and $L_v$ denote the loss in energy, force and virial, respectively. $p_e$, $p_f$, and $p_v$ give the prefactors of the energy, force and virial losses. The prefectors may not be a constant, rather it changes linearly with the learning rate. Taking the force prefactor for example, at training step $t$, it is given by +where $L_e$, $L_f$, and $L_v$ denote the loss in energy, forces and virials, respectively. $p_e$, $p_f$, and $p_v$ give the prefactors of the energy, force and virial losses. The prefectors may not be a constant, rather it changes linearly with the learning rate. Taking the force prefactor for example, at training step $t$, it is given by $$p_f(t) = p_f^0 \frac{ \alpha(t) }{ \alpha(0) } + p_f^\infty ( 1 - \frac{ \alpha(t) }{ \alpha(0) })$$ -where $\alpha(t)$ denotes the learning rate at step $t$. $p_f^0$ and $p_f^\infty$ specifies the $p_f$ at the start of the training and at the limit of $t \to \infty$ (set by {ref}`start_pref_f ` and {ref}`limit_pref_f `, respectively), i.e. +where $\alpha(t)$ denotes the learning rate at step $t$. $p_f^0$ and $p_f^\infty$ specifies the $p_f$ at the start of the training and the limit of $t \to \infty$ (set by {ref}`start_pref_f ` and {ref}`limit_pref_f `, respectively), i.e. ```math pref_f(t) = start_pref_f * ( lr(t) / start_lr ) + limit_pref_f * ( 1 - lr(t) / start_lr ) ``` diff --git a/doc/model/train-fitting-tensor.md b/doc/model/train-fitting-tensor.md index 240f126aa3..348f33d425 100644 --- a/doc/model/train-fitting-tensor.md +++ b/doc/model/train-fitting-tensor.md @@ -1,6 +1,6 @@ # Fit `tensor` like `Dipole` and `Polarizability` -Unlike `energy`, which is a scalar, one may want to fit some high dimensional physical quantity, like `dipole` (vector) and `polarizability` (matrix, shorted as `polar`). Deep Potential has provided different APIs to do this. In this example, we will show you how to train a model to fit them for a water system. A complete training input script of the examples can be found in +Unlike `energy`, which is a scalar, one may want to fit some high dimensional physical quantity, like `dipole` (vector) and `polarizability` (matrix, shorted as `polar`). Deep Potential has provided different APIs to do this. In this example, we will show you how to train a model to fit a water system. A complete training input script of the examples can be found in ```bash $deepmd_source_dir/examples/water_tensor/dipole/dipole_input.json @@ -9,13 +9,13 @@ $deepmd_source_dir/examples/water_tensor/polar/polar_input.json The training and validation data are also provided our examples. But note that **the data provided along with the examples are of limited amount, and should not be used to train a production model.** -Similar to the `input.json` used in `ener` mode, training json is also divided into {ref}`model `, {ref}`learning_rate `, {ref}`loss ` and {ref}`training `. Most keywords remains the same as `ener` mode, and their meaning can be found [here](train-se-e2-a.md). To fit a tensor, one need to modify {ref}`model/fitting_net ` and {ref}`loss `. +Similar to the `input.json` used in `ener` mode, training JSON is also divided into {ref}`model `, {ref}`learning_rate `, {ref}`loss ` and {ref}`training `. Most keywords remain the same as `ener` mode, and their meaning can be found [here](train-se-e2-a.md). To fit a tensor, one needs to modify {ref}`model/fitting_net ` and {ref}`loss `. ## The fitting Network The {ref}`fitting_net ` section tells DP which fitting net to use. -The json of `dipole` type should be provided like +The JSON of `dipole` type should be provided like ```json "fitting_net" : { @@ -27,7 +27,7 @@ The json of `dipole` type should be provided like }, ``` -The json of `polar` type should be provided like +The JSON of `polar` type should be provided like ```json "fitting_net" : { @@ -40,14 +40,14 @@ The json of `polar` type should be provided like ``` - `type` specifies which type of fitting net should be used. It should be either `dipole` or `polar`. Note that `global_polar` mode in version 1.x is already **deprecated** and is merged into `polar`. To specify whether a system is global or atomic, please see [here](train-se-e2-a.md). -- `sel_type` is a list specifying which type of atoms have the quantity you want to fit. For example, in water system, `sel_type` is `[0]` since `0` represents for atom `O`. If left unset, all type of atoms will be fitted. -- The rest `args` has the same meaning as they do in `ener` mode. +- `sel_type` is a list specifying which type of atoms have the quantity you want to fit. For example, in the water system, `sel_type` is `[0]` since `0` represents atom `O`. If left unset, all types of atoms will be fitted. +- The rest arguments have the same meaning as they do in `ener` mode. ## Loss -DP supports a combinational training of global system (only a global `tensor` label, i.e. dipole or polar, is provided in a frame) and atomic system (labels for **each** atom included in `sel_type` are provided). In a global system, each frame has just **one** `tensor` label. For example, when fitting `polar`, each frame will just provide a `1 x 9` vector which gives the elements of the polarizability tensor of that frame in order XX, XY, XZ, YX, YY, YZ, XZ, ZY, ZZ. By contrast, in a atomic system, each atom in `sel_type` has a `tensor` label. For example, when fitting dipole, each frame will provide a `#sel_atom x 3` matrix, where `#sel_atom` is the number of atoms whose type are in `sel_type`. +DP supports a combinational training of the global system (only a global `tensor` label, i.e. dipole or polar, is provided in a frame) and atomic system (labels for **each** atom included in `sel_type` are provided). In a global system, each frame has just **one** `tensor` label. For example, when fitting `polar`, each frame will just provide a `1 x 9` vector which gives the elements of the polarizability tensor of that frame in order XX, XY, XZ, YX, YY, YZ, XZ, ZY, ZZ. By contrast, in an atomic system, each atom in `sel_type` has a `tensor` label. For example, when fitting a dipole, each frame will provide a `#sel_atom x 3` matrices, where `#sel_atom` is the number of atoms whose type are in `sel_type`. -The {ref}`loss ` section tells DP the weight of this two kind of loss, i.e. +The {ref}`loss ` section tells DP the weight of these two kinds of loss, i.e. ```python loss = pref * global_loss + pref_atomic * atomic_loss @@ -64,17 +64,17 @@ The loss section should be provided like ``` - {ref}`type ` should be written as `tensor` as a distinction from `ener` mode. -- {ref}`pref ` and {ref}`pref_atomic ` respectively specify the weight of global loss and atomic loss. It can not be left unset. If set to 0, system with corresponding label will NOT be included in the training process. +- {ref}`pref ` and {ref}`pref_atomic ` respectively specify the weight of global loss and atomic loss. It can not be left unset. If set to 0, the corresponding label will NOT be included in the training process. ## Training Data Preparation -In tensor mode, the identification of label's type (global or atomic) is derived from the file name. The global label should be named as `dipole.npy/raw` or `polarizability.npy/raw`, while the atomic label should be named as `atomic_dipole.npy/raw` or `atomic_polarizability.npy/raw`. If wrongly named, DP will report an error +In tensor mode, the identification of the label's type (global or atomic) is derived from the file name. The global label should be named `dipole.npy/raw` or `polarizability.npy/raw`, while the atomic label should be named `atomic_dipole.npy/raw` or `atomic_polarizability.npy/raw`. If wrongly named, DP will report an error ```bash ValueError: cannot reshape array of size xxx into shape (xx,xx). This error may occur when your label mismatch it's name, i.e. you might store global tensor in `atomic_tensor.npy` or atomic tensor in `tensor.npy`. ``` -In this case, please check the file name of label. +In this case, please check the file name of the label. ## Train the Model @@ -111,7 +111,7 @@ The detailed loss can be found in `lcurve.out`: 2000 2.59e-02 5.71e-02 1.03e-02 5.71e-02 1.94e-03 0.00e+00 1.0e-08 ``` -One may notice that in each step, some of local loss and global loss will be `0.0`. This is because our training data and validation data consist of global system and atomic system, i.e. +One may notice that in each step, some of the local loss and global loss will be `0.0`. This is because our training data and validation data consist of the global system and atomic system, i.e. ``` --training_data >atomic_system @@ -120,6 +120,6 @@ One may notice that in each step, some of local loss and global loss will be `0. >atomic_system >global_system ``` -During training, at each step when the lcurve.out is printed, the system used for evaluating the training (validation) error may be either with only global or only atomic labels, thus the corresponding atomic or global errors are missing and are printed as zeros. +During training, at each step when the `lcurve.out` is printed, the system used for evaluating the training (validation) error may be either with only global or only atomic labels, thus the corresponding atomic or global errors are missing and are printed as zeros. diff --git a/doc/model/train-hybrid.md b/doc/model/train-hybrid.md index b69b49ea21..fb4af522ca 100644 --- a/doc/model/train-hybrid.md +++ b/doc/model/train-hybrid.md @@ -1,6 +1,6 @@ # Descriptor `"hybrid"` -This descriptor hybridize multiple descriptors to form a new descriptor. For example we have a list of descriptor denoted by $\mathcal D_1$, $\mathcal D_2$, ..., $\mathcal D_N$, the hybrid descriptor this the concatenation of the list, i.e. $\mathcal D = (\mathcal D_1, \mathcal D_2, \cdots, \mathcal D_N)$. +This descriptor hybridizes multiple descriptors to form a new descriptor. For example, we have a list of descriptors denoted by $\mathcal D_1$, $\mathcal D_2$, ..., $\mathcal D_N$, the hybrid descriptor this the concatenation of the list, i.e. $\mathcal D = (\mathcal D_1, \mathcal D_2, \cdots, \mathcal D_N)$. To use the descriptor in DeePMD-kit, one firstly set the {ref}`type ` to {ref}`hybrid `, then provide the definitions of the descriptors by the items in the `list`, ```json diff --git a/doc/model/train-se-atten.md b/doc/model/train-se-atten.md index a742070391..7fe521f8a6 100644 --- a/doc/model/train-se-atten.md +++ b/doc/model/train-se-atten.md @@ -9,18 +9,18 @@ Here we propose DPA-1, a Deep Potential model with a novel attention mechanism, See [this paper](https://arxiv.org/abs/2208.08236) for more information. DPA-1 is implemented as a new descriptor `"se_atten"` for model training, which can be used after simply editing the input.json. ## Installation -Follow the [standard installation](../install/install-from-source.md#install-the-python-interface) of python interface in DeePMD-kit. -After that, you can smoothly use the DPA-1 model with following instructions. +Follow the [standard installation](../install/install-from-source.md#install-the-python-interface) of Python interface in the DeePMD-kit. +After that, you can smoothly use the DPA-1 model with the following instructions. ## Introduction to new features of DPA-1 -Next we will list the detail settings in input.json and the data format, especially for large systems with dozens of elements. An example of DPA-1 input can be found in [here](../../examples/water/se_atten/input.json). +Next, we will list the detailed settings in input.json and the data format, especially for large systems with dozens of elements. An example of DPA-1 input can be found [here](../../examples/water/se_atten/input.json). ### Descriptor `"se_atten"` The notation of `se_atten` is short for the smooth edition of Deep Potential with an attention mechanism. This descriptor was described in detail in [the DPA-1 paper](https://arxiv.org/abs/2208.08236) and the images above. -In this example we will train a DPA-1 model for a water system. A complete training input script of this example can be find in the directory: +In this example, we will train a DPA-1 model for a water system. A complete training input script of this example can be found in the directory: ```bash $deepmd_source_dir/examples/water/se_atten/input.json ``` @@ -45,21 +45,21 @@ An example of the DPA-1 descriptor is provided as follows ``` * The {ref}`type ` of the descriptor is set to `"se_atten"`, which will use DPA-1 structures. * {ref}`rcut ` is the cut-off radius for neighbor searching, and the {ref}`rcut_smth ` gives where the smoothing starts. -* **{ref}`sel `** gives the maximum possible number of neighbors in the cut-off radius. It is an int. Note that this number highly effects the efficiency of training, which we usually use less than 200. (We use 120 for training 56 elements in [OC2M dataset](https://github.com/Open-Catalyst-Project/ocp/blob/main/DATASET.md)) -* The {ref}`neuron ` specifies the size of the embedding net. From left to right the members denote the sizes of each hidden layer from input end to the output end, respectively. If the outer layer is of twice size as the inner layer, then the inner layer is copied and concatenated, then a [ResNet architecture](https://arxiv.org/abs/1512.03385) is built between them. -* The {ref}`axis_neuron ` specifies the size of submatrix of the embedding matrix, the axis matrix as explained in the [DeepPot-SE paper](https://arxiv.org/abs/1805.09003) +* **{ref}`sel `** gives the maximum possible number of neighbors in the cut-off radius. It is an int. Note that this number highly affects the efficiency of training, which we usually use less than 200. (We use 120 for training 56 elements in [OC2M dataset](https://github.com/Open-Catalyst-Project/ocp/blob/main/DATASET.md)) +* The {ref}`neuron ` specifies the size of the embedding net. From left to right the members denote the sizes of each hidden layer from the input end to the output end, respectively. If the outer layer is twice the size of the inner layer, then the inner layer is copied and concatenated, then a [ResNet architecture](https://arxiv.org/abs/1512.03385) is built between them. +* The {ref}`axis_neuron ` specifies the size of the submatrix of the embedding matrix, the axis matrix as explained in the [DeepPot-SE paper](https://arxiv.org/abs/1805.09003) * If the option {ref}`resnet_dt ` is set to `true`, then a timestep is used in the ResNet. * {ref}`seed ` gives the random seed that is used to generate random numbers when initializing the model parameters. -* {ref}`attn ` sets the length of hidden vector during scale-dot attention computation. +* {ref}`attn ` sets the length of a hidden vector during scale-dot attention computation. * {ref}`attn_layer ` sets the number of layers in attention mechanism. * {ref}`attn_mask ` determines whether to mask the diagonal in the attention weights and False is recommended. * {ref}`attn_dotr ` determines whether to dot the relative coordinates on the attention weights as a gated scheme, True is recommended. ### Fitting `"ener"` -DPA-1 only support `"ener"` fitting type, and you can refer [here](train-energy.md) for detail information. +DPA-1 only supports `"ener"` fitting type, and you can refer [here](train-energy.md) for detailed information. ### Type embedding -DPA-1 only support models with type embeddings on. And the default setting is as follows: +DPA-1 only supports models with type embeddings. And the default setting is as follows: ```json "type_embedding":{ "neuron": [8], @@ -67,11 +67,11 @@ DPA-1 only support models with type embeddings on. And the default setting is as "seed": 1 } ``` -You can add these settings in input.json if you want to change the default ones, see [here](train-se-e2-a-tebd.md) for detail information. +You can add these settings in input.json if you want to change the default ones, see [here](train-se-e2-a-tebd.md) for detailed information. ### Type map -For training a large systems, especially those with dozens of elements, the {ref}`type ` determines the element index of training data: +For training large systems, especially those with dozens of elements, the {ref}`type ` determines the element index of training data: ```json "type_map": [ "Mg", @@ -82,10 +82,10 @@ For training a large systems, especially those with dozens of elements, the {ref which should include all the elements in the dataset you want to train on. ## Data format DPA-1 supports the standard data format, which is detailed in [data-conv.md](../data/data-conv.md) and [system.md](../data/system.md). -Note that in this format, only those frames with the same fingerprint(i.e. the number of atoms of different element) can be put together as a unit system. -This may lead to sparse frame number in those rare systems. +Note that in this format, only those frames with the same fingerprint (i.e. the number of atoms of different elements) can be put together as a unified system. +This may lead to sparse frame numbers in those rare systems. -An ideal way is to put systems with same total number of atoms together, which is the way we trained DPA-1 on [OC2M](https://github.com/Open-Catalyst-Project/ocp/blob/main/DATASET.md). +An ideal way is to put systems with the same total number of atoms together, which is the way we trained DPA-1 on [OC2M](https://github.com/Open-Catalyst-Project/ocp/blob/main/DATASET.md). This system format, which is called `mixed_type`, is proper to put frame-sparse systems together and is slightly different from the standard one. Take an example, a `mixed_type` may contain the following files: ``` @@ -97,7 +97,7 @@ set.000/energy.npy set.000/force.npy set.000/real_atom_types.npy ``` -This system contains `Nframes` frames with the same atom number `Natoms`, the total number of element types contained in all frames is `Ntypes`. Note that we put all the frames in one set `set.000`. Most files are the same as those in [standard format](../data/system.md), here we only list the distinct ones: +This system contains `Nframes` frames with the same atom number `Natoms`, the total number of element types contained in all frames is `Ntypes`. Note that we put all the frames in one set `set.000`. Most files are the same as those in [standard formats](../data/system.md), here we only list the distinct ones: ID | Property | File | Required/Optional | Shape | Description ---------- | -------------------------------- | ------------------- | -------------------- | ----------------------- | ----------- @@ -110,7 +110,7 @@ With these edited files, one can put together frames with the same `Natoms`, ins The API to generate or transfer to `mixed_type` format will be uploaded on [dpdata](https://github.com/deepmodeling/dpdata) soon for a more convenient experience. ## Training example -Here we upload the AlMgCu example showed in the paper, you can download here: +Here we upload the AlMgCu example shown in the paper, you can download it here: [Baidu disk](https://pan.baidu.com/s/1Mk9CihPHCmf8quwaMhT-nA?pwd=d586); [Google disk](https://drive.google.com/file/d/11baEpRrvHoqxORFPSdJiGWusb3Y4AnRE/view?usp=sharing). diff --git a/doc/model/train-se-e2-a-tebd.md b/doc/model/train-se-e2-a-tebd.md index 4820b6ee2c..07546e3120 100644 --- a/doc/model/train-se-e2-a-tebd.md +++ b/doc/model/train-se-e2-a-tebd.md @@ -1,6 +1,6 @@ # Type embedding approach -We generate specific type embedding vector for each atom type, so that we can share one descriptor embedding net and one fitting net in total, which decline training complexity largely. +We generate specific a type embedding vector for each atom type so that we can share one descriptor embedding net and one fitting net in total, which decline training complexity largely. The training input script is similar to that of [`se_e2_a`](train-se-e2-a.md), but different by adding the {ref}`type_embedding ` section. @@ -20,7 +20,7 @@ The {ref}`model ` defines how the model is constructed, adding a section } } ``` -Model will automatically apply type embedding approach and generate type embedding vectors. If type embedding vector is detected, descriptor and fitting net would take it as a part of input. +The model will automatically apply the type embedding approach and generate type embedding vectors. If the type embedding vector is detected, the descriptor and fitting net would take it as a part of the input. The construction of type embedding net is given by {ref}`type_embedding `. An example of {ref}`type_embedding ` is provided as follows ```json @@ -30,17 +30,17 @@ The construction of type embedding net is given by {ref}`type_embedding ` specifies the size of the type embedding net. From left to right the members denote the sizes of each hidden layer from input end to the output end, respectively. It takes one-hot vector as input and output dimension equals to the last dimension of the {ref}`neuron ` list. If the outer layer is of twice size as the inner layer, then the inner layer is copied and concatenated, then a [ResNet architecture](https://arxiv.org/abs/1512.03385) is built between them. +* The {ref}`neuron ` specifies the size of the type embedding net. From left to right the members denote the sizes of each hidden layer from the input end to the output end, respectively. It takes a one-hot vector as input and output dimension equals to the last dimension of the {ref}`neuron ` list. If the outer layer is twice the size of the inner layer, then the inner layer is copied and concatenated, then a [ResNet architecture](https://arxiv.org/abs/1512.03385) is built between them. * If the option {ref}`resnet_dt ` is set to `true`, then a timestep is used in the ResNet. * {ref}`seed ` gives the random seed that is used to generate random numbers when initializing the model parameters. -A complete training input script of this example can be find in the directory. +A complete training input script of this example can be found in the directory. ```bash $deepmd_source_dir/examples/water/se_e2_a_tebd/input.json ``` See [here](../development/type-embedding.md) for further explanation of `type embedding`. :::{note} -You can't apply compression method while using atom type embedding. +You can't apply the compression method while using the atom type embedding. ::: \ No newline at end of file diff --git a/doc/model/train-se-e2-a.md b/doc/model/train-se-e2-a.md index 2a28bf9658..94ab209e38 100644 --- a/doc/model/train-se-e2-a.md +++ b/doc/model/train-se-e2-a.md @@ -2,7 +2,9 @@ The notation of `se_e2_a` is short for the Deep Potential Smooth Edition (DeepPot-SE) constructed from all information (both angular and radial) of atomic configurations. The `e2` stands for the embedding with two-atoms information. This descriptor was described in detail in [the DeepPot-SE paper](https://arxiv.org/abs/1805.09003). -In this example we will train a DeepPot-SE model for a water system. A complete training input script of this example can be find in the directory. +Note that it is sometimes called a "two-atom embedding descriptor" which means the input of the embedding net is atomic distances. The descriptor **does** encode multi-body information (both angular and radial information of neighboring atoms). + +In this example, we will train a DeepPot-SE model for a water system. A complete training input script of this example can be found in the directory. ```bash $deepmd_source_dir/examples/water/se_e2_a/input.json ``` @@ -24,10 +26,10 @@ The construction of the descriptor is given by section {ref}`descriptor ` of the descriptor is set to `"se_e2_a"`. * {ref}`rcut ` is the cut-off radius for neighbor searching, and the {ref}`rcut_smth ` gives where the smoothing starts. -* {ref}`sel ` gives the maximum possible number of neighbors in the cut-off radius. It is a list, the length of which is the same as the number of atom types in the system, and `sel[i]` denote the maximum possible number of neighbors with type `i`. -* The {ref}`neuron ` specifies the size of the embedding net. From left to right the members denote the sizes of each hidden layer from input end to the output end, respectively. If the outer layer is of twice size as the inner layer, then the inner layer is copied and concatenated, then a [ResNet architecture](https://arxiv.org/abs/1512.03385) is built between them. -* If the option {ref}`type_one_side ` is set to `true`, then descriptor will consider the types of neighbor atoms. Otherwise, both the types of centric and  neighbor atoms are considered. -* The {ref}`axis_neuron ` specifies the size of submatrix of the embedding matrix, the axis matrix as explained in the [DeepPot-SE paper](https://arxiv.org/abs/1805.09003) +* {ref}`sel ` gives the maximum possible number of neighbors in the cut-off radius. It is a list, the length of which is the same as the number of atom types in the system, and `sel[i]` denotes the maximum possible number of neighbors with type `i`. +* The {ref}`neuron ` specifies the size of the embedding net. From left to right the members denote the sizes of each hidden layer from the input end to the output end, respectively. If the outer layer is twice the size of the inner layer, then the inner layer is copied and concatenated, then a [ResNet architecture](https://arxiv.org/abs/1512.03385) is built between them. +* If the option {ref}`type_one_side ` is set to `true`, then the descriptor will consider the types of neighbor atoms. Otherwise, both the types of centric and neighbor atoms are considered. +* The {ref}`axis_neuron ` specifies the size of the submatrix of the embedding matrix, the axis matrix as explained in the [DeepPot-SE paper](https://arxiv.org/abs/1805.09003) * If the option {ref}`resnet_dt ` is set to `true`, then a timestep is used in the ResNet. * {ref}`seed ` gives the random seed that is used to generate random numbers when initializing the model parameters. diff --git a/doc/nvnmd/nvnmd.md b/doc/nvnmd/nvnmd.md index 3979020f9d..97781fc06c 100644 --- a/doc/nvnmd/nvnmd.md +++ b/doc/nvnmd/nvnmd.md @@ -2,19 +2,19 @@ NVNMD stands for non-von Neumann molecular dynamics. -This is the training code we used to generate the results in our paper entitled "Accurate and Efficient Molecular Dynamics based on Machine Learning and Non Von Neumann Architecture", which has been accepted by npj Computational Materials ([DOI: 10.1038/s41524-022-00773-z](https://www.nature.com/articles/s41524-022-00773-z)). +This is the training code we used to generate the results in our paper entitled "Accurate and Efficient Molecular Dynamics based on Machine Learning and non von Neumann Architecture", which has been accepted by npj Computational Materials ([DOI: 10.1038/s41524-022-00773-z](https://www.nature.com/articles/s41524-022-00773-z)). Any user can follow two consecutive steps to run molecular dynamics (MD) on the proposed NVNMD computer, which has been released online: (i) to train a machine learning (ML) model that can decently reproduce the potential energy surface (PES); and (ii) to deploy the trained ML model on the proposed NVNMD computer, then run MD there to obtain the atomistic trajectories. # Training -Our training procedure consists of not only the continuous neural network (CNN) training, but also the quantized neural network (QNN) training which uses the results of CNN as inputs. It is performed on CPU or GPU by using the training codes we open-sourced online. +Our training procedure consists of not only continuous neural network (CNN) training but also quantized neural network (QNN) training which uses the results of CNN as inputs. It is performed on CPU or GPU by using the training codes we open-sourced online. -To train a ML model that can decently reproduce the PES, training and testing data set should be prepared first. This can be done by using either the state-of-the-art active learning tools, or the outdated (i.e., less efficient) brute-force density functional theory (DFT)-based ab-initio molecular dynamics (AIMD) sampling. +To train an ML model that can decently reproduce the PES, a training and testing data set should be prepared first. This can be done by using either the state-of-the-art active learning tools or the outdated (i.e., less efficient) brute-force density functional theory (DFT)-based ab-initio molecular dynamics (AIMD) sampling. If you just want to simply test the training function, you can use the example in the `$deepmd_source_dir/examples/nvnmd` directory. If you want to fully experience training and running MD functions, you can download the complete example from the [website](https://github.com/LiuGroupHNU/nvnmd-example). -Then, copy the data set to working directory +Then, copy the data set to the working directory ```bash mkdir -p $workspace @@ -23,7 +23,7 @@ mkdir -p data cp -r $dataset data ``` -where `$dataset` is the path to the data set and `$workspace` is the path to working directory. +where `$dataset` is the path to the data set and `$workspace` is the path to the working directory. ## Input script @@ -170,7 +170,7 @@ dp train-nvnmd train_cnn.json -s s1 dp train-nvnmd train_qnn.json -s s2 ``` -After training process, you will get two folders: `nvnmd_cnn` and `nvnmd_qnn`. The `nvnmd_cnn` contains the model after continuous neural network (CNN) training. The `nvnmd_qnn` contains the model after quantized neural network (QNN) training. The binary file `nvnmd_qnn/model.pb` is the model file which is used to performs NVNMD in server [http://nvnmd.picp.vip] +After the training process, you will get two folders: `nvnmd_cnn` and `nvnmd_qnn`. The `nvnmd_cnn` contains the model after continuous neural network (CNN) training. The `nvnmd_qnn` contains the model after quantized neural network (QNN) training. The binary file `nvnmd_qnn/model.pb` is the model file that is used to perform NVNMD in the server [http://nvnmd.picp.vip]. # Testing @@ -182,7 +182,7 @@ mkdir test dp test -m ./nvnmd_qnn/frozen_model.pb -s path/to/system -d ./test/detail -n 99999 -l test/output.log ``` -where the frozen model file to import is given via the `-m` command line flag, the path to the testing data set is given via the `-s` command line flag, the file containing details of energy, force and virial accuracy is given via the `-d` command line flag, the amount of data for testing is given via the `-n` command line flag. +where the frozen model file to import is given via the `-m` command line flag, the path to the testing data set is given via the `-s` command line flag, and the file containing details of energy, forces and virials accuracy is given via the `-d` command line flag, the amount of data for testing is given via the `-n` command line flag. # Running MD @@ -210,7 +210,7 @@ The homepage displays the remaining calculation time and all calculation records
Figure.3 The interface for adding a new task
- Task name: name of the task -- Upload mode: two modes of uploading results to online data storage, including `Manual upload` and `Automatic upload`. Results need to be uploaded manually to online data storage with `Manual upload` mode, and will be uploaded automatically with `Automatic upload` mode. +- Upload mode: two modes of uploading results to online data storage, including `Manual upload` and `Automatic upload`. Results need to be uploaded manually to online data storage with `Manual upload` mode and will be uploaded automatically with `Automatic upload` mode. - Input script: input file of the MD simulation. In the input script, one needs to specify the pair style as follows @@ -221,7 +221,7 @@ pair_coeff * * ``` - Model file: the ML model named `model.pb` obtained by QNN training. -- Data files: data files containing information required for running an MD simulation (e.g., `coord.lmp` containing initial atom coordinates). +- Data files: data files containing the information required for running an MD simulation (e.g., `coord.lmp` containing initial atom coordinates). Next, you can click `Submit` to submit the task and then automatically return to the homepage (Figure.4). @@ -235,7 +235,7 @@ Then, click `Refresh` to view the latest status of all calculation tasks. For the task whose calculation status is `Pending` and `Running`, you can click the corresponding `Cancel` on the homepage to stop the calculation (Figure.5). ![ALT](./figure_5.png "The homepage with a cancelled task") -
Figure.5 The homepage with a cancelled task
+
Figure.5 The homepage with a canceled task
## Downloading results diff --git a/doc/test/model-deviation.md b/doc/test/model-deviation.md index edc4e199d1..41cda9ddb7 100644 --- a/doc/test/model-deviation.md +++ b/doc/test/model-deviation.md @@ -1,6 +1,6 @@ # Calculate Model Deviation -One can also use a subcommand to calculate deviation of prediced forces or virials for a bunch of models in the following way: +One can also use a subcommand to calculate the deviation of predicted forces or virials for a bunch of models in the following way: ```bash dp model-devi -m graph.000.pb graph.001.pb graph.002.pb graph.003.pb -s ./data -o model_devi.out ``` @@ -35,4 +35,4 @@ optional arguments: The trajectory frequency of the system (default: 1) ``` -For more details with respect to definition of model deviation and its application, please refer to [Yuzhi Zhang, Haidi Wang, Weijie Chen, Jinzhe Zeng, Linfeng Zhang, Han Wang, and Weinan E, DP-GEN: A concurrent learning platform for the generation of reliable deep learning based potential energy models, Computer Physics Communications, 2020, 253, 107206.](https://doi.org/10.1016/j.cpc.2020.107206) +For more details concerning the definition of model deviation and its application, please refer to [Yuzhi Zhang, Haidi Wang, Weijie Chen, Jinzhe Zeng, Linfeng Zhang, Han Wang, and Weinan E, DP-GEN: A concurrent learning platform for the generation of reliable deep learning based potential energy models, Computer Physics Communications, 2020, 253, 107206.](https://doi.org/10.1016/j.cpc.2020.107206) diff --git a/doc/test/test.md b/doc/test/test.md index d097ec2223..ae7fd2fd5c 100644 --- a/doc/test/test.md +++ b/doc/test/test.md @@ -27,6 +27,6 @@ optional arguments: The random seed --shuffle-test Shuffle test data -d DETAIL_FILE, --detail-file DETAIL_FILE - The file containing details of energy force and virial - accuracy + The prefix to files where details of energy, force and virial accuracy/accuracy per atom will be written + -a, --atomic Test the accuracy of atomic label, i.e. energy / tensor (dipole, polar) ``` \ No newline at end of file diff --git a/doc/third-party/gromacs.md b/doc/third-party/gromacs.md index e504c43f59..d5bafc4d43 100644 --- a/doc/third-party/gromacs.md +++ b/doc/third-party/gromacs.md @@ -2,7 +2,7 @@ ## DP/MM Simulation This part gives a simple tutorial on how to run a DP/MM simulation for methane in water, which means using DP for methane and TIP3P for water. All relevant files can be found in `examples/methane`. ### Topology Preparation -Similar to QM/MM simulation, the internal interactions (including bond, angle, dihedrals, LJ, Columb) of the region descibed by a neural network potential (NNP) have to be **turned off**. In GROMACS, bonded interactions can be turned off by modifying `[ bonds ]`, `[ angles ]`, `[ dihedrals ]` and `[ pairs ]` sections. And LJ and Columb interactions must be turned off by `[ exclusions ]` section. +Similar to QM/MM simulation, the internal interactions (including bond, angle, dihedrals, LJ, Columb) of the region described by a neural network potential (NNP) have to be **turned off**. In GROMACS, bonded interactions can be turned off by modifying `[ bonds ]`, `[ angles ]`, `[ dihedrals ]` and `[ pairs ]` sections. And LJ and Columb interactions must be turned off by `[ exclusions ]` section. For example, if one wants to simulate ethane in water, using DeepPotential for methane and TIP3P for water, the topology of methane should be like the following (as presented in `examples/methane/methane.itp`): ``` @@ -38,7 +38,7 @@ For example, if one wants to simulate ethane in water, using DeepPotential for m 4 1 2 3 5 5 1 2 3 4 ``` -For comparsion, the original topology file genearted by `acpype` will be: +For comparison, the original topology file generated by `acpype` will be: ``` ; methane_GMX.itp created by acpype (v: 2021-02-05T22:15:50CET) on Wed Sep 8 01:21:53 2021 @@ -76,7 +76,7 @@ For comparsion, the original topology file genearted by `acpype` will be: 4 1 5 1 1.0758e+02 3.2635e+02 ; H3 - C1 - H4 ``` ### DeepMD Settings -Before running simulation, we need to tell GROMACS to use DeepPotential by setting environment variable `GMX_DEEPMD_INPUT_JSON`: +Before running simulations, we need to tell GROMACS to use DeepPotential by setting the environment variable `GMX_DEEPMD_INPUT_JSON`: ```bash export GMX_DEEPMD_INPUT_JSON=input.json ``` @@ -92,29 +92,29 @@ Then, in your working directories, we have to write `input.json` file: ``` Here is an explanation for these settings: + `graph_file` : The graph file (with suffix .pb) generated by `dp freeze` command -+ `type_file` : File to specify DP atom types (in space-sepreated format). Here, `type.raw` looks like ++ `type_file` : File to specify DP atom types (in space-separated format). Here, `type.raw` looks like ``` 1 0 0 0 0 ``` -+ `index_file` : File containing indices of DP atoms (in space-seperated format), which should be in consistent with indices' order in .gro file but **starting from zero**. Here, `index.raw` looks like ++ `index_file` : File containing indices of DP atoms (in space-separated format), which should be consistent with the indices' order in .gro file but **starting from zero**. Here, `index.raw` looks like ``` 0 1 2 3 4 ``` + `lambda`: Optional, default 1.0. Used in alchemical calculations. -+ `pbc`: Optional, default true. If true, the GROMACS peroidic condition is passed to DeepMD. ++ `pbc`: Optional, default true. If true, the GROMACS periodic condition is passed to DeepMD. ### Run Simulation Finally, you can run GROMACS using `gmx mdrun` as usual. ## All-atom DP Simulation -This part gives an example on how to run a simulation with all atoms described by a DeepPotential with Gromacs, taking water as an example. Instead of using `[ exclusions ]` to turn off the non-bonded energies, we can simply do this by setting LJ parameters (i.e. epsilon and sigma) and partial charges to 0, as shown in `examples/water/gmx/water.top`: +This part gives an example of how to simulate all atoms described by a DeepPotential with Gromacs, taking water as an example. Instead of using `[ exclusions ]` to turn off the non-bonded energies, we can simply do this by setting LJ parameters (i.e. epsilon and sigma) and partial charges to 0, as shown in `examples/water/gmx/water.top`: ``` [ atomtypes ] ; name at.num mass charge ptype sigma epsilon HW 1 1.008 0.0000 A 0.00000e+00 0.00000e+00 OW 8 16.00 0.0000 A 0.00000e+00 0.00000e+00 ``` -As mentioned in the above section, `input.json` and relevant files (`index.raw`, `type.raw`) should also be created. Then, we can start the simulation under NVT ensemble and plot the radial distribution function (RDF) by `gmx rdf` command. We can see that the RDF given by Gromacs+DP matches perfectly with Lammps+DP, which further provides an evidence on the validity of our simulation. +As mentioned in the above section, `input.json` and relevant files (`index.raw`, `type.raw`) should also be created. Then, we can start the simulation under the NVT ensemble and plot the radial distribution function (RDF) by `gmx rdf` command. We can see that the RDF given by Gromacs+DP matches perfectly with Lammps+DP, which further provides an evidence on the validity of our simulation. ![rdf](../../examples/water/gmx/rdf.png) -However, we still recommend you run all-atom DP simulation using LAMMPS since it is more stable and efficient. \ No newline at end of file +However, we still recommend you run an all-atom DP simulation using LAMMPS since it is more stable and efficient. \ No newline at end of file diff --git a/doc/third-party/ipi.md b/doc/third-party/ipi.md index 8553953627..41611adf3d 100644 --- a/doc/third-party/ipi.md +++ b/doc/third-party/ipi.md @@ -1,10 +1,10 @@ # Run path-integral MD with i-PI -The i-PI works in a client-server model. The i-PI provides the server for integrating the replica positions of atoms, while the DeePMD-kit provides a client named `dp_ipi` (or `dp_ipi_low` for low precision) that computes the interactions (including energy, force and virial). The server and client communicates via the Unix domain socket or the Internet socket. Installation instructions of i-PI can be found [here](../install/install-ipi.md). The client can be started by +The i-PI works in a client-server model. The i-PI provides the server for integrating the replica positions of atoms, while the DeePMD-kit provides a client named `dp_ipi` (or `dp_ipi_low` for low precision) that computes the interactions (including energy, forces and virials). The server and client communicate via the Unix domain socket or the Internet socket. Installation instructions for i-PI can be found [here](../install/install-ipi.md). The client can be started by ```bash i-pi input.xml & dp_ipi water.json ``` -It is noted that multiple instances of the client is allow for computing, in parallel, the interactions of multiple replica of the path-integral MD. +It is noted that multiple instances of the client allow for computing, in parallel, the interactions of multiple replicas of the path-integral MD. `water.json` is the parameter file for the client `dp_ipi`, and an example is provided: ```json @@ -31,4 +31,4 @@ The option **`port`** should be the same as that in input.xml: The option **`graph_file`** provides the file name of the frozen model. -The `dp_ipi` gets the atom names from an [XYZ file](https://en.wikipedia.org/wiki/XYZ_file_format) provided by **`coord_file`** (meanwhile ignores all coordinates in it), and translates the names to atom types by rules provided by **`atom_type`**. \ No newline at end of file +The `dp_ipi` gets the atom names from an [XYZ file](https://en.wikipedia.org/wiki/XYZ_file_format) provided by **`coord_file`** (meanwhile ignores all coordinates in it) and translates the names to atom types by rules provided by **`atom_type`**. \ No newline at end of file diff --git a/doc/third-party/lammps-command.md b/doc/third-party/lammps-command.md index 84eb5f5b99..5ec51c6830 100644 --- a/doc/third-party/lammps-command.md +++ b/doc/third-party/lammps-command.md @@ -29,7 +29,7 @@ pair_style deepmd models ... keyword value ... - models = frozen model(s) to compute the interaction. If multiple models are provided, then only the first model serves to provide energy and force prediction for each timestep of molecular dynamics, and the model deviation will be computed among all models every `out_freq` timesteps. -- keyword = *out_file* or *out_freq* or *fparam* or *atomic* or *relative* +- keyword = *out_file* or *out_freq* or *fparam* or *atomic* or *relative* or *relative_v* or *aparam* or *ttm*
     out_file value = filename
         filename = The file name for the model deviation output. Default is model_devi.out
@@ -40,7 +40,13 @@ and the model deviation will be computed among all models every `out_freq` times
     atomic = no value is required. 
         If this keyword is set, the model deviation of each atom will be output.
     relative value = level
-        level = The level parameter for computing the relative model deviation
+        level = The level parameter for computing the relative model deviation of the force
+    relative_v value = level
+        level = The level parameter for computing the relative model deviation of the virial
+    aparam value = parameters
+        parameters = one or more atomic parameters of each atom required for model evaluation
+    ttm value = id
+        id = fix ID of fix ttm
 
### Examples @@ -55,13 +61,20 @@ Evaluate the interaction of the system by using [Deep Potential][DP] or [Deep Po This pair style takes the deep potential defined in a model file that usually has the .pb extension. The model can be trained and frozen by package [DeePMD-kit](https://github.com/deepmodeling/deepmd-kit). -The model deviation evalulate the consistency of the force predictions from multiple models. By default, only the maximal, minimal and averge model deviations are output. If the key `atomic` is set, then the model deviation of force prediction of each atom will be output. +The model deviation evalulates the consistency of the force predictions from multiple models. By default, only the maximal, minimal and average model deviations are output. If the key `atomic` is set, then the model deviation of force prediction of each atom will be output. -By default, the model deviation is output in absolute value. If the keyword `relative` is set, then the relative model deviation will be output. The relative model deviation of the force on atom $i$ is defined by +By default, the model deviation is output in absolute value. If the keyword `relative` is set, then the relative model deviation of the force will be output, including values output by the keyword `atomic`. The relative model deviation of the force on atom $i$ is defined by $$E_{f_i}=\frac{\left|D_{f_i}\right|}{\left|f_i\right|+l}$$ -where $D_{f_i}$ is the absolute model deviation of the force on atom $i$, $f_i$ is the norm of the the force and $l$ is provided as the parameter of the keyword `relative`. +where $D_{f_i}$ is the absolute model deviation of the force on atom $i$, $f_i$ is the norm of the force and $l$ is provided as the parameter of the keyword `relative`. +If the keyword `relative_v` is set, then the relative model deviation of the virial will be output instead of the absolute value, with the same definition of that of the force: + +$$E_{v_i}=\frac{\left|D_{v_i}\right|}{\left|v_i\right|+l}$$ + +If the keyword `fparam` is set, the given frame parameter(s) will be fed to the model. +If the keyword `aparam` is set, the given atomic parameter(s) will be fed to the model, where each atom is assumed to have the same atomic parameter(s). +If the keyword `ttm` is set, electronic temperatures from [fix ttm command](https://docs.lammps.org/fix_ttm.html) will be fed to the model as the atomic parameters. ### Restrictions - The `deepmd` pair style is provided in the USER-DEEPMD package, which is compiled from the DeePMD-kit, visit the [DeePMD-kit website](https://github.com/deepmodeling/deepmd-kit) for more information. @@ -69,7 +82,7 @@ where $D_{f_i}$ is the absolute model deviation of the force on atom $i$, $f_i$ ## Compute tensorial properties -The DeePMD-kit package provide the compute `deeptensor/atom` for computing atomic tensorial properties. +The DeePMD-kit package provides the compute `deeptensor/atom` for computing atomic tensorial properties. ```lammps compute ID group-ID deeptensor/atom model_file @@ -83,7 +96,7 @@ compute ID group-ID deeptensor/atom model_file ```lammps compute dipole all deeptensor/atom dipole.pb ``` -The result of the compute can be dump to trajctory file by +The result of the compute can be dumped to trajectory file by ```lammps dump 1 all custom 100 water.dump id type c_dipole[1] c_dipole[2] c_dipole[3] ``` @@ -108,24 +121,24 @@ The [DeePMD-kit](https://github.com/deepmodeling/deepmd-kit) allows also the com $$dvatom=\sum_{m}( \mathbf{r}_n- \mathbf{r}_m) \frac{de_m}{d\mathbf{r}_n}$$ -Where $\mathbf{r}_n$ is the atomic position of nth atom, $\mathbf{v}_n$ velocity of atom and $\frac{de_m}{d\mathbf{r}_n}$ the derivative of the atomic energy. +Where $\mathbf{r}_n$ is the atomic position of nth atom, $\mathbf{v}_n$ velocity of the atom and $\frac{de_m}{d\mathbf{r}_n}$ the derivative of the atomic energy. In LAMMPS one can get the per-atom stress using the command `centroid/stress/atom`: ```lammps compute ID group-ID centroid/stress/atom NULL virial ``` -see [LAMMPS doc page](https://docs.lammps.org/compute_stress_atom.html#thompson2) for more detailes on the meaning of the keywords. +see [LAMMPS doc page](https://docs.lammps.org/compute_stress_atom.html#thompson2) for more details on the meaning of the keywords. ### Examples In order of computing the 9-component per-atom stress ```lammps compute stress all centroid/stress/atom NULL virial ``` -Thus `c_stress` is an array with 9 component in the order `xx,yy,zz,xy,xz,yz,yx,zx,zy`. +Thus `c_stress` is an array with 9 components in the order `xx,yy,zz,xy,xz,yz,yx,zx,zy`. If you use this feature please cite [D. Tisi, L. Zhang, R. Bertossa, H. Wang, R. Car, S. Baroni - arXiv preprint arXiv:2108.10850, 2021](https://arxiv.org/abs/2108.10850) ## Computation of heat flux -Using per-atom stress tensor one can, for example, compute the heat flux defined as: +Using a per-atom stress tensor one can, for example, compute the heat flux defined as: $$\mathbf J = \sum_n e_n \mathbf v_n + \sum_{n,m} ( \mathbf r_m- \mathbf r_n) \frac{de_m}{d\mathbf r_n} \mathbf v_n$$ diff --git a/doc/third-party/lammps.md b/doc/third-party/lammps.md index 0dc092c9e9..5b9d3fd728 100644 --- a/doc/third-party/lammps.md +++ b/doc/third-party/lammps.md @@ -6,4 +6,4 @@ Running an MD simulation with LAMMPS is simpler. In the LAMMPS input file, one n pair_style deepmd graph.pb pair_coeff * * ``` -where `graph.pb` is the file name of the frozen model. It should be noted that LAMMPS counts atom types starting from 1, therefore, all LAMMPS atom type will be firstly subtracted by 1, and then passed into the DeePMD-kit engine to compute the interactions. +where `graph.pb` is the file name of the frozen model. It should be noted that LAMMPS counts atom types starting from 1, therefore, all LAMMPS atom types will be firstly subtracted by 1, and then passed into the DeePMD-kit engine to compute the interactions. diff --git a/doc/third-party/out-of-deepmd-kit.md b/doc/third-party/out-of-deepmd-kit.md index 3561f5bb83..4ae4d4006d 100644 --- a/doc/third-party/out-of-deepmd-kit.md +++ b/doc/third-party/out-of-deepmd-kit.md @@ -16,15 +16,15 @@ By inferring with the DP model `frozen_model_compressed.pb`, dpdata will generat ## OpenMM plugin for DeePMD-kit -An [OpenMM](https://github.com/openmm/openmm) plugin is provided from [JingHuangLab/openmm_deepmd_plugin](https://github.com/JingHuangLab/openmm_deepmd_plugin), written by the [Huang Lab](http://www.compbiophysics.org/) at the Westlake University. +An [OpenMM](https://github.com/openmm/openmm) plugin is provided from [JingHuangLab/openmm_deepmd_plugin](https://github.com/JingHuangLab/openmm_deepmd_plugin), written by the [Huang Lab](http://www.compbiophysics.org/) at Westlake University. ## AMBER interface to DeePMD-kit -An [AMBER](https://ambermd.org/) interface to DeePMD-kit is written by the [York Lab](https://theory.rutgers.edu/) from the Rutgers University. It is open-source at [GitLab RutgersLBSR/AmberDPRc](https://gitlab.com/RutgersLBSR/AmberDPRc/). Details can be found in [this paper](https://doi.org/10.1021/acs.jctc.1c00201). +An [AMBER](https://ambermd.org/) interface to DeePMD-kit is written by the [York [Lab](https://theory.rutgers.edu/) from Rutgers University. It is open-source at [GitLab RutgersLBSR/AmberDPRc](https://gitlab.com/RutgersLBSR/AmberDPRc/). Details can be found in [this paper](https://doi.org/10.1021/acs.jctc.1c00201). ## DP-GEN -[DP-GEN](https://github.com/deepmodeling/dpgen) provides a workflow to generate accurate DP models by calling DeePMD-kit's command line interface (CLI) in the local or the remote server. Details can be found in [this paper](https://doi.org/10.1016/j.cpc.2020.107206). +[DP-GEN](https://github.com/deepmodeling/dpgen) provides a workflow to generate accurate DP models by calling DeePMD-kit's command line interface (CLI) in the local or remote server. Details can be found in [this paper](https://doi.org/10.1016/j.cpc.2020.107206). ## MLatom diff --git a/doc/train/finetuning.md b/doc/train/finetuning.md new file mode 100644 index 0000000000..ede27c246a --- /dev/null +++ b/doc/train/finetuning.md @@ -0,0 +1,42 @@ +# Finetune the pretrained model + +Pretraining-and-finetuning is a widely used approach in other fields such as Computer Vision (CV) or Natural Language Processing (NLP) +to vastly reduce the training cost, while it's not trivial in potential models. +Compositions and configurations of data samples or even computational parameters in upstream software (such as VASP) +may be different between the pretrained and target datasets, leading to energy shifts or other diversities of training data. + +Recently the emerging of methods such as [DPA-1](https://arxiv.org/abs/2208.08236) has brought us to a new stage where we can +perform similar pretraining-finetuning approaches. +DPA-1 can hopefully learn the common knowledge in the pretrained dataset (especially the `force` information) +and thus reduce the computational cost in downstream training tasks. +If you have a pretrained model `pretrained.pb` +(here we support models using [`se_atten`](../model/train-se-atten.md) descriptor and [`ener`](../model/train-energy.md) fitting net) +on a large dataset (for example, [OC2M](https://github.com/Open-Catalyst-Project/ocp/blob/main/DATASET.md) in +DPA-1 [paper](https://arxiv.org/abs/2208.08236)), a finetuning strategy can be performed by simply running: + +```bash +$ dp train input.json --finetune pretrained.pb +``` + +The command above will change the energy bias in the last layer of the fitting net in `pretrained.pb`, +according to the training dataset in input.json. + +:::{warning} +Note that the elements in the training dataset must be contained in the pretrained dataset. +::: + +The finetune procedure will inherit the model structures in `pretrained.pb`, +and thus it will ignore the model parameters in `input.json`, +such as {ref}`descriptor `, {ref}`fitting_net `, +{ref}`type_embedding ` and {ref}`type_map `. +However, you can still set the `trainable` parameters in each part of `input.json` to control the training procedure. + +To obtain a more simplified script, for example, you can change the {ref}`model ` part in `input.json` to perform finetuning: +```json + "model": { + "type_map": ["O", "H"], + "type_embedding": {"trainable": true}, + "descriptor" : {}, + "fitting_net" : {} + } +``` diff --git a/doc/train/gpu-limitations.md b/doc/train/gpu-limitations.md index 269ccb8e57..d684698c42 100644 --- a/doc/train/gpu-limitations.md +++ b/doc/train/gpu-limitations.md @@ -1,7 +1,7 @@ # Known limitations of using GPUs -If you use deepmd-kit in a GPU environment, the acceptable value range of some variables are additionally restricted compared to the CPU environment due to the software's GPU implementations: -1. The number of atom type of a given system must be less than 128. -2. The maximum distance between an atom and it's neighbors must be less than 128. It can be controlled by setting the rcut value of training parameters. -3. Theoretically, the maximum number of atoms that a single GPU can accept is about 10,000,000. However, this value is actually limited by the GPU memory size currently, usually within 1000,000 atoms even at the model compression mode. -4. The total sel value of training parameters(in model/descriptor section) must be less than 4096. -5. The size of the last layer of embedding net must be less than 1024 during the model compression process. +If you use DeePMD-kit in a GPU environment, the acceptable value range of some variables is additionally restricted compared to the CPU environment due to the software's GPU implementations: +1. The number of atom types of a given system must be less than 128. +2. The maximum distance between an atom and its neighbors must be less than 128. It can be controlled by setting the rcut value of training parameters. +3. Theoretically, the maximum number of atoms that a single GPU can accept is about 10,000,000. However, this value is limited by the GPU memory size currently, usually within 1000,000 atoms even in the model compression mode. +4. The total sel value of training parameters(in `model/descriptor` section) must be less than 4096. +5. The size of the last layer of the embedding net must be less than 1024 during the model compression process. diff --git a/doc/train/index.md b/doc/train/index.md index b9086d8322..f37c1a55ce 100644 --- a/doc/train/index.md +++ b/doc/train/index.md @@ -3,6 +3,8 @@ - [Training a model](training.md) - [Advanced options](training-advanced.md) - [Parallel training](parallel-training.md) +- [multi-task training](multi-task-training.md) - [TensorBoard Usage](tensorboard.md) - [Known limitations of using GPUs](gpu-limitations.md) - [Training Parameters](../train-input-auto.rst) +- [Finetuning the Pretrained Model](finetuning.md) diff --git a/doc/train/index.rst b/doc/train/index.rst index a3114dc844..f8b792e33f 100644 --- a/doc/train/index.rst +++ b/doc/train/index.rst @@ -8,5 +8,7 @@ Training training-advanced train-input parallel-training + multi-task-training tensorboard - gpu-limitations \ No newline at end of file + gpu-limitations + finetuning \ No newline at end of file diff --git a/doc/train/multi-task-training.md b/doc/train/multi-task-training.md new file mode 100644 index 0000000000..3ad30e7339 --- /dev/null +++ b/doc/train/multi-task-training.md @@ -0,0 +1,34 @@ +# Multi-task training + +Training on multiple data sets (each data set contains several data systems) can be performed in multi-task mode, +with one common descriptor and multiple specific fitting nets for each data set. +One can simply switch the following parameters in training input script to perform multi-task mode: +- {ref}`fitting_net ` --> {ref}`fitting_net_dict `, +each key of which can be one individual fitting net. +- {ref}`training_data `, {ref}`validation_data ` +--> {ref}`data_dict `, each key of which can be one individual data set contains +several data systems for corresponding fitting net, the keys must be consistent with those in +{ref}`fitting_net_dict `. +- {ref}`loss ` --> {ref}`loss_dict `, each key of which can be one individual loss setting +for corresponding fitting net, the keys must be consistent with those in +{ref}`fitting_net_dict `, if not set, the corresponding fitting net will use the default loss. +- (Optional) {ref}`fitting_weight `, each key of which can be a non-negative integer or float, +deciding the chosen probability for corresponding fitting net in training, if not set or invalid, +the corresponding fitting net will not be used. + +The training procedure will automatically choose single-task or multi-task mode, based on the above parameters. +Note that parameters of single-task mode and multi-task mode can not be mixed. + +The supported descriptors for multi-task mode are listed: +- {ref}`se_a (se_e2_a) ` +- {ref}`se_r (se_e2_r) ` +- {ref}`se_at (se_e3) ` +- {ref}`se_atten ` +- {ref}`hybrid ` + +The supported fitting nets for multi-task mode are listed: +- {ref}`ener ` +- {ref}`dipole ` +- {ref}`polar ` + +The output of `dp freeze` command in multi-task mode can be seen in [freeze command](../freeze/freeze.md). diff --git a/doc/train/parallel-training.md b/doc/train/parallel-training.md index c8d3d29aad..2a8cd72664 100644 --- a/doc/train/parallel-training.md +++ b/doc/train/parallel-training.md @@ -1,15 +1,15 @@ # Parallel training -Currently, parallel training is enabled in a sychoronized way with help of [Horovod](https://github.com/horovod/horovod). -Depend on the number of training processes (according to MPI context) and number of GPU cards avaliable, DeePMD-kit will decide whether to launch the training in parallel (distributed) mode or in serial mode. Therefore, no additional options is specified in your JSON/YAML input file. +Currently, parallel training is enabled in a synchronized way with help of [Horovod](https://github.com/horovod/horovod). +Depending on the number of training processes (according to MPI context) and the number of GPU cards available, DeePMD-kit will decide whether to launch the training in parallel (distributed) mode or in serial mode. Therefore, no additional options are specified in your JSON/YAML input file. ## Tuning learning rate Horovod works in the data-parallel mode, resulting in a larger global batch size. For example, the real batch size is 8 when {ref}`batch_size ` is set to 2 in the input file and you launch 4 workers. Thus, {ref}`learning_rate ` is automatically scaled by the number of workers for better convergence. Technical details of such heuristic rule are discussed at [Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour](https://arxiv.org/abs/1706.02677). -The number of decay steps required to achieve same accuracy can decrease by the number of cards (e.g., 1/2 of steps in the above case), but needs to be scaled manually in the input file. +The number of decay steps required to achieve the same accuracy can decrease by the number of cards (e.g., 1/2 of steps in the above case), but needs to be scaled manually in the input file. -In some cases, it won't work well when scale learning rate by worker count in a `linear` way. Then you can try `sqrt` or `none` by setting argument {ref}`scale_by_worker ` like below. +In some cases, it won't work well when scaling the learning rate by worker count in a `linear` way. Then you can try `sqrt` or `none` by setting argument {ref}`scale_by_worker ` like below. ```json "learning_rate" :{ "scale_by_worker": "none", @@ -19,7 +19,7 @@ In some cases, it won't work well when scale learning rate by worker count in a ## Scaling test -Testing `examples/water/se_e2_a` on a 8-GPU host, linear acceleration can be observed with increasing number of cards. +Testing `examples/water/se_e2_a` on an 8-GPU host, linear acceleration can be observed with the increasing number of cards. | Num of GPU cards | Seconds every 100 samples | Samples per second | Speed up | | -- | -- | -- | -- | @@ -37,18 +37,18 @@ CUDA_VISIBLE_DEVICES=4,5,6,7 horovodrun -np 4 \ dp train --mpi-log=workers input.json ``` -Need to mention, environment variable `CUDA_VISIBLE_DEVICES` must be set to control parallelism on the occupied host where one process is bound to one GPU card. +Need to mention, the environment variable `CUDA_VISIBLE_DEVICES`` must be set to control parallelism on the occupied host where one process is bound to one GPU card. -Note that `OMP_NUM_THREADS`, `TF_INTRA_OP_PARALLELISM_THREADS`, and `TF_INTER_OP_PARALLELISM_THREADS` should be carefully adjusted to achieve the best performance. +To maximize the performance, one should follow [FAQ: How to control the parallelism of a job](../troubleshooting/howtoset_num_nodes.md) to control the number of threads. -When using MPI with Horovod, `horovodrun` is a simple wrapper around `mpirun`. In the case where fine-grained control over options passed to `mpirun`, [`mpirun` can be invoked directly](https://horovod.readthedocs.io/en/stable/mpi_include.html), and it will be detected automatically by Horovod, e.g., +When using MPI with Horovod, `horovodrun` is a simple wrapper around `mpirun`. In the case where fine-grained control over options is passed to `mpirun`, [`mpirun` can be invoked directly](https://horovod.readthedocs.io/en/stable/mpi_include.html), and it will be detected automatically by Horovod, e.g., ```bash CUDA_VISIBLE_DEVICES=4,5,6,7 mpirun -l -launcher=fork -hosts=localhost -np 4 \ dp train --mpi-log=workers input.json ``` -this is sometimes neccessary on HPC environment. +this is sometimes necessary for an HPC environment. -Whether distributed workers are initiated can be observed at the "Summary of the training" section in the log (`world size` > 1, and `distributed`). +Whether distributed workers are initiated can be observed in the "Summary of the training" section in the log (`world size` > 1, and `distributed`). ``` [0] DEEPMD INFO ---Summary of the training--------------------------------------- [0] DEEPMD INFO distributed @@ -66,7 +66,7 @@ Whether distributed workers are initiated can be observed at the "Summary of the ## Logging -What's more, 2 command-line arguments are defined to control the logging behvaior when performing parallel training with MPI. +What's more, 2 command-line arguments are defined to control the logging behavior when performing parallel training with MPI. ``` optional arguments: -l LOG_PATH, --log-path LOG_PATH diff --git a/doc/train/tensorboard.md b/doc/train/tensorboard.md index 17b0384d66..922f9ac49b 100644 --- a/doc/train/tensorboard.md +++ b/doc/train/tensorboard.md @@ -1,17 +1,17 @@ # TensorBoard Usage TensorBoard provides the visualization and tooling needed for machine learning -experimentation. A full instruction of tensorboard can be found +experimentation. Full instructions for TensorBoard can be found [here](https://tensorflow.google.cn/tensorboard). ## Highlighted features -DeePMD-kit can now use most of the interesting features enabled by tensorboard! +DeePMD-kit can now use most of the interesting features enabled by TensorBoard! * **Tracking and visualizing metrics,** such as l2_loss, l2_energy_loss and l2_force_loss * **Visualizing the model graph** (ops and layers) * **Viewing histograms of weights, biases, or other tensors as they change over time.** -* **Viewing summaries of trainable viriables** +* **Viewing summaries of trainable variables** @@ -19,8 +19,7 @@ DeePMD-kit can now use most of the interesting features enabled by tensorboard! ## How to use Tensorboard with DeePMD-kit Before running TensorBoard, make sure you have generated summary data in a log -directory by modifying the the input script, set {ref}`tensorboard ` to true in training -subsection will enable the tensorboard data analysis. eg. **water_se_a.json**. +directory by modifying the input script, setting {ref}`tensorboard ` to true in the training subsection will enable the TensorBoard data analysis. eg. **water_se_a.json**. ```json "training" : { @@ -53,7 +52,7 @@ subsection will enable the tensorboard data analysis. eg. **water_se_a.json**. Once you have event files, run TensorBoard and provide the log directory. This should print that TensorBoard has started. Next, connect to http://tensorboard_server_ip:6006. -TensorBoard requires a logdir to read logs from. For info on configuring TensorBoard, run tensorboard --help. +TensorBoard requires a logdir to read logs from. For info on configuring TensorBoard, run TensorBoard --help. One can easily change the log name with "tensorboard_log_dir" and the sampling frequency with "tensorboard_freq". ```bash @@ -64,24 +63,24 @@ tensorboard --logdir path/to/logs ### Tracking and visualizing loss metrics(red:train, blue:test) -![ALT](../images/l2_loss.png "l2 loss") +![l2 loss](../images/l2_loss.png) -![ALT](../images/l2_energy_loss.png "l2 energy loss") +![l2 energy loss](../images/l2_energy_loss.png) -![ALT](../images/l2_force_loss.png "l2 force loss") +![l2 force loss](../images/l2_force_loss.png) -### Visualizing deepmd-kit model graph +### Visualizing DeePMD-kit model graph -![ALT](../images/tensorboard-graph.png "deepmd-kit graph") +![DeePMD-kit graph](../images/tensorboard-graph.png) ### Viewing histograms of weights, biases, or other tensors as they change over time -![ALT](../images/tensorboard-histograms.png "deepmd-kit histograms") +![DeePMD-kit histograms](../images/tensorboard-histograms.png) -![ALT](../images/tensorboard-distribution.png "deepmd-kit distribution") +![DeePMD-kit distribution](../images/tensorboard-distribution.png) ### Viewing summaries of trainable variables -![ALT](../images/tensorboard-scalar.png "deepmd-kit scalar") +![DeePMD-kit scalar](../images/tensorboard-scalar.png) ## Attention diff --git a/doc/train/train-input.rst b/doc/train/train-input.rst index e2aa45a522..fdf2db9fec 100644 --- a/doc/train/train-input.rst +++ b/doc/train/train-input.rst @@ -5,20 +5,5 @@ Training Parameters .. dargs:: :module: deepmd.utils.argcheck - :func: model_args + :func: gen_args -.. dargs:: - :module: deepmd.utils.argcheck - :func: learning_rate_args - -.. dargs:: - :module: deepmd.utils.argcheck - :func: loss_args - -.. dargs:: - :module: deepmd.utils.argcheck - :func: training_args - -.. dargs:: - :module: deepmd.utils.argcheck - :func: nvnmd_args diff --git a/doc/train/training-advanced.md b/doc/train/training-advanced.md index 98e12b4773..0fef1fa6a3 100644 --- a/doc/train/training-advanced.md +++ b/doc/train/training-advanced.md @@ -56,11 +56,11 @@ The sections {ref}`training_data ` and {ref}`validation_ * {ref}`systems ` provide paths of the training data systems. DeePMD-kit allows you to provide multiple systems with different numbers of atoms. This key can be a `list` or a `str`. * `list`: {ref}`systems ` gives the training data systems. * `str`: {ref}`systems ` should be a valid path. DeePMD-kit will recursively search all data systems in this path. -* At each training step, DeePMD-kit randomly pick {ref}`batch_size ` frame(s) from one of the systems. The probability of using a system is by default in proportion to the number of batches in the system. More optional are available for automatically determining the probability of using systems. One can set the key {ref}`auto_prob ` to +* At each training step, DeePMD-kit randomly picks {ref}`batch_size ` frame(s) from one of the systems. The probability of using a system is by default in proportion to the number of batches in the system. More options are available for automatically determining the probability of using systems. One can set the key {ref}`auto_prob ` to * `"prob_uniform"` all systems are used with the same probability. - * `"prob_sys_size"` the probability of using a system is in proportional to its size (number of frames). - * `"prob_sys_size; sidx_0:eidx_0:w_0; sidx_1:eidx_1:w_1;..."` the `list` of systems are divided into blocks. The block `i` has systems ranging from `sidx_i` to `eidx_i`. The probability of using a system from block `i` is in proportional to `w_i`. Within one block, the probability of using a system is in proportional to its size. -* An example of using `"auto_prob"` is given as below. The probability of using `systems[2]` is 0.4, and the sum of the probabilities of using `systems[0]` and `systems[1]` is 0.6. If the number of frames in `systems[1]` is twice as `system[0]`, then the probability of using `system[1]` is 0.4 and that of `system[0]` is 0.2. + * `"prob_sys_size"` the probability of using a system is proportional to its size (number of frames). + * `"prob_sys_size; sidx_0:eidx_0:w_0; sidx_1:eidx_1:w_1;..."` the `list` of systems is divided into blocks. Block `i` has systems ranging from `sidx_i` to `eidx_i`. The probability of using a system from block `i` is proportional to `w_i`. Within one block, the probability of using a system is proportional to its size. +* An example of using `"auto_prob"` is given below. The probability of using `systems[2]` is 0.4, and the sum of the probabilities of using `systems[0]` and `systems[1]` is 0.6. If the number of frames in `systems[1]` is twice of `system[0]`, then the probability of using `system[1]` is 0.4 and that of `system[0]` is 0.2. ```json "training_data": { "systems": ["../data_water/data_0/", "../data_water/data_1/", "../data_water/data_2/"], @@ -68,7 +68,7 @@ The sections {ref}`training_data ` and {ref}`validation_ "batch_size": "auto" } ``` -* The probability of using systems can also be specified explicitly with key {ref}`sys_probs ` that is a list having the length of the number of systems. For example +* The probability of using systems can also be specified explicitly with key {ref}`sys_probs ` which is a list having the length of the number of systems. For example ```json "training_data": { "systems": ["../data_water/data_0/", "../data_water/data_1/", "../data_water/data_2/"], @@ -83,19 +83,19 @@ The sections {ref}`training_data ` and {ref}`validation_ * `"auto:N"`: automatically determines the batch size so that the {ref}`batch_size ` times the number of atoms in the system is no less than `N`. * The key {ref}`numb_batch ` in {ref}`validate_data ` gives the number of batches of model validation. Note that the batches may not be from the same system -The section {ref}`mixed_precision ` specifies the mixed precision settings, which will enable the mixed precision training workflow for deepmd-kit. The keys are explained below: +The section {ref}`mixed_precision ` specifies the mixed precision settings, which will enable the mixed precision training workflow for DeePMD-kit. The keys are explained below: * {ref}`output_prec ` precision used in the output tensors, only `float32` is supported currently. * {ref}`compute_prec ` precision used in the computing tensors, only `float16` is supported currently. -Note there are severial limitations about the mixed precision training: +Note there are several limitations about mixed precision training: * Only {ref}`se_e2_a ` type descriptor is supported by the mixed precision training workflow. -* The precision of embedding net and fitting net are forced to be set to `float32`. +* The precision of the embedding net and the fitting net are forced to be set to `float32`. Other keys in the {ref}`training ` section are explained below: * {ref}`numb_steps ` The number of training steps. * {ref}`seed ` The random seed for getting frames from the training data set. * {ref}`disp_file ` The file for printing learning curve. * {ref}`disp_freq ` The frequency of printing learning curve. Set in the unit of training steps -* {ref}`save_freq ` The frequency of saving check point. +* {ref}`save_freq ` The frequency of saving checkpoint. ## Options and environment variables @@ -129,25 +129,7 @@ optional arguments: **`--skip-neighbor-stat`** will skip calculating neighbor statistics if one is concerned about performance. Some features will be disabled. -To get the best performance, one should control the number of threads used by DeePMD-kit. This is achieved by three environmental variables: `OMP_NUM_THREADS`, `TF_INTRA_OP_PARALLELISM_THREADS` and `TF_INTER_OP_PARALLELISM_THREADS`. `OMP_NUM_THREADS` controls the multithreading of DeePMD-kit implemented operations. `TF_INTRA_OP_PARALLELISM_THREADS` and `TF_INTER_OP_PARALLELISM_THREADS` controls `intra_op_parallelism_threads` and `inter_op_parallelism_threads`, which are Tensorflow configurations for multithreading. An explanation is found [here](https://www.intel.com/content/www/us/en/developer/articles/technical/maximize-tensorflow-performance-on-cpu-considerations-and-recommendations-for-inference.html). - -For example if you wish to use 3 cores of 2 CPUs on one node, you may set the environmental variables and run DeePMD-kit as follows: -```bash -export OMP_NUM_THREADS=3 -export TF_INTRA_OP_PARALLELISM_THREADS=3 -export TF_INTER_OP_PARALLELISM_THREADS=2 -dp train input.json -``` - -For a node with 128 cores, it is recommended to start with the following variables: - -```bash -export OMP_NUM_THREADS=16 -export TF_INTRA_OP_PARALLELISM_THREADS=16 -export TF_INTER_OP_PARALLELISM_THREADS=8 -``` - -It is encouraged to adjust the configurations after empirical testing. +To maximize the performance, one should follow [FAQ: How to control the parallelism of a job](../troubleshooting/howtoset_num_nodes.md) to control the number of threads. One can set other environmental variables: @@ -159,7 +141,7 @@ One can set other environmental variables: ## Adjust `sel` of a frozen model -One can use `--init-frz-model` features to adjust (increase or decrease) [`sel`](../model/sel.md) of a existing model. Firstly, one need to adjust [`sel`](./train-input.rst) in `input.json`. For example, adjust from `[46, 92]` to `[23, 46]`. +One can use `--init-frz-model` features to adjust (increase or decrease) [`sel`](../model/sel.md) of a existing model. Firstly, one needs to adjust [`sel`](./train-input.rst) in `input.json`. For example, adjust from `[46, 92]` to `[23, 46]`. ```json "model": { "descriptor": { @@ -182,4 +164,4 @@ dp freeze -o frozen_model_adjusted_sel.pb Two models should give the same result when the input satisfies both constraints. -Note: At this time, this feature is only supported by [`se_e2_a`](../model/train-se-e2-a.md) descriptor with [`set_davg_true`](./train-input.rst) enable, or `hybrid` composed of above descriptors. +Note: At this time, this feature is only supported by [`se_e2_a`](../model/train-se-e2-a.md) descriptor with [`set_davg_true`](./train-input.rst) enabled, or `hybrid` composed of the above descriptors. diff --git a/doc/train/training.md b/doc/train/training.md index 0c04b8196a..40aa4c0e8c 100644 --- a/doc/train/training.md +++ b/doc/train/training.md @@ -1,6 +1,6 @@ # Train a model -Several examples of training can be found at the `examples` directory: +Several examples of training can be found in the `examples` directory: ```bash $ cd $deepmd_source_dir/examples/water/se_e2_a/ ``` @@ -11,7 +11,7 @@ $ dp train input.json ``` where `input.json` is the name of the input script. -By default, the verbosity level of the DeePMD-kit is `INFO`, one may see a lot of important information on the code and environment showing on the screen. Among them two pieces of information regarding data systems worth special notice. +By default, the verbosity level of the DeePMD-kit is `INFO`, one may see a lot of important information on the code and environment showing on the screen. Among them two pieces of information regarding data systems are worth special notice. ```bash DEEPMD INFO ---Summary of DataSystem: training ----------------------------------------------- DEEPMD INFO found 3 system(s): @@ -26,9 +26,9 @@ DEEPMD INFO system natoms bch_sz n_bc DEEPMD INFO ../data_water/data_3 192 1 80 1.000 T DEEPMD INFO -------------------------------------------------------------------------------------- ``` -The DeePMD-kit prints detailed information on the training and validation data sets. The data sets are defined by {ref}`training_data ` and {ref}`validation_data ` defined in the {ref}`training ` section of the input script. The training data set is composed by three data systems, while the validation data set is composed by one data system. The number of atoms, batch size, number of batches in the system and the probability of using the system are all shown on the screen. The last column presents if the periodic boundary condition is assumed for the system. +The DeePMD-kit prints detailed information on the training and validation data sets. The data sets are defined by {ref}`training_data ` and {ref}`validation_data ` defined in the {ref}`training ` section of the input script. The training data set is composed of three data systems, while the validation data set is composed by one data system. The number of atoms, batch size, the number of batches in the system and the probability of using the system are all shown on the screen. The last column presents if the periodic boundary condition is assumed for the system. -During the training, the error of the model is tested every {ref}`disp_freq ` training steps with the batch used to train the model and with {ref}`numb_btch ` batches from the validating data. The training error and validation error are printed correspondingly in the file {ref}`disp_file ` (default is `lcurve.out`). The batch size can be set in the input script by the key {ref}`batch_size ` in the corresponding sections for training and validation data set. An example of the output +During the training, the error of the model is tested every {ref}`disp_freq ` training steps with the batch used to train the model and with {ref}`numb_btch ` batches from the validating data. The training error and validation error are printed correspondingly in the file {ref}`disp_file ` (default is `lcurve.out`). The batch size can be set in the input script by the key {ref}`batch_size ` in the corresponding sections for the training and validation data set. An example of the output ```bash # step rmse_val rmse_trn rmse_e_val rmse_e_trn rmse_f_val rmse_f_trn lr 0 3.33e+01 3.41e+01 1.03e+01 1.03e+01 8.39e-01 8.72e-01 1.0e-03 @@ -38,7 +38,7 @@ During the training, the error of the model is tested every {ref}`disp_freq ` every {ref}`save_freq ` training steps. +Checkpoints will be written to files with the prefix {ref}`save_ckpt ` every {ref}`save_freq ` training steps. :::{warning} -It is warned that the example water data (in folder `examples/water/data`) is of very limited amount, is provided only for testing purpose, and should not be used to train a production model. +It is warned that the example water data (in folder `examples/water/data`) is of very limited amount, is provided only for testing purposes, and should not be used to train a production model. ::: diff --git a/doc/troubleshooting/howtoset_num_nodes.md b/doc/troubleshooting/howtoset_num_nodes.md index 131732ea42..18c6a5962f 100644 --- a/doc/troubleshooting/howtoset_num_nodes.md +++ b/doc/troubleshooting/howtoset_num_nodes.md @@ -1,16 +1,73 @@ -# How to control the number of nodes used by a job ? +# How to control the parallelism of a job? -Set the number of CPU nodes used by DP algorithms with: +DeePMD-kit has three levels of parallelism. +To get the best performance, one should control the number of threads used by DeePMD-kit. +One should make sure the product of the parallel numbers is less than or equal to the number of cores available. + +## MPI (optional) + +Parallelism for MPI is optional and used for multiple nodes, multiple GPU cards, or sometimes multiple CPU cores. + +To enable MPI support for training, one should [install horovod](../install/install-from-source.md#install-horovod-and-mpi4py) in advance. Note that the parallelism mode is data parallelism, so it is not expected to see the training time per batch decreases. + +MPI support for inference is not directly supported by DeePMD-kit, but indirectly supported by the third-party software. For example, [LAMMPS enables running simulations in parallel](https://docs.lammps.org/Developer_parallel.html) using the MPI parallel communication standard with distributed data. That software has to build against MPI. + +Set the number of processes with: ```bash mpirun -np $num_nodes dp ``` -Set the number of threads used by DP algorithms with: +Note that `mpirun` here should be the same as the MPI used to build software. For example, one can use `mpirun -h` and `lmp -h` to see if `mpirun` and LAMMPS has the same MPI version. + +Sometimes, `$num_nodes` and the nodes information can be directly given by the HPC scheduler system, if the MPI used here is the same as the MPI used to build the scheduler system. Otherwise, one have to manually assign these information. + +## Parallelism between independent operators + +For CPU devices, TensorFlow use multiple streams to run independent operators (OP). + ```bash -export OMP_NUM_THREADS=$num_threads +export TF_INTER_OP_PARALLELISM_THREADS=3 ``` -Set the number of CPU nodes used by TF kernels with: +However, for GPU devices, TensorFlow uses only one compute stream and multiple copy streams. +Note that some of DeePMD-kit OPs do not have GPU support, so it is still encouraged to set environmental variables even if one has a GPU. + +## Parallelism within an individual operators + +For CPU devices, `TF_INTRA_OP_PARALLELISM_THREADS` controls parallelism within TensorFlow native OPs when TensorFlow is built against Eigen. + ```bash -export TF_INTRA_OP_PARALLELISM_THREADS=$num_nodes -export TF_INTER_OP_PARALLELISM_THREADS=$num_nodes +export TF_INTRA_OP_PARALLELISM_THREADS=2 ``` + +`OMP_NUM_THREADS` is threads for OpenMP parallelism. It controls parallelism within TensorFlow native OPs when TensorFlow is built by Intel OneDNN and DeePMD-kit custom CPU OPs. +It may also control parallelsim for NumPy when NumPy is built against OpenMP, so one who uses GPUs for training should also care this environmental variable. + +```bash +export OMP_NUM_THREADS=2 +``` + +There are several other environmental variables for OpenMP, such as `KMP_BLOCKTIME`. See [Intel documentation](https://www.intel.com/content/www/us/en/developer/articles/technical/maximize-tensorflow-performance-on-cpu-considerations-and-recommendations-for-inference.html) for detailed information. + +## Tune the performance + +There is no one general parallel configuration that works for all situations, so you are encouraged to tune parallel configurations yourself after empirical testing. + +Here are some empirical examples. +If you wish to use 3 cores of 2 CPUs on one node, you may set the environmental variables and run DeePMD-kit as follows: +```bash +export OMP_NUM_THREADS=3 +export TF_INTRA_OP_PARALLELISM_THREADS=3 +export TF_INTER_OP_PARALLELISM_THREADS=2 +dp train input.json +``` + +For a node with 128 cores, it is recommended to start with the following variables: + +```bash +export OMP_NUM_THREADS=16 +export TF_INTRA_OP_PARALLELISM_THREADS=16 +export TF_INTER_OP_PARALLELISM_THREADS=8 +``` + +Again, in general, one should make sure the product of the parallel numbers is less than or equal to the number of cores available. +In the above case, $16 \times 8 = 128$, so threads will not compete with each other. diff --git a/doc/troubleshooting/howtoset_rcut.md b/doc/troubleshooting/howtoset_rcut.md index f8ba56ccaa..fb0395a2f5 100644 --- a/doc/troubleshooting/howtoset_rcut.md +++ b/doc/troubleshooting/howtoset_rcut.md @@ -1,7 +1,7 @@ -# Do we need to set rcut < half boxsize ? +# Do we need to set rcut < half boxsize? -When seeking the neighbors of atom i under periodic boundary condition, deepmd-kit considers all j atoms within cutoff rcut from atom i in all mirror cells. +When seeking the neighbors of atom i under periodic boundary conditions, DeePMD-kit considers all j atoms within cutoff rcut from atom i in all mirror cells. -So, so there is no limitation on the setting of rcut. +So, there is no limitation on the setting of rcut. -PS: The reason why some softwares require rcut < half boxsize is that they only consider the nearest mirrors from the center cell. Deepmd-kit is totally different from them. +PS: The reason why some software requires rcut < half box size is that they only consider the nearest mirrors from the center cell. DeePMD-kit is different from them. diff --git a/doc/troubleshooting/howtoset_sel.md b/doc/troubleshooting/howtoset_sel.md index 915fdd3094..2c993491fc 100644 --- a/doc/troubleshooting/howtoset_sel.md +++ b/doc/troubleshooting/howtoset_sel.md @@ -1,10 +1,10 @@ -# How to set sel ? +# How to set sel? `sel` is short for "selected number of atoms in `rcut`". `sel_a[i]` is a list of integers. The length of the list should be the same as the number of atom types in the system. -`sel_a[i]` gives the number of selected number of type `i` neighbors within `rcut`. To ensure that the results are strictly accurate, `sel_a[i]` should be larger than the largest number of type `i` neighbors in the `rcut`. +`sel_a[i]` gives the number of the selected number of type `i` neighbors within `rcut`. To ensure that the results are strictly accurate, `sel_a[i]` should be larger than the largest number of type `i` neighbors in the `rcut`. However, the computation overhead increases with `sel_a[i]`, therefore, `sel_a[i]` should be as small as possible. diff --git a/doc/troubleshooting/index.md b/doc/troubleshooting/index.md index dcb8775501..a77d058811 100644 --- a/doc/troubleshooting/index.md +++ b/doc/troubleshooting/index.md @@ -1,14 +1,15 @@ # FAQs -In consequence of various differences of computers or systems, problems may occur. Some common circumstances are listed as follows. -In addition, some frequently asked questions about parameters setting are listed as follows. +As a consequence of differences in computers or systems, problems may occur. Some common circumstances are listed as follows. +In addition, some frequently asked questions are listed as follows. If other unexpected problems occur, you’re welcome to contact us for help. - [Model compatibility](model-compatability.md) - [Installation](installation.md) -- [The temperature undulates violently during early stages of MD](md-energy-undulation.md) +- [The temperature undulates violently during the early stages of MD](md-energy-undulation.md) - [MD: cannot run LAMMPS after installing a new version of DeePMD-kit](md-version-compatibility.md) - [Do we need to set rcut < half boxsize?](howtoset-rcut.md) - [How to set sel?](howtoset-sel.md) -- [How to control the number of nodes used by a job?](howtoset_num_nodes.md) -- [How to tune Fitting/embedding-net size?](howtoset_netsize.md) \ No newline at end of file +- [How to control the parallelism of a job?](howtoset_num_nodes.md) +- [How to tune Fitting/embedding-net size?](howtoset_netsize.md) +- [Why does a model have low precision?](precision.md) diff --git a/doc/troubleshooting/index.rst b/doc/troubleshooting/index.rst index 603309f302..f938d0973c 100644 --- a/doc/troubleshooting/index.rst +++ b/doc/troubleshooting/index.rst @@ -1,14 +1,14 @@ FAQs ==== -In consequence of various differences of computers or systems, problems may occur. Some common circumstances are listed as follows. -In addition, some frequently asked questions about parameters setting are listed as follows. +As a consequence of differences in computers or systems, problems may occur. Some common circumstances are listed as follows. +In addition, some frequently asked questions are listed as follows. If other unexpected problems occur, you're welcome to contact us for help. .. _trouble: .. toctree:: :maxdepth: 1 - :caption: Trouble shooting + :caption: Troubleshooting :glob: ./* \ No newline at end of file diff --git a/doc/troubleshooting/installation.md b/doc/troubleshooting/installation.md index 696b18d5c9..4d681aecda 100644 --- a/doc/troubleshooting/installation.md +++ b/doc/troubleshooting/installation.md @@ -1,6 +1,6 @@ # Installation ## Inadequate versions of gcc/g++ -Sometimes you may use a gcc/g++ of version < 4.8. In this way, you can still compile all the parts of TensorFlow and most of the parts of DeePMD-kit, but i-Pi and GROMACS plugin will be disabled automatically. Or if you have a gcc/g++ of version > 4.8, say, 7.2.0, you may choose to use it by doing +Sometimes you may use a gcc/g++ of version < 4.8. In this way, you can still compile all the parts of TensorFlow and most of the parts of DeePMD-kit, but i-Pi and GROMACS plugins will be disabled automatically. Or if you have a gcc/g++ of version > 4.8, say, 7.2.0, you may choose to use it by doing ```bash export CC=/path/to/gcc-7.2.0/bin/gcc export CXX=/path/to/gcc-7.2.0/bin/g++ diff --git a/doc/troubleshooting/md-energy-undulation.md b/doc/troubleshooting/md-energy-undulation.md index f45a21cd72..da743c7a0d 100644 --- a/doc/troubleshooting/md-energy-undulation.md +++ b/doc/troubleshooting/md-energy-undulation.md @@ -1,5 +1,5 @@ -# The temperature undulates violently during early stages of MD +# The temperature undulates violently during the early stages of MD -This is probably because your structure is too far from the equlibrium configuration. +This is probably because your structure is too far from the equilibrium configuration. -Although, to make sure the potential model is truly accurate, we recommend to check model deviation. +To make sure the potential model is truly accurate, we recommend checking model deviation. diff --git a/doc/troubleshooting/md-version-compatibility.md b/doc/troubleshooting/md-version-compatibility.md index dfc2e3abc2..3adfb26fbb 100644 --- a/doc/troubleshooting/md-version-compatibility.md +++ b/doc/troubleshooting/md-version-compatibility.md @@ -1,7 +1,7 @@ # MD: cannot run LAMMPS after installing a new version of DeePMD-kit This typically happens when you install a new version of DeePMD-kit and copy directly the generated `USER-DEEPMD` to a LAMMPS source code folder and re-install LAMMPS. -To solve this problem, it suffices to first remove `USER-DEEPMD` from LAMMPS source code by +To solve this problem, it suffices to first remove `USER-DEEPMD` from the LAMMPS source code by ```bash make no-user-deepmd ``` diff --git a/doc/troubleshooting/model-compatability.md b/doc/troubleshooting/model-compatability.md index 9ed9607bbb..0db5f57a16 100644 --- a/doc/troubleshooting/model-compatability.md +++ b/doc/troubleshooting/model-compatability.md @@ -1,8 +1,8 @@ # Model compatibility -When the version of DeePMD-kit used to training model is different from the that of DeePMD-kit running MDs, one has the problem of model compatibility. +When the version of DeePMD-kit used to train the model is different from the that of DeePMD-kit running MDs, one has the problem of model compatibility. -DeePMD-kit guarantees that the codes with the same major and minor revisions are compatible. That is to say v0.12.5 is compatible to v0.12.0, but is not compatible to v0.11.0 nor v1.0.0. +DeePMD-kit guarantees that the codes with the same major and minor revisions are compatible. That is to say, v0.12.5 is compatible with v0.12.0, but is not compatible with v0.11.0 or v1.0.0. One can execute `dp convert-from` to convert an old model to a new one. diff --git a/doc/troubleshooting/precision.md b/doc/troubleshooting/precision.md new file mode 100644 index 0000000000..074552068f --- /dev/null +++ b/doc/troubleshooting/precision.md @@ -0,0 +1,75 @@ +# Why does a model have low precision? + +Many phenomena are caused by model accuracy. +For example, during simulations, temperatures explode, structures fall apart, and atoms are lost. +One can [test the model](../test/test.md) to confirm whether the model has the enough accuracy. + +There are many reasons for a low-quality model. +Some common reasons are listed below. + +## Data + +### Data units and signs + +The unit of training data should follow what is listed in [data section](../data/system.md). +Usually, the package to calculate the training data has different units from those of the DeePMD-kit. +It is noted that some software label the energy gradient as forces, instead of the negative energy gradient. +It is neccessary to check them carefully to avoid inconsistent data. + +### SCF coverage and data accuracy + +The accuracy of models will not exceed the accuracy of training data, so the training data should reach enough accuracy. +Here is a checklist for the accuracy of data: +- SCF should converge to a suitable threshold for all points in the training data. +- The convergence of the energy, force and virial with respect to the energy cutoff and k-spacing sample is checked. +- Sometimes, QM software may generate unstable outliers, which should be removed. +- The data should be extracted with enough digits and stored with the proper precision. Large energies may have low precision when they are stored as the single-precision floating-point format (FP32). + +### Enough data + +If the model performs good on the training data, but has bad accuracy on another data, this means some data space is not covered by the training data. +It can be validated by evaluting the [model deviation](../test/model-deviation.md) with multiple models. +If the model deviation of these data is high for some data, try to collect more data using [DP-GEN](../third-party/out-of-deepmd-kit.md#dp-gen). + +### Values of data + +One should be aware that the errors of some data is also affected by the absolute values of this data. +Stable structures tend to be more precise than unstable structures because unstable structures may have larger forces. +Also, errors will be introduced in the Projector augmented wave (PAW) DFT calculations when the atoms are very close due to the overlap of pseudo-potentials. +It is expected to see that data with large forces has larger errors and it is better to compare different models only with the same data. + +## Model + +### Enough `sel` + +The [`sel`](../model/sel.md) of the descriptors must be enough for both training and test data. +Otherwise, the model will be unreliable and give wrong results. + +### Cutoff radius + +The model cannot fit the long-term interaction out of the cutoff radius. +This is a designed approximation for performance, but one has to choose proper cutoff radius for the system. + +### Neural network size + +The size of neural networks will affect the accuracy, but if one follows the parameters in the examples, this effect is insignificant. +See [FAQ: How to tune Fitting/embedding-net size](./howtoset_netsize.md) for details. + +### Neural network precision + +In some cases, one may want to use the FP32 precision to make the model faster. +For some applications, FP32 is enough and thus is recommended, but one should still be aware that the precision of FP32 is not as high as that of FP64. + +## Training + +### Training steps + +Generally speaking, the longer the number of training steps, the better the model. +A balance between model accuracy and training time can be achieved. +If one finds that model accuracy decreases with training time, there may be a problem with the data. See the [data section](#data) for details. + +### Learning rate + +Both too large and too small learning rate may affect the training. +It is recommended to start with a large learning rate and end with a small learning rate. +The learning rate from the examples is a good choice to start. diff --git a/examples/infer_water/.gitignore b/examples/infer_water/.gitignore new file mode 100644 index 0000000000..2102f49b3e --- /dev/null +++ b/examples/infer_water/.gitignore @@ -0,0 +1,10 @@ +cmake_install.cmake +Makefile +CMakeCache.txt +CMakeFiles +infer_water_cc +infer_water_c +infer_water +infer_water_hpp +infer_water_nlist +graph.pb diff --git a/examples/infer_water/CMakeLists.txt b/examples/infer_water/CMakeLists.txt new file mode 100644 index 0000000000..27b7541c2d --- /dev/null +++ b/examples/infer_water/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.7) +project(infer_water) + +# find DeePMD-kit +find_package(DeePMD REQUIRED) + +# C++ example +add_executable(infer_water_cc infer_water.cpp) +# link DeePMD-kit C++ API +target_link_libraries(infer_water_cc PRIVATE DeePMD::deepmd_cc) + +# C example +add_executable(infer_water_c infer_water.c) +# link DeePMD-kit C API +target_link_libraries(infer_water_c PRIVATE DeePMD::deepmd_c) + +# header-only example +add_executable(infer_water_hpp infer_water_hpp.cpp) +# link DeePMD-kit C API +target_link_libraries(infer_water_hpp PRIVATE DeePMD::deepmd_c) + +# nlist +add_executable(infer_water_nlist infer_water_nlist.cpp) +# link DeePMD-kit C API +target_link_libraries(infer_water_nlist PRIVATE DeePMD::deepmd_c) diff --git a/examples/infer_water/README.md b/examples/infer_water/README.md new file mode 100644 index 0000000000..290dd8cd1d --- /dev/null +++ b/examples/infer_water/README.md @@ -0,0 +1,10 @@ +# infer_water based on C/C++ API + +This is a project based on C/C++ API described in the documentation. + +Build the project using + +```sh +cmake -DCMAKE_PREFIX_PATH=$deepmd_root . +make +``` diff --git a/examples/infer_water/infer_water.c b/examples/infer_water/infer_water.c new file mode 100644 index 0000000000..0be6d0cf60 --- /dev/null +++ b/examples/infer_water/infer_water.c @@ -0,0 +1,32 @@ +#include +#include +#include "deepmd/c_api.h" + +int main(){ + const char* model = "graph.pb"; + double coord[] = {1., 0., 0., 0., 0., 1.5, 1. ,0. ,3.}; + double cell[] = {10., 0., 0., 0., 10., 0., 0., 0., 10.}; + int atype[] = {1, 0, 1}; + // init C pointers with given memory + double* e = malloc(sizeof(*e)); + double* f = malloc(sizeof(*f) * 9); // natoms * 3 + double* v = malloc(sizeof(*v) * 9); + double* ae = malloc(sizeof(*ae) * 9); // natoms + double* av = malloc(sizeof(*av) * 27); // natoms * 9 + // DP model + DP_DeepPot* dp = DP_NewDeepPot(model); + DP_DeepPotCompute (dp, 3, coord, atype, cell, e, f, v, ae, av); + // print results + printf("energy: %f\n", *e); + for (int ii = 0; ii < 9; ++ii) + printf("force[%d]: %f\n", ii, f[ii]); + for (int ii = 0; ii < 9; ++ii) + printf("force[%d]: %f\n", ii, v[ii]); + // free memory + free(e); + free(f); + free(v); + free(ae); + free(av); + free(dp); +} \ No newline at end of file diff --git a/examples/infer_water/infer_water.cpp b/examples/infer_water/infer_water.cpp new file mode 100644 index 0000000000..3697ba588c --- /dev/null +++ b/examples/infer_water/infer_water.cpp @@ -0,0 +1,11 @@ +#include "deepmd/DeepPot.h" + +int main(){ + deepmd::DeepPot dp ("graph.pb"); + std::vector coord = {1., 0., 0., 0., 0., 1.5, 1. ,0. ,3.}; + std::vector cell = {10., 0., 0., 0., 10., 0., 0., 0., 10.}; + std::vector atype = {1, 0, 1}; + double e; + std::vector f, v; + dp.compute (e, f, v, coord, atype, cell); +} diff --git a/examples/infer_water/infer_water_hpp.cpp b/examples/infer_water/infer_water_hpp.cpp new file mode 100644 index 0000000000..1c73ebd600 --- /dev/null +++ b/examples/infer_water/infer_water_hpp.cpp @@ -0,0 +1,19 @@ +/* header only C++ library +*/ +#include "deepmd/deepmd.hpp" + +int main(){ + deepmd::hpp::DeepPot dp ("graph.pb"); + std::vector coord = {1., 0., 0., 0., 0., 1.5, 1. ,0. ,3.}; + std::vector cell = {10., 0., 0., 0., 10., 0., 0., 0., 10.}; + std::vector atype = {1, 0, 1}; + double e; + std::vector f, v; + dp.compute (e, f, v, coord, atype, cell); + // print results + printf("energy: %f\n", e); + for (int ii = 0; ii < 9; ++ii) + printf("force[%d]: %f\n", ii, f[ii]); + for (int ii = 0; ii < 9; ++ii) + printf("force[%d]: %f\n", ii, v[ii]); +} diff --git a/examples/infer_water/infer_water_nlist.cpp b/examples/infer_water/infer_water_nlist.cpp new file mode 100644 index 0000000000..f45fd04585 --- /dev/null +++ b/examples/infer_water/infer_water_nlist.cpp @@ -0,0 +1,41 @@ +/** + * Infer water using a neighbor list +*/ + +#ifdef USE_NATIVE_CXX_API +#include "deepmd/DeepPot.h" +using deepmd::DeepPot; +using deepmd::InputNlist; +using deepmd::convert_nlist; +#else +#include "deepmd/deepmd.hpp" +using deepmd::hpp::DeepPot; +using deepmd::hpp::InputNlist; +using deepmd::hpp::convert_nlist; +#endif + +int main(){ + DeepPot dp ("graph.pb"); + std::vector coord = {1., 0., 0., 0., 0., 1.5, 1. ,0. ,3.}; + std::vector cell = {10., 0., 0., 0., 10., 0., 0., 0., 10.}; + std::vector atype = {1, 0, 1}; + // neighbor list + std::vector> nlist_vec = { + {1, 2}, + {0, 2}, + {0, 1} + }; + double e; + std::vector f, v; + std::vector ilist(3), numneigh(3); + std::vector firstneigh(3); + InputNlist nlist(3, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(nlist, nlist_vec); + dp.compute (e, f, v, coord, atype, cell, 0, nlist, 0); + // print results + printf("energy: %f\n", e); + for (int ii = 0; ii < 9; ++ii) + printf("force[%d]: %f\n", ii, f[ii]); + for (int ii = 0; ii < 9; ++ii) + printf("force[%d]: %f\n", ii, v[ii]); +} diff --git a/examples/water_multi_task/ener_dipole/input.json b/examples/water_multi_task/ener_dipole/input.json new file mode 100644 index 0000000000..df60e3b763 --- /dev/null +++ b/examples/water_multi_task/ener_dipole/input.json @@ -0,0 +1,105 @@ +{ + "_comment": "that's all", + "model": { + "type_map": ["O", "H"], + "descriptor": { + "type": "se_e2_a", + "sel": [46, 92], + "rcut_smth": 0.5, + "rcut": 6.0, + "neuron": [25, 50, 100], + "resnet_dt": false, + "axis_neuron": 16, + "seed": 1, + "_comment": " that's all" + }, + "fitting_net_dict": { + "water_dipole": { + "type": "dipole", + "sel_type": [0], + "neuron": [100, 100, 100], + "resnet_dt": true, + "seed": 1, + "_comment": " that's all" + }, + "water_ener": { + "neuron": [240, 240, 240], + "resnet_dt": true, + "seed": 1, + "_comment": " that's all" + } + }, + "_comment": " that's all" + }, + "learning_rate": { + "type": "exp", + "decay_steps": 5000, + "start_lr": 0.001, + "stop_lr": 3.51e-08, + "_comment": "that's all" + }, + "loss_dict": { + "water_dipole": { + "type": "tensor", + "pref": 1.0, + "pref_atomic": 1.0, + "_comment": " that's all" + }, + "water_ener": { + "type": "ener", + "start_pref_e": 0.02, + "limit_pref_e": 1, + "start_pref_f": 1000, + "limit_pref_f": 1, + "start_pref_v": 0, + "limit_pref_v": 0, + "_comment": " that's all" + } + }, + "training": { + "data_dict": { + "water_dipole": { + "training_data": { + "systems": [ + "../../water_tensor/dipole/training_data/atomic_system", + "../../water_tensor/dipole/training_data/global_system" + ], + "batch_size": "auto", + "_comment": "that's all" + }, + "validation_data": { + "systems": [ + "../../water_tensor/dipole/validation_data/atomic_system", + "../../water_tensor/dipole/validation_data/global_system" + ], + "batch_size": 1, + "numb_btch": 3, + "_comment": "that's all" + } + }, + "water_ener": { + "training_data": { + "systems": ["../../water/data/data_0/", "../../water/data/data_1/", "../../water/data/data_2/"], + "batch_size": "auto", + "_comment": "that's all" + }, + "validation_data": { + "systems": ["../../water/data/data_3/"], + "batch_size": 1, + "numb_btch": 3, + "_comment": "that's all" + } + } + }, + "fitting_weight": { + "water_dipole": 10, + "water_ener": 20 + }, + "numb_steps": 1000000, + "seed": 10, + "disp_file": "lcurve.out", + "disp_freq": 100, + "save_freq": 1000, + "_comment": "that's all" + } +} \ No newline at end of file diff --git a/examples/water_tensor/dipole/training_data/atomic_system/type_map.raw b/examples/water_tensor/dipole/training_data/atomic_system/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/examples/water_tensor/dipole/training_data/atomic_system/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/examples/water_tensor/dipole/training_data/global_system/type_map.raw b/examples/water_tensor/dipole/training_data/global_system/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/examples/water_tensor/dipole/training_data/global_system/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/examples/water_tensor/dipole/validation_data/atomic_system/type_map.raw b/examples/water_tensor/dipole/validation_data/atomic_system/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/examples/water_tensor/dipole/validation_data/atomic_system/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/examples/water_tensor/dipole/validation_data/global_system/type_map.raw b/examples/water_tensor/dipole/validation_data/global_system/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/examples/water_tensor/dipole/validation_data/global_system/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/examples/water_tensor/polar/training_data/atomic_system/type_map.raw b/examples/water_tensor/polar/training_data/atomic_system/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/examples/water_tensor/polar/training_data/atomic_system/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/examples/water_tensor/polar/training_data/global_system/type_map.raw b/examples/water_tensor/polar/training_data/global_system/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/examples/water_tensor/polar/training_data/global_system/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/examples/water_tensor/polar/validation_data/atomic_system/type_map.raw b/examples/water_tensor/polar/validation_data/atomic_system/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/examples/water_tensor/polar/validation_data/atomic_system/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/examples/water_tensor/polar/validation_data/global_system/type_map.raw b/examples/water_tensor/polar/validation_data/global_system/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/examples/water_tensor/polar/validation_data/global_system/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/pyproject.toml b/pyproject.toml index 8d4bfad3eb..f377b80036 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,103 @@ [build-system] requires = [ - "setuptools", - "setuptools_scm", + "setuptools>=61", + "setuptools_scm[toml]>=6.2", "wheel", "scikit-build", "cmake", # see https://github.com/scikit-build/scikit-build/releases/tag/0.13.1 "ninja; platform_system!='Windows'", ] +build-backend = "dp_backend" +backend-path = ["backend"] +[project] +name = "deepmd-kit" +dynamic = ["version", "optional-dependencies", "entry-points"] +description = "A deep learning package for many-body potential energy representation and molecular dynamics" +authors = [ + {name = "DeepModeling"}, + {name = "Han Wang", email = "wang_han@iapcm.ac.cn"}, +] +license = {file = "LICENSE"} +classifiers = [ + "Programming Language :: Python :: 3.7", + "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", +] +dependencies = [ + 'numpy', + 'scipy', + 'pyyaml', + 'dargs >= 0.2.6', + 'python-hostlist >= 1.21', + 'typing_extensions; python_version < "3.7"', + 'importlib_metadata>=1.4; python_version < "3.8"', + 'h5py', + 'wcmatch', + 'packaging', +] +requires-python = ">=3.7" +readme = "README.md" +keywords = ["deepmd"] + +[project.urls] +Homepage = "https://github.com/deepmodeling/deepmd-kit" +documentation = "https://docs.deepmodeling.com/projects/deepmd-kit" +repository = "https://github.com/deepmodeling/deepmd-kit" + +[tool.setuptools_scm] +write_to = "deepmd/_version.py" + +[tool.cibuildwheel] +test-command = [ + "dp -h", +] +test-extras = ["cpu"] +build = ["cp310-*"] +skip = ["*-win32", "*-manylinux_i686", "*-musllinux*"] +# TODO: bump to "latest" tag when CUDA supports GCC 12 +manylinux-x86_64-image = "quay.io/pypa/manylinux_2_28_x86_64:2022-11-19-1b19e81" +manylinux-aarch64-image = "quay.io/pypa/manylinux_2_28_aarch64:2022-11-19-1b19e81" + +[tool.cibuildwheel.macos] +environment = { DP_LAMMPS_VERSION="stable_23Jun2022_update2" } +before-all = ["brew install mpich"] +repair-wheel-command = "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel} --ignore-missing-dependencies" +test-extras = ["cpu", "test", "lmp"] +test-command = [ + "dp -h", + "pytest {project}/source/tests/test_lammps.py" +] + +[tool.cibuildwheel.linux] +repair-wheel-command = "auditwheel repair --exclude libtensorflow_framework.so.2 --exclude libtensorflow_framework.so.1 --exclude libtensorflow_framework.so --exclude _pywrap_tensorflow_internal.so -w {dest_dir} {wheel}" +environment-pass = ["CIBW_BUILD", "DP_VARIANT"] +environment = { DP_VARIANT="cuda", DP_LAMMPS_VERSION="stable_23Jun2022_update2", MPI_HOME="/usr/lib64/mpich", PATH="/usr/lib64/mpich/bin:$PATH" } +before-all = [ + """{ if [ "$(uname -m)" = "x86_64" ] ; then yum config-manager --add-repo http://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo && yum install -y cuda-11-8; fi }""", + "yum install -y mpich-devel", +] + + +# selectively turn of lintner warnings, always include reasoning why any warning should +# be silenced + +# W504 - line break after binary operator - there is conflict between W503 and W504 in +# some lintners. One recomends line bread after and one before binary operator so we +# swith W504 off and recomend this coding style: +# a = (b + -> instead of -> a = (b +# c) + c) +[tool.autopep8] +ignore = "W504" + +# D413 - Missing blank line after last section - makes no sense only adds empy lines in +# docstrings +# D416 - Section name should end with a colon - only applicable to RST type docstrings, +# we are using numpy style +# D203 - 1 blank line required before class docstring - only adds unnecessary empty space +# D107 - Missing docstring in __init__ - Nupmy style documents __init__ parameters in +# class docstring +# D213 - Multi-line docstring summary should start at the second line - unnecessary waste +# of space, start on the first line +[tool.pydocstyle] +ignore = "D413, D416, D203, D107, D213" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 8cd273f803..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,10 +0,0 @@ -numpy -scipy -pyyaml -dargs >= 0.2.6 -python-hostlist >= 1.21 -typing_extensions; python_version < "3.7" -importlib_metadata>=1.4; python_version < "3.8" -h5py -wcmatch -packaging diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 0ae74b314d..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,22 +0,0 @@ -# selectively turn of lintner warnings, always include reasoning why any warning should -# be silenced - -# W504 - line break after binary operator - there is conflict between W503 and W504 in -# some lintners. One recomends line bread after and one before binary operator so we -# swith W504 off and recomend this coding style: -# a = (b + -> instead of -> a = (b -# c) + c) -[pep8] -ignore = W504 - -# D413 - Missing blank line after last section - makes no sense only adds empy lines in -# docstrings -# D416 - Section name should end with a colon - only applicable to RST type docstrings, -# we are using numpy style -# D203 - 1 blank line required before class docstring - only adds unnecessary empty space -# D107 - Missing docstring in __init__ - Nupmy style documents __init__ parameters in -# class docstring -# D213 - Multi-line docstring summary should start at the second line - unnecessary waste -# of space, start on the first line -[pydocstyle] -ignore = D413, D416, D203, D107, D213 \ No newline at end of file diff --git a/setup.py b/setup.py index 4803b043ee..76b2cbafd5 100644 --- a/setup.py +++ b/setup.py @@ -1,42 +1,16 @@ """Setup script for DeePMD-kit package.""" import os -import site -from importlib.machinery import FileFinder -from importlib.util import find_spec -from pathlib import Path -from sysconfig import get_path +import sys -from packaging.specifiers import SpecifierSet from skbuild import setup -from skbuild.cmaker import get_cmake_version -from skbuild.exceptions import SKBuildError +from wheel.bdist_wheel import bdist_wheel -# define constants -INSTALL_REQUIRES = (Path(__file__).parent / "requirements.txt").read_text().splitlines() -setup_requires = ["setuptools_scm", "scikit-build"] +topdir = os.path.abspath(os.path.dirname(__file__)) +sys.path.insert(0, os.path.join(topdir, 'backend')) -# read readme to markdown -readme_file = Path(__file__).parent / "README.md" -readme = readme_file.read_text(encoding="utf-8") +from find_tensorflow import find_tensorflow, get_tf_requirement, get_tf_version -tf_version = os.environ.get("TENSORFLOW_VERSION", "") - -if tf_version == "": - extras_require = { - "cpu": ["tensorflow-cpu"], - "gpu": ["tensorflow"], - } -elif tf_version in SpecifierSet("<1.15") or tf_version in SpecifierSet(">=2.0,<2.1"): - extras_require = { - "cpu": [f"tensorflow=={tf_version}"], - "gpu": [f"tensorflow-gpu=={tf_version}"], - } -else: - extras_require = { - "cpu": [f"tensorflow-cpu=={tf_version}"], - "gpu": [f"tensorflow=={tf_version}"], - } cmake_args = [] # get variant option from the environment varibles, available: cpu, cuda, rocm @@ -52,57 +26,37 @@ cmake_args.append("-DUSE_ROCM_TOOLKIT:BOOL=TRUE") rocm_root = os.environ.get("ROCM_ROOT") if rocm_root: - cmake_args.append(f"-DROCM_ROOT:STRING={rocm_root}") + cmake_args.append(f"-DCMAKE_HIP_COMPILER_ROCM_ROOT:STRING={rocm_root}") else: raise RuntimeError("Unsupported DP_VARIANT option: %s" % dp_variant) -# get tensorflow spec -tf_spec = find_spec("tensorflow") - -if not tf_spec and site.ENABLE_USER_SITE: - # first search TF from user site-packages before global site-packages - site_packages = site.getusersitepackages() - if site_packages: - tf_spec = FileFinder(site_packages).find_spec("tensorflow") +if os.environ.get("DP_BUILD_TESTING", "0") == "1": + cmake_args.append("-DBUILD_TESTING:BOOL=TRUE") +if os.environ.get("DP_ENABLE_NATIVE_OPTIMIZATION", "0") == "1": + cmake_args.append("-DENABLE_NATIVE_OPTIMIZATION:BOOL=TRUE") +dp_lammps_version = os.environ.get("DP_LAMMPS_VERSION", "") +if dp_lammps_version != "": + cmake_args.append("-DBUILD_CPP_IF:BOOL=TRUE") + cmake_args.append("-DUSE_TF_PYTHON_LIBS:BOOL=TRUE") + cmake_args.append(f"-DLAMMPS_VERSION={dp_lammps_version}") +else: + cmake_args.append("-DBUILD_CPP_IF:BOOL=FALSE") -if not tf_spec: - # purelib gets site-packages path - site_packages = get_path("purelib") - if site_packages: - tf_spec = FileFinder(site_packages).find_spec("tensorflow") +tf_install_dir, _ = find_tensorflow() +tf_version = get_tf_version(tf_install_dir) -# get install dir from spec -try: - tf_install_dir = tf_spec.submodule_search_locations[0] # type: ignore - # AttributeError if ft_spec is None - # TypeError if submodule_search_locations are None - # IndexError if submodule_search_locations is an empty list -except (AttributeError, TypeError, IndexError): - setup_requires.extend(extras_require['cpu']) - # setuptools will re-find tensorflow after installing setup_requires - tf_install_dir = None -# add cmake as a build requirement if cmake>3.12 is not installed -try: - cmake_version = get_cmake_version() -except SKBuildError: - setup_requires.append("cmake") -else: - if cmake_version in SpecifierSet("<3.12"): - setup_requires.append("cmake") +class bdist_wheel_abi3(bdist_wheel): + def get_tag(self): + python, abi, plat = super().get_tag() + if python.startswith("cp"): + return "py37", "none", plat + return python, abi, plat -Path("deepmd").mkdir(exist_ok=True) +# TODO: migrate packages and entry_points to pyproject.toml after scikit-build supports it +# See also https://scikit-build.readthedocs.io/en/latest/usage.html#setuptools-options setup( - name="deepmd-kit", - setup_requires=setup_requires, - use_scm_version={"write_to": "deepmd/_version.py"}, - author="Han Wang", - author_email="wang_han@iapcm.ac.cn", - description="A deep learning package for many-body potential energy representation and molecular dynamics", - long_description=readme, - long_description_content_type="text/markdown", - url="https://github.com/deepmodeling/deepmd-kit", packages=[ "deepmd", "deepmd/descriptor", @@ -123,21 +77,13 @@ "deepmd/nvnmd/fit", "deepmd/nvnmd/utils", ], - python_requires=">=3.6", - classifiers=[ - "Programming Language :: Python :: 3.6", - "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", - ], - keywords="deepmd", - install_requires=INSTALL_REQUIRES, cmake_args=[ - f"-DTENSORFLOW_ROOT:STRING={tf_install_dir}", + f"-DTENSORFLOW_ROOT:PATH={tf_install_dir}", "-DBUILD_PY_IF:BOOL=TRUE", - "-DBUILD_CPP_IF:BOOL=FALSE", *cmake_args, ], cmake_source_dir="source", - cmake_minimum_required_version="3.0", + cmake_minimum_required_version="3.16", extras_require={ "test": ["dpdata>=0.1.9", "ase", "pytest", "pytest-cov", "pytest-sugar"], "docs": [ @@ -151,11 +97,22 @@ "numpydoc", "ase", "deepmodeling-sphinx>=0.1.0", - "dargs>=0.3.1", + "dargs>=0.3.4", "sphinx-argparse", "pygments-lammps", ], - **extras_require, + "lmp": [ + "lammps-manylinux-2-28~=2022.6.23.2.2; platform_system=='Linux'", + "lammps~=2022.6.23.2.2; platform_system!='Linux'", + "find_libpython", + ], + **get_tf_requirement(tf_version), + }, + entry_points={ + "console_scripts": ["dp = deepmd.entrypoints.main:main"], + "lammps.plugins": ["deepmd = deepmd.lmp:get_op_dir"], + }, + cmdclass = { + "bdist_wheel": bdist_wheel_abi3, }, - entry_points={"console_scripts": ["dp = deepmd.entrypoints.main:main"]}, ) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 943d1a14d6..84648c169a 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,6 +1,13 @@ -cmake_minimum_required(VERSION 3.12) +# new in 3.16: GET_RUNTIME_DEPENDENCIES, target_precompile_headers +cmake_minimum_required(VERSION 3.16) project(DeePMD) +option(BUILD_TESTING "Build test and enable converage" OFF) +if(BUILD_TESTING) + enable_testing() + add_subdirectory(${CMAKE_SOURCE_DIR}/cmake/coverage_config coverage_config) +endif() + # build cpp or python interfaces if (NOT DEFINED BUILD_CPP_IF) set(BUILD_CPP_IF TRUE) @@ -13,6 +20,30 @@ if ((NOT BUILD_PY_IF) AND (NOT BUILD_CPP_IF)) message(FATAL_ERROR "Nothing to do.") endif() +if (BUILD_CPP_IF AND BUILD_TESTING) + if (NOT INSTALL_TENSORFLOW) + # some errors in conda packages... + find_package(GTest) + endif() + if(NOT GTEST_LIBRARIES) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/googletest.cmake.in googletest-download/CMakeLists.txt @ONLY) + execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) + if(result) + message(FATAL_ERROR "CMake step for googletest failed: ${result}") + endif() + execute_process(COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) + if(result) + message(FATAL_ERROR "Build step for googletest failed: ${result}") + endif() + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src ${CMAKE_CURRENT_BINARY_DIR}/googletest-build EXCLUDE_FROM_ALL) + endif () +endif() + find_package(Git) if(GIT_FOUND) execute_process( @@ -81,101 +112,19 @@ set(DEEPMD_SOURCE_DIR ${PROJECT_SOURCE_DIR}/..) # setup tensorflow libraries by python if (USE_TF_PYTHON_LIBS) - find_package (Python COMPONENTS Interpreter Development REQUIRED) + if(NOT $ENV{CIBUILDWHEEL} STREQUAL "1") + find_package (Python COMPONENTS Interpreter Development REQUIRED) + else() + set(Python_LIBRARIES ${Python_LIBRARY}) + endif() endif(USE_TF_PYTHON_LIBS) # find tensorflow, I need tf abi info find_package(tensorflow REQUIRED) -if (TENSORFLOW_VERSION VERSION_GREATER_EQUAL 2.10) - set (CMAKE_CXX_STANDARD 17) -elseif (TENSORFLOW_VERSION VERSION_GREATER_EQUAL 2.7) - set (CMAKE_CXX_STANDARD 14) -else() - set (CMAKE_CXX_STANDARD 11) -endif() - -if (MSVC) - # see TF .bazelrc - add_compile_options(/W0 /Zc:__cplusplus /D_USE_MATH_DEFINES /d2ReducedOptimizeHugeFunctions) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) -endif() -if (TENSORFLOW_VERSION VERSION_GREATER_EQUAL 2.4 AND MSVC) - # see TF 2.4 release notes - add_compile_options(/Zc:preprocessor) -endif() - # find threads find_package(Threads) -# auto op_cxx_abi -if (NOT DEFINED OP_CXX_ABI) - if (BUILD_PY_IF) - if (DEFINED TENSORFLOW_ROOT) - # note \ in windows path - set(FIND_ABI_CMD "import sys,os; sys.path.insert(0, os.path.join(r'${TENSORFLOW_ROOT}', '..')); import tensorflow; print(tensorflow.CXX11_ABI_FLAG if 'CXX11_ABI_FLAG' in tensorflow.__dict__ else tensorflow.sysconfig.CXX11_ABI_FLAG, end = '')" ) - else() - set(FIND_ABI_CMD "import tensorflow; print(tensorflow.CXX11_ABI_FLAG if 'CXX11_ABI_FLAG' in tensorflow.__dict__ else tensorflow.sysconfig.CXX11_ABI_FLAG, end = '')") - endif() - execute_process( - COMMAND ${PYTHON_EXECUTABLE} "-c" "${FIND_ABI_CMD}" - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - OUTPUT_VARIABLE PY_CXX_ABI - RESULT_VARIABLE PY_CXX_ABI_RESULT_VAR - ERROR_VARIABLE PY_CXX_ABI_ERROR_VAR - ) - if (NOT ${PY_CXX_ABI_RESULT_VAR} EQUAL 0) - message(FATAL_ERROR "Cannot determine cxx abi, error message: ${PY_CXX_ABI_ERROR_VAR}") - endif() - set(OP_CXX_ABI ${PY_CXX_ABI}) - endif() - if (BUILD_CPP_IF) - try_run( - CPP_CXX_ABI_RUN_RESULT_VAR CPP_CXX_ABI_COMPILE_RESULT_VAR - ${CMAKE_CURRENT_BINARY_DIR}/tf_cxx_abi - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/tf_cxx_abi.cpp" - LINK_LIBRARIES ${TensorFlowFramework_LIBRARY} - CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${TensorFlow_INCLUDE_DIRS}" - RUN_OUTPUT_VARIABLE CPP_CXX_ABI - COMPILE_OUTPUT_VARIABLE CPP_CXX_ABI_COMPILE_OUTPUT_VAR - ) - if (NOT ${CPP_CXX_ABI_COMPILE_RESULT_VAR}) - message(FATAL_ERROR "Failed to compile: \n ${CPP_CXX_ABI_COMPILE_OUTPUT_VAR}" ) - endif() - if (NOT ${CPP_CXX_ABI_RUN_RESULT_VAR} EQUAL "0") - message(FATAL_ERROR "Failed to run, return code: ${CPP_CXX_ABI}" ) - endif() - if (DEFINED PY_CXX_ABI) - if (NOT (${CPP_CXX_ABI} EQUAL ${PY_CXX_ABI})) - message (WARNNING "NOT consistent CXX_ABIs: python interface of tf uses ${PY_CXX_ABI}, while c++ interface of tf uses ${CPP_CXX_ABI}, we follow c++ interface ") - endif() - endif() - set(OP_CXX_ABI ${CPP_CXX_ABI}) - endif() - message (STATUS "Automatically determined OP_CXX_ABI=${OP_CXX_ABI} ") -else() - message (STATUS "User set OP_CXX_ABI=${OP_CXX_ABI} ") -endif() -# message the cxx_abi used during compiling -if (${OP_CXX_ABI} EQUAL 0) - message (STATUS "Set GLIBCXX_USE_CXX_ABI=0 when compiling ops") -else () - set (OP_CXX_ABI 1) - message (STATUS "Set GLIBCXX_USE_CXX_ABI=1 when compiling ops") -endif () - -# set _GLIBCXX_USE_CXX11_ABI flag globally -add_definitions(-D_GLIBCXX_USE_CXX11_ABI=${OP_CXX_ABI}) - -# define USE_TTM -if (NOT DEFINED USE_TTM) - set(USE_TTM FALSE) -endif (NOT DEFINED USE_TTM) -if (USE_TTM) - message(STATUS "Use TTM") - set(TTM_DEF "-DUSE_TTM") -endif (USE_TTM) - # define build type if ((NOT DEFINED CMAKE_BUILD_TYPE) OR CMAKE_BUILD_TYPE STREQUAL "") set (CMAKE_BUILD_TYPE release) @@ -195,11 +144,19 @@ if (OPENMP_FOUND) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() +# optimize flags +option(ENABLE_NATIVE_OPTIMIZATION "Enable native optimization" OFF) +if (ENABLE_NATIVE_OPTIMIZATION) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mtune=native") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -mtune=native") +endif() + # define names of libs set (LIB_DEEPMD "deepmd") +set (LIB_DEEPMD_OP "deepmd_op") if (BUILD_CPP_IF) - set (LIB_DEEPMD_OP "deepmd_op") set (LIB_DEEPMD_CC "deepmd_cc") + set (LIB_DEEPMD_C "deepmd_c") if (USE_CUDA_TOOLKIT) set (LIB_DEEPMD_OP_DEVICE "deepmd_op_cuda") elseif (USE_ROCM_TOOLKIT) @@ -224,11 +181,14 @@ if (BUILD_PY_IF) endif (BUILD_PY_IF) if (BUILD_CPP_IF) add_subdirectory (api_cc/) + add_subdirectory (api_c/) add_subdirectory (lmp/) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.8) # add_subdirectory (md/) + if(NOT BUILD_PY_IF) add_subdirectory (ipi/) add_subdirectory (gmx/) + endif() endif () endif (BUILD_CPP_IF) @@ -250,3 +210,20 @@ configure_file( add_custom_target(lammps COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_lammps.cmake) +# add configure file +if(BUILD_CPP_IF AND NOT BUILD_PY_IF) + include(CMakePackageConfigHelpers) + set(targets_export_name ${CMAKE_PROJECT_NAME}Targets CACHE INTERNAL "") + set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated" CACHE INTERNAL "") + set(cmake_files_install_dir "${CMAKE_INSTALL_PREFIX}/lib/cmake/${CMAKE_PROJECT_NAME}") + set(version_file "${generated_dir}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake") + write_basic_package_version_file(${version_file} VERSION $ COMPATIBILITY AnyNewerVersion) + install(EXPORT ${targets_export_name} + NAMESPACE ${CMAKE_PROJECT_NAME}:: + DESTINATION ${cmake_files_install_dir}) + set(config_file "${generated_dir}/${CMAKE_PROJECT_NAME}Config.cmake") + configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in" + "${config_file}" INSTALL_DESTINATION ${cmake_files_install_dir}) + install(FILES ${version_file} ${config_file} + DESTINATION ${cmake_files_install_dir}) +endif(BUILD_CPP_IF AND NOT BUILD_PY_IF) diff --git a/source/api_c/CMakeLists.txt b/source/api_c/CMakeLists.txt new file mode 100644 index 0000000000..75e785a341 --- /dev/null +++ b/source/api_c/CMakeLists.txt @@ -0,0 +1,85 @@ +file(GLOB LIB_SRC src/*.cc src/*.cpp) +# only install public headers +file(GLOB INC_SRC include/c_api.h include/deepmd.hpp) + +set (libname "${LIB_DEEPMD_C}") + +add_library(${libname} SHARED ${LIB_SRC}) + +# link: libdeepmd libdeepmd_op libtensorflow_cc libtensorflow_framework +target_link_libraries (${libname} PRIVATE ${LIB_DEEPMD_CC}) +target_include_directories( + ${libname} PUBLIC + $ + $ +) + +set_target_properties( + ${libname} + PROPERTIES + INSTALL_RPATH "$ORIGIN;${TensorFlow_LIBRARY_PATH}" +) +if (CMAKE_TESTING_ENABLED) + target_link_libraries(${libname} PRIVATE coverage_config) +endif() + +if(BUILD_PY_IF) + install( + TARGETS ${libname} + DESTINATION deepmd/op/ + ) +else(BUILD_PY_IF) +install( + TARGETS ${libname} + EXPORT ${CMAKE_PROJECT_NAME}Targets + DESTINATION lib/ +) + +install( + FILES ${INC_SRC} + DESTINATION include/deepmd +) +endif(BUILD_PY_IF) + +if (PACKAGE_C) + MESSAGE(STATUS "Packaging C API library") + # follow pypa/auditwheel convention + install(CODE [[ + file(GET_RUNTIME_DEPENDENCIES + LIBRARIES $ $ + RESOLVED_DEPENDENCIES_VAR _r_deps + PRE_EXCLUDE_REGEXES "libgcc_s\\.so.*" + "libstdc\\+\\+\\.so.*" + "libm\\.so.*" + "libdl\\.so.*" + "librt\\.so.*" + "libc\\.so.*" + "libpthread\\.so.*" + "ld-.*\\.so.*" + "libgomp\\.so.*" + ) + message(STATUS "Runtime dependencies: ${_r_deps}") + foreach(_file ${_r_deps}) + file(INSTALL ${_file} DESTINATION libdeepmd_c/lib + FOLLOW_SYMLINK_CHAIN + ) + endforeach() + ]] + ) + install( + FILES ${INC_SRC} + DESTINATION ${CMAKE_BINARY_DIR}/libdeepmd_c/include/deepmd + ) + install( + TARGETS ${libname} + DESTINATION ${CMAKE_BINARY_DIR}/libdeepmd_c/lib + ) + install( + TARGETS ${LIB_DEEPMD_OP} + DESTINATION ${CMAKE_BINARY_DIR}/libdeepmd_c/lib + ) +endif() + +if (CMAKE_TESTING_ENABLED) + add_subdirectory(tests) +endif() diff --git a/source/api_c/include/c_api.h b/source/api_c/include/c_api.h new file mode 100644 index 0000000000..a97ab6b79a --- /dev/null +++ b/source/api_c/include/c_api.h @@ -0,0 +1,540 @@ +#pragma once +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Neighbor list. +*/ +typedef struct DP_Nlist DP_Nlist; + +/** +* @brief Create a new neighbor list. +* @param[in] inum_ Number of core region atoms +* @param[in] Array stores the core region atom's index +* @param[in] Array stores the core region atom's neighbor atom number +* @param[in] Array stores the core region atom's neighbor index +* @returns A pointer to the neighbor list. +**/ +extern DP_Nlist* DP_NewNlist( + int inum_, + int * ilist_, + int * numneigh_, + int ** firstneigh_); + +/** +* @brief The deep potential. +**/ +typedef struct DP_DeepPot DP_DeepPot; + +/** +* @brief DP constructor with initialization. +* @param[in] c_model The name of the frozen model file. +* @returns A pointer to the deep potential. +**/ +extern DP_DeepPot* DP_NewDeepPot(const char* c_model); + +/** +* @brief Evaluate the energy, force and virial by using a DP. (double version) +* @param[in] dp The DP to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[out] energy Output energy. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_energy Output atomic energy. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepPotCompute ( + DP_DeepPot* dp, + const int natom, + const double* coord, + const int* atype, + const double* cell, + double* energy, + double* force, + double* virial, + double* atomic_energy, + double* atomic_virial + ); + +/** +* @brief Evaluate the energy, force and virial by using a DP. (float version) +* @param[in] dp The DP to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[out] energy Output energy. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_energy Output atomic energy. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepPotComputef ( + DP_DeepPot* dp, + const int natom, + const float* coord, + const int* atype, + const float* cell, + double* energy, + float* force, + float* virial, + float* atomic_energy, + float* atomic_virial + ); + +/** +* @brief Evaluate the energy, force and virial by using a DP with the neighbor list. (double version) +* @param[in] dp The DP to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[in] nghost The number of ghost atoms. +* @param[in] nlist The neighbor list. +* @param[in] ago Update the internal neighbour list if ago is 0. +* @param[out] energy Output energy. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_energy Output atomic energy. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepPotComputeNList ( + DP_DeepPot* dp, + const int natom, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + double* force, + double* virial, + double* atomic_energy, + double* atomic_virial + ); + +/** +* @brief Evaluate the energy, force and virial by using a DP with the neighbor list. (float version) +* @param[in] dp The DP to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[in] nghost The number of ghost atoms. +* @param[in] nlist The neighbor list. +* @param[in] ago Update the internal neighbour list if ago is 0. +* @param[out] energy Output energy. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_energy Output atomic energy. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepPotComputeNListf ( + DP_DeepPot* dp, + const int natom, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + float* force, + float* virial, + float* atomic_energy, + float* atomic_virial + ); + +/** +* @brief The deep potential model deviation. +**/ +typedef struct DP_DeepPotModelDevi DP_DeepPotModelDevi; + +/** +* @brief DP model deviation constructor with initialization. +* @param[in] c_models The array of the name of the frozen model file. +* @param[in] nmodels The number of models. +**/ +extern DP_DeepPotModelDevi* DP_NewDeepPotModelDevi(const char** c_models, int n_models); + +/** +* @brief Evaluate the energy, force and virial by using a DP model deviation with neighbor list. (double version) +* @param[in] dp The DP model deviation to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[in] nghost The number of ghost atoms. +* @param[in] nlist The neighbor list. +* @param[in] ago Update the internal neighbour list if ago is 0. +* @param[out] energy Output energy. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_energy Output atomic energy. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepPotModelDeviComputeNList ( + DP_DeepPotModelDevi* dp, + const int natom, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + double* force, + double* virial, + double* atomic_energy, + double* atomic_virial + ); + +/** +* @brief Evaluate the energy, force and virial by using a DP model deviation with neighbor list. (float version) +* @param[in] dp The DP model deviation to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[in] nghost The number of ghost atoms. +* @param[in] nlist The neighbor list. +* @param[in] ago Update the internal neighbour list if ago is 0. +* @param[out] energy Output energy. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_energy Output atomic energy. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepPotModelDeviComputeNListf ( + DP_DeepPotModelDevi* dp, + const int natom, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + float* force, + float* virial, + float* atomic_energy, + float* atomic_virial + ); + +/** + * @brief Get the type map of a DP model deviation. + * @param[in] dp The DP model deviation to use. + * @return The cutoff radius. +*/ +double DP_DeepPotModelDeviGetCutoff(DP_DeepPotModelDevi* dp); + +/** + * @brief Get the type map of a DP model deviation. + * @param[in] dp The DP model deviation to use. + * @return The number of types of the DP model deviation. +*/ +int DP_DeepPotModelDeviGetNumbTypes(DP_DeepPotModelDevi* dp); + +/** + * @brief Get the type map of a DP. + * @param[in] dp The DP to use. + * @return The cutoff radius. +*/ +double DP_DeepPotGetCutoff(DP_DeepPot* dp); + +/** + * @brief Get the type map of a DP. + * @param[in] dp The DP to use. + * @return The number of types of the DP. +*/ +int DP_DeepPotGetNumbTypes(DP_DeepPot* dp); + +/** + * @brief Get the type map of a DP. + * @param[in] dp The DP to use. + * @return The type map of the DP. +*/ +const char* DP_DeepPotGetTypeMap(DP_DeepPot* dp); + +/** +* @brief The deep tensor. +**/ +typedef struct DP_DeepTensor DP_DeepTensor; + +/** +* @brief Deep Tensor constructor with initialization. +* @param[in] c_model The name of the frozen model file. +* @returns A pointer to the deep tensor. +**/ +extern DP_DeepTensor* DP_NewDeepTensor(const char* c_model); + +/** +* @brief Evaluate the tensor by using a DP. (double version) +* @param[in] dt The Deep Tensor to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[out] tensor Output tensor. + **/ +extern void DP_DeepTensorComputeTensor ( + DP_DeepTensor* dt, + const int natom, + const double* coord, + const int* atype, + const double* cell, + double** tensor, + int* size + ); + +/** +* @brief Evaluate the tensor by using a DP. (float version) +* @param[in] dt The Deep Tensor to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[out] tensor Output tensor. +* @param[out] size Output size of the tensor. + **/ +extern void DP_DeepTensorComputeTensorf ( + DP_DeepTensor* dt, + const int natom, + const float* coord, + const int* atype, + const float* cell, + float** tensor, + int* size + ); + +/** +* @brief Evaluate the tensor by using a DP with the neighbor list. (double version) +* @param[in] dt The Deep Tensor to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[in] nghost The number of ghost atoms. +* @param[in] nlist The neighbor list. +* @param[out] tensor Output tensor. +* @param[out] size Output size of the tensor. + **/ +extern void DP_DeepTensorComputeTensorNList ( + DP_DeepTensor* dt, + const int natom, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + double** tensor, + int* size + ); + +/** +* @brief Evaluate the tensor by using a DP with the neighbor list. (float version) +* @param[in] dt The Deep Tensor to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[in] nghost The number of ghost atoms. +* @param[in] nlist The neighbor list. +* @param[out] tensor Output tensor. +* @param[out] size Output size of the tensor. + **/ +extern void DP_DeepTensorComputeTensorNListf ( + DP_DeepTensor* dt, + const int natom, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + float** tensor, + int* size + ); + +/** +* @brief Evaluate the global tensor, force and virial by using a DP. (double version) +* @param[in] dt The Deep Tensor to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[out] global_tensor Output global tensor. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_tensor Output atomic tensor. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @param[out] size_at Output size of atomic tensor. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepTensorCompute ( + DP_DeepTensor* dt, + const int natom, + const double* coord, + const int* atype, + const double* cell, + double* global_tensor, + double* force, + double* virial, + double** atomic_tensor, + double* atomic_virial, + int* size_at + ); + +/** +* @brief Evaluate the global tensor, force and virial by using a DP. (float version) +* @param[in] dt The Deep Tensor to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[out] global_tensor Output global tensor. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_tensor Output atomic tensor. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @param[out] size_at Output size of atomic tensor. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepTensorComputef ( + DP_DeepTensor* dt, + const int natom, + const float* coord, + const int* atype, + const float* cell, + float* global_tensor, + float* force, + float* virial, + float** atomic_tensor, + float* atomic_virial, + int* size_at + ); + +/** +* @brief Evaluate the global tensor, force and virial by using a DP with the neighbor list. (double version) +* @param[in] dt The Deep Tensor to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[in] nghost The number of ghost atoms. +* @param[in] nlist The neighbor list. +* @param[out] global_tensor Output global tensor. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_tensor Output atomic tensor. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @param[out] size_at Output size of atomic tensor. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepTensorComputeNList ( + DP_DeepTensor* dt, + const int natom, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + double* global_tensor, + double* force, + double* virial, + double** atomic_tensor, + double* atomic_virial, + int* size_at + ); + +/** +* @brief Evaluate the global tensor, force and virial by using a DP with the neighbor list. (float version) +* @param[in] dt The Deep Tensor to use. +* @param[in] natoms The number of atoms. +* @param[in] coord The coordinates of atoms. The array should be of size natoms x 3. +* @param[in] atype The atom types. The array should contain natoms ints. +* @param[in] box The cell of the region. The array should be of size 9. Pass NULL if pbc is not used. +* @param[in] nghost The number of ghost atoms. +* @param[in] nlist The neighbor list. +* @param[out] global_tensor Output global tensor. +* @param[out] force Output force. The array should be of size natoms x 3. +* @param[out] virial Output virial. The array should be of size 9. +* @param[out] atomic_tensor Output atomic tensor. The array should be of size natoms. +* @param[out] atomic_virial Output atomic virial. The array should be of size natoms x 9. +* @param[out] size_at Output size of atomic tensor. +* @warning The output arrays should be allocated before calling this function. Pass NULL if not required. + **/ +extern void DP_DeepTensorComputeNListf ( + DP_DeepTensor* dt, + const int natom, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + float* global_tensor, + float* force, + float* virial, + float** atomic_tensor, + float* atomic_virial, + int* size_at + ); + +/** + * @brief Get the type map of a Deep Tensor. + * @param[in] dt The Deep Tensor to use. + * @return The cutoff radius. +*/ +double DP_DeepTensorGetCutoff(DP_DeepTensor* dt); + +/** + * @brief Get the type map of a Deep Tensor. + * @param[in] dt The Deep Tensor to use. + * @return The number of types of the Deep Tensor. +*/ +int DP_DeepTensorGetNumbTypes(DP_DeepTensor* dt); + +/** + * @brief Get the output dimension of a Deep Tensor. + * @param[in] dt The Deep Tensor to use. + * @return The output dimension of the Deep Tensor. +*/ +int DP_DeepTensorGetOutputDim(DP_DeepTensor* dt); + +/** + * @brief Get sel types of a Deep Tensor. + * @param[in] dt The Deep Tensor to use. + * @return The sel types +*/ +int* DP_DeepTensorGetSelTypes(DP_DeepTensor* dt); + +/** + * @brief Get the number of sel types of a Deep Tensor. + * @param[in] dt The Deep Tensor to use. + * @return The number of sel types +*/ +int DP_DeepTensorGetNumbSelTypes(DP_DeepTensor* dt); + +/** +* @brief Convert PBtxt to PB. +* @param[in] c_pbtxt The name of the PBtxt file. +* @param[in] c_pb The name of the PB file. + **/ +extern void DP_ConvertPbtxtToPb( + const char* c_pbtxt, + const char* c_pb + ); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif \ No newline at end of file diff --git a/source/api_c/include/c_api_internal.h b/source/api_c/include/c_api_internal.h new file mode 100644 index 0000000000..ec4eba1b17 --- /dev/null +++ b/source/api_c/include/c_api_internal.h @@ -0,0 +1,27 @@ +#include "neighbor_list.h" +#include "DeepPot.h" +#include "DeepTensor.h" + +struct DP_Nlist { + DP_Nlist(deepmd::InputNlist& nl); + + deepmd::InputNlist nl; +}; + +struct DP_DeepPot { + DP_DeepPot(deepmd::DeepPot& dp); + + deepmd::DeepPot dp; +}; + +struct DP_DeepPotModelDevi { + DP_DeepPotModelDevi(deepmd::DeepPotModelDevi& dp); + + deepmd::DeepPotModelDevi dp; +}; + +struct DP_DeepTensor { + DP_DeepTensor(deepmd::DeepTensor& dt); + + deepmd::DeepTensor dt; +}; diff --git a/source/api_c/include/deepmd.hpp b/source/api_c/include/deepmd.hpp new file mode 100644 index 0000000000..1007f92ef2 --- /dev/null +++ b/source/api_c/include/deepmd.hpp @@ -0,0 +1,1165 @@ +/* +Header-only DeePMD-kit C++ 11 library + +This header-only library provides a C++ 11 interface to the DeePMD-kit C API. +*/ + +#pragma once + +#include +#include +#include +#include +#include + +#include "c_api.h" + +template +inline void _DP_DeepPotCompute( + DP_DeepPot *dp, + const int natom, + const FPTYPE *coord, + const int *atype, + const FPTYPE *cell, + double *energy, + FPTYPE *force, + FPTYPE *virial, + FPTYPE *atomic_energy, + FPTYPE *atomic_virial); + +template <> +inline void _DP_DeepPotCompute( + DP_DeepPot *dp, + const int natom, + const double *coord, + const int *atype, + const double *cell, + double *energy, + double *force, + double *virial, + double *atomic_energy, + double *atomic_virial) +{ + DP_DeepPotCompute(dp, natom, coord, atype, cell, energy, force, virial, atomic_energy, atomic_virial); +} + +template <> +inline void _DP_DeepPotCompute( + DP_DeepPot *dp, + const int natom, + const float *coord, + const int *atype, + const float *cell, + double *energy, + float *force, + float *virial, + float *atomic_energy, + float *atomic_virial) +{ + DP_DeepPotComputef(dp, natom, coord, atype, cell, energy, force, virial, atomic_energy, atomic_virial); +} + +template +inline void _DP_DeepPotComputeNList( + DP_DeepPot *dp, + const int natom, + const FPTYPE *coord, + const int *atype, + const FPTYPE *cell, + const int nghost, + const DP_Nlist *nlist, + const int ago, + double *energy, + FPTYPE *force, + FPTYPE *virial, + FPTYPE *atomic_energy, + FPTYPE *atomic_virial); + +template <> +inline void _DP_DeepPotComputeNList( + DP_DeepPot *dp, + const int natom, + const double *coord, + const int *atype, + const double *cell, + const int nghost, + const DP_Nlist *nlist, + const int ago, + double *energy, + double *force, + double *virial, + double *atomic_energy, + double *atomic_virial) +{ + DP_DeepPotComputeNList(dp, natom, coord, atype, cell, nghost, nlist, ago, energy, force, virial, atomic_energy, atomic_virial); +} + +template <> +inline void _DP_DeepPotComputeNList( + DP_DeepPot *dp, + const int natom, + const float *coord, + const int *atype, + const float *cell, + const int nghost, + const DP_Nlist *nlist, + const int ago, + double *energy, + float *force, + float *virial, + float *atomic_energy, + float *atomic_virial) +{ + DP_DeepPotComputeNListf(dp, natom, coord, atype, cell, nghost, nlist, ago, energy, force, virial, atomic_energy, atomic_virial); +} + +template +inline void _DP_DeepPotModelDeviComputeNList( + DP_DeepPotModelDevi *dp, + const int natom, + const FPTYPE *coord, + const int *atype, + const FPTYPE *cell, + const int nghost, + const DP_Nlist *nlist, + const int ago, + double *energy, + FPTYPE *force, + FPTYPE *virial, + FPTYPE *atomic_energy, + FPTYPE *atomic_virial); + +template <> +inline void _DP_DeepPotModelDeviComputeNList( + DP_DeepPotModelDevi *dp, + const int natom, + const double *coord, + const int *atype, + const double *cell, + const int nghost, + const DP_Nlist *nlist, + const int ago, + double *energy, + double *force, + double *virial, + double *atomic_energy, + double *atomic_virial) +{ + DP_DeepPotModelDeviComputeNList(dp, natom, coord, atype, cell, nghost, nlist, ago, energy, force, virial, atomic_energy, atomic_virial); +} + +template <> +inline void _DP_DeepPotModelDeviComputeNList( + DP_DeepPotModelDevi *dp, + const int natom, + const float *coord, + const int *atype, + const float *cell, + const int nghost, + const DP_Nlist *nlist, + const int ago, + double *energy, + float *force, + float *virial, + float *atomic_energy, + float *atomic_virial) +{ + DP_DeepPotModelDeviComputeNListf(dp, natom, coord, atype, cell, nghost, nlist, ago, energy, force, virial, atomic_energy, atomic_virial); +} + +template +inline void _DP_DeepTensorComputeTensor( + DP_DeepTensor *dt, + const int natom, + const FPTYPE *coord, + const int *atype, + const FPTYPE *cell, + FPTYPE **tensor, + int* size); + +template <> +inline void _DP_DeepTensorComputeTensor( + DP_DeepTensor *dt, + const int natom, + const double *coord, + const int *atype, + const double *cell, + double **tensor, + int* size) +{ + DP_DeepTensorComputeTensor(dt, natom, coord, atype, cell, tensor, size); +} + +template <> +inline void _DP_DeepTensorComputeTensor( + DP_DeepTensor *dt, + const int natom, + const float *coord, + const int *atype, + const float *cell, + float **tensor, + int* size) +{ + DP_DeepTensorComputeTensorf(dt, natom, coord, atype, cell, tensor, size); +} + +template +inline void _DP_DeepTensorComputeTensorNList( + DP_DeepTensor *dt, + const int natom, + const FPTYPE *coord, + const int *atype, + const FPTYPE *cell, + const int nghost, + const DP_Nlist *nlist, + FPTYPE **tensor, + int* size); + +template <> +inline void _DP_DeepTensorComputeTensorNList( + DP_DeepTensor *dt, + const int natom, + const double *coord, + const int *atype, + const double *cell, + const int nghost, + const DP_Nlist *nlist, + double **tensor, + int* size) +{ + DP_DeepTensorComputeTensorNList(dt, natom, coord, atype, cell, nghost, nlist, tensor, size); +} + +template <> +inline void _DP_DeepTensorComputeTensorNList( + DP_DeepTensor *dt, + const int natom, + const float *coord, + const int *atype, + const float *cell, + const int nghost, + const DP_Nlist *nlist, + float **tensor, + int* size) +{ + DP_DeepTensorComputeTensorNListf(dt, natom, coord, atype, cell, nghost, nlist, tensor, size); +} + +template +inline void _DP_DeepTensorCompute( + DP_DeepTensor *dt, + const int natom, + const FPTYPE *coord, + const int *atype, + const FPTYPE *cell, + FPTYPE *global_tensor, + FPTYPE *force, + FPTYPE *virial, + FPTYPE **atomic_energy, + FPTYPE *atomic_virial, + int* size_at); + +template <> +inline void _DP_DeepTensorCompute( + DP_DeepTensor *dt, + const int natom, + const double *coord, + const int *atype, + const double *cell, + double *global_tensor, + double *force, + double *virial, + double **atomic_tensor, + double *atomic_virial, + int* size_at) +{ + DP_DeepTensorCompute(dt, natom, coord, atype, cell, global_tensor, force, virial, atomic_tensor, atomic_virial, size_at); +} + +template <> +inline void _DP_DeepTensorCompute( + DP_DeepTensor *dt, + const int natom, + const float *coord, + const int *atype, + const float *cell, + float *global_tensor, + float *force, + float *virial, + float **atomic_tensor, + float *atomic_virial, + int* size_at) +{ + DP_DeepTensorComputef(dt, natom, coord, atype, cell, global_tensor, force, virial, atomic_tensor, atomic_virial, size_at); +} + +template +inline void _DP_DeepTensorComputeNList( + DP_DeepTensor *dt, + const int natom, + const FPTYPE *coord, + const int *atype, + const FPTYPE *cell, + const int nghost, + const DP_Nlist *nlist, + FPTYPE *global_tensor, + FPTYPE *force, + FPTYPE *virial, + FPTYPE **atomic_energy, + FPTYPE *atomic_virial, + int* size_at); + +template <> +inline void _DP_DeepTensorComputeNList( + DP_DeepTensor *dt, + const int natom, + const double *coord, + const int *atype, + const double *cell, + const int nghost, + const DP_Nlist *nlist, + double *global_tensor, + double *force, + double *virial, + double **atomic_tensor, + double *atomic_virial, + int* size_at) +{ + DP_DeepTensorComputeNList(dt, natom, coord, atype, cell, nghost, nlist, global_tensor, force, virial, atomic_tensor, atomic_virial, size_at); +} + +template <> +inline void _DP_DeepTensorComputeNList( + DP_DeepTensor *dt, + const int natom, + const float *coord, + const int *atype, + const float *cell, + const int nghost, + const DP_Nlist *nlist, + float *global_tensor, + float *force, + float *virial, + float **atomic_tensor, + float *atomic_virial, + int* size_at) +{ + DP_DeepTensorComputeNListf(dt, natom, coord, atype, cell, nghost, nlist, global_tensor, force, virial, atomic_tensor, atomic_virial, size_at); +} + +namespace deepmd +{ + namespace hpp + { + /** + * @brief Neighbor list. + **/ + struct InputNlist + { + InputNlist () + : inum(0), ilist(nullptr), numneigh(nullptr), firstneigh(nullptr), + nl(DP_NewNlist(0, nullptr, nullptr, nullptr)) + {}; + InputNlist( + int inum_, + int *ilist_, + int *numneigh_, + int **firstneigh_) + : inum(inum_), ilist(ilist_), numneigh(numneigh_), firstneigh(firstneigh_), + nl(DP_NewNlist(inum_, ilist_, numneigh_, firstneigh_)) + {}; + /// @brief C API neighbor list. + DP_Nlist* nl; + /// @brief Number of core region atoms + int inum; + /// @brief Array stores the core region atom's index + int *ilist; + /// @brief Array stores the core region atom's neighbor atom number + int *numneigh; + /// @brief Array stores the core region atom's neighbor index + int **firstneigh; + }; + + /** + * @brief Convert pbtxt to pb. + * @param[in] fn_pb_txt Filename of the pb txt file. + * @param[in] fn_pb Filename of the pb file. + **/ + void + inline + convert_pbtxt_to_pb(std::string fn_pb_txt, std::string fn_pb) + { + DP_ConvertPbtxtToPb(fn_pb_txt.c_str(), fn_pb.c_str()); + }; + /** + * @brief Convert int vector to InputNlist. + * @param[out] to_nlist InputNlist. + * @param[in] from_nlist 2D int vector. The first axis represents the centeral atoms + * and the second axis represents the neighbor atoms. + */ + void + inline + convert_nlist( + InputNlist & to_nlist, + std::vector > & from_nlist + ) + { + to_nlist.inum = from_nlist.size(); + for(int ii = 0; ii < to_nlist.inum; ++ii){ + to_nlist.ilist[ii] = ii; + to_nlist.numneigh[ii] = from_nlist[ii].size(); + to_nlist.firstneigh[ii] = &from_nlist[ii][0]; + } + to_nlist.nl = DP_NewNlist( + to_nlist.inum, + to_nlist.ilist, + to_nlist.numneigh, + to_nlist.firstneigh + ); + } + /** + * @brief Deep Potential. + **/ + class DeepPot + { + public: + /** + * @brief DP constructor without initialization. + **/ + DeepPot() : dp(nullptr) {}; + ~DeepPot(){}; + /** + * @brief DP constructor with initialization. + * @param[in] model The name of the frozen model file. + **/ + DeepPot(const std::string &model) : dp(nullptr) + { + init(model); + }; + /** + * @brief Initialize the DP. + * @param[in] model The name of the frozen model file. + **/ + void init(const std::string &model) + { + if (dp) + { + std::cerr << "WARNING: deepmd-kit should not be initialized twice, do nothing at the second call of initializer" << std::endl; + return; + } + dp = DP_NewDeepPot(model.c_str()); + }; + + /** + * @brief Evaluate the energy, force and virial by using this DP. + * @param[out] ener The system energy. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + **/ + template + void compute(double &ener, + std::vector &force, + std::vector &virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + double *ener_ = &ener; + force.resize(natoms * 3); + virial.resize(9); + VALUETYPE *force_ = &force[0]; + VALUETYPE *virial_ = &virial[0]; + + _DP_DeepPotCompute(dp, natoms, coord_, atype_, box_, ener_, force_, virial_, nullptr, nullptr); + }; + /** + * @brief Evaluate the energy, force, virial, atomic energy, and atomic virial by using this DP. + * @param[out] ener The system energy. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[out] atom_energy The atomic energy. + * @param[out] atom_virial The atomic virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + **/ + template + void compute(double &ener, + std::vector &force, + std::vector &virial, + std::vector &atom_energy, + std::vector &atom_virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + + double *ener_ = &ener; + force.resize(natoms * 3); + virial.resize(9); + atom_energy.resize(natoms); + atom_virial.resize(natoms * 9); + VALUETYPE *force_ = &force[0]; + VALUETYPE *virial_ = &virial[0]; + VALUETYPE *atomic_ener_ = &atom_energy[0]; + VALUETYPE *atomic_virial_ = &atom_virial[0]; + + _DP_DeepPotCompute(dp, natoms, coord_, atype_, box_, ener_, force_, virial_, atomic_ener_, atomic_virial_); + }; + + /** + * @brief Evaluate the energy, force and virial by using this DP with the neighbor list. + * @param[out] ener The system energy. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + * @param[in] nghost The number of ghost atoms. + * @param[in] nlist The neighbor list. + * @param[in] ago Update the internal neighbour list if ago is 0. + **/ + template + void compute(double &ener, + std::vector &force, + std::vector &virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const int nghost, + const InputNlist &lmp_list, + const int &ago) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) + { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + double *ener_ = &ener; + force.resize(natoms * 3); + virial.resize(9); + VALUETYPE *force_ = &force[0]; + VALUETYPE *virial_ = &virial[0]; + + _DP_DeepPotComputeNList(dp, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, ener_, force_, virial_, nullptr, nullptr); + }; + /** + * @brief Evaluate the energy, force, virial, atomic energy, and atomic virial by using this DP with the neighbor list. + * @param[out] ener The system energy. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[out] atom_energy The atomic energy. + * @param[out] atom_virial The atomic virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + * @param[in] nghost The number of ghost atoms. + * @param[in] nlist The neighbor list. + * @param[in] ago Update the internal neighbour list if ago is 0. + **/ + template + void compute(double &ener, + std::vector &force, + std::vector &virial, + std::vector &atom_energy, + std::vector &atom_virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const int nghost, + const InputNlist &lmp_list, + const int &ago) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) + { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + + double *ener_ = &ener; + force.resize(natoms * 3); + virial.resize(9); + atom_energy.resize(natoms); + atom_virial.resize(natoms * 9); + VALUETYPE *force_ = &force[0]; + VALUETYPE *virial_ = &virial[0]; + VALUETYPE *atomic_ener_ = &atom_energy[0]; + VALUETYPE *atomic_virial_ = &atom_virial[0]; + + _DP_DeepPotComputeNList(dp, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, ener_, force_, virial_, atomic_ener_, atomic_virial_); + }; + /** + * @brief Get the cutoff radius. + * @return The cutoff radius. + **/ + double cutoff() const + { + assert(dp); + return DP_DeepPotGetCutoff(dp); + }; + /** + * @brief Get the number of types. + * @return The number of types. + **/ + int numb_types() const + { + assert(dp); + return DP_DeepPotGetNumbTypes(dp); + }; + /** + * @brief Get the type map (element name of the atom types) of this model. + * @param[out] type_map The type map of this model. + **/ + void get_type_map(std::string &type_map) + { + const char *type_map_c = DP_DeepPotGetTypeMap(dp); + type_map.assign(type_map_c); + delete[] type_map_c; + }; + + private: + DP_DeepPot *dp; + }; + + /** + * @brief Deep Potential model deviation. + **/ + class DeepPotModelDevi + { + public: + /** + * @brief DP model deviation constructor without initialization. + **/ + DeepPotModelDevi() : dp(nullptr) {}; + ~DeepPotModelDevi(){}; + /** + * @brief DP model deviation constructor with initialization. + * @param[in] models The names of the frozen model file. + **/ + DeepPotModelDevi(const std::vector &models) : dp(nullptr) + { + init(models); + }; + /** + * @brief Initialize the DP model deviation. + * @param[in] model The name of the frozen model file. + **/ + void init(const std::vector &models) + { + if (dp) + { + std::cerr << "WARNING: deepmd-kit should not be initialized twice, do nothing at the second call of initializer" << std::endl; + return; + } + std::vector cstrings; + cstrings.reserve(models.size()); + for (std::string const& str : models) + cstrings.push_back(str.data()); + + dp = DP_NewDeepPotModelDevi(cstrings.data(), cstrings.size()); + numb_models = models.size(); + }; + + /** + * @brief Evaluate the energy, force and virial by using this DP model deviation. + * @param[out] ener The system energy. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + **/ + template + void compute(std::vector &ener, + std::vector> &force, + std::vector> &virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const int nghost, + const InputNlist &lmp_list, + const int &ago) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + + // memory will be continous for std::vector but not std::vector + std::vector energy_flat(numb_models); + std::vector force_flat(numb_models * natoms * 3); + std::vector virial_flat(numb_models * 9); + double *ener_ = &energy_flat[0]; + VALUETYPE *force_ = &force_flat[0]; + VALUETYPE *virial_ = &virial_flat[0]; + + _DP_DeepPotModelDeviComputeNList(dp, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, ener_, force_, virial_, nullptr, nullptr); + + // reshape + ener.resize(numb_models); + force.resize(numb_models); + virial.resize(numb_models); + for (int i = 0; i < numb_models; i++) + { + ener[i] = energy_flat[i]; + force[i].resize(natoms * 3); + virial[i].resize(9); + for (int j = 0; j < natoms * 3; j++) + force[i][j] = force_flat[i * natoms * 3 + j]; + for (int j = 0; j < 9; j++) + virial[i][j] = virial_flat[i * 9 + j]; + } + }; + /** + * @brief Evaluate the energy, force, virial, atomic energy, and atomic virial by using this DP model deviation. + * @param[out] ener The system energy. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[out] atom_energy The atomic energy. + * @param[out] atom_virial The atomic virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + **/ + template + void compute(std::vector &ener, + std::vector> &force, + std::vector> &virial, + std::vector> &atom_energy, + std::vector> &atom_virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const int nghost, + const InputNlist &lmp_list, + const int &ago) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + + std::vector energy_flat(numb_models); + std::vector force_flat(numb_models * natoms * 3); + std::vector virial_flat(numb_models * 9); + std::vector atom_energy_flat(numb_models * natoms); + std::vector atom_virial_flat(numb_models * natoms * 9); + double *ener_ = &energy_flat[0]; + VALUETYPE *force_ = &force_flat[0]; + VALUETYPE *virial_ = &virial_flat[0]; + VALUETYPE *atomic_ener_ = &atom_energy_flat[0]; + VALUETYPE *atomic_virial_ = &atom_virial_flat[0]; + + _DP_DeepPotModelDeviComputeNList(dp, natoms, coord_, atype_, box_, nghost, lmp_list.nl, ago, ener_, force_, virial_, atomic_ener_, atomic_virial_); + + // reshape + ener.resize(numb_models); + force.resize(numb_models); + virial.resize(numb_models); + atom_energy.resize(numb_models); + atom_virial.resize(numb_models); + for (int i = 0; i < numb_models; i++) + { + ener[i] = energy_flat[i]; + force[i].resize(natoms * 3); + virial[i].resize(9); + atom_energy[i].resize(natoms); + atom_virial[i].resize(natoms * 9); + for (int j = 0; j < natoms * 3; j++) + force[i][j] = force_flat[i * natoms * 3 + j]; + for (int j = 0; j < 9; j++) + virial[i][j] = virial_flat[i * 9 + j]; + for (int j = 0; j < natoms; j++) + atom_energy[i][j] = atom_energy_flat[i * natoms + j]; + for (int j = 0; j < natoms * 9; j++) + atom_virial[i][j] = atom_virial_flat[i * natoms * 9 + j]; + } + }; + /** + * @brief Get the cutoff radius. + * @return The cutoff radius. + **/ + double cutoff() const + { + assert(dp); + return DP_DeepPotModelDeviGetCutoff(dp); + }; + /** + * @brief Get the number of types. + * @return The number of types. + **/ + int numb_types() const + { + assert(dp); + return DP_DeepPotModelDeviGetNumbTypes(dp); + }; + + private: + DP_DeepPotModelDevi *dp; + int numb_models; + }; + + /** + * @brief Deep Tensor. + **/ + class DeepTensor + { + public: + /** + * @brief Deep Tensor constructor without initialization. + **/ + DeepTensor() : dt(nullptr) {}; + ~DeepTensor(){}; + /** + * @brief DeepTensor constructor with initialization. + * @param[in] model The name of the frozen model file. + **/ + DeepTensor(const std::string &model) : dt(nullptr) + { + init(model); + }; + /** + * @brief Initialize the DeepTensor. + * @param[in] model The name of the frozen model file. + **/ + void init(const std::string &model) + { + if (dt) + { + std::cerr << "WARNING: deepmd-kit should not be initialized twice, do nothing at the second call of initializer" << std::endl; + return; + } + dt = DP_NewDeepTensor(model.c_str()); + odim = output_dim(); + nsel_types = DP_DeepTensorGetNumbSelTypes(dt); + }; + + /** + * @brief Evaluate the tensor, force and virial by using this Deep Tensor. + * @param[out] tensor The atomic tensor. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + **/ + template + void compute(std::vector &tensor, + const std::vector &coord, + const std::vector &atype, + const std::vector &box) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + + VALUETYPE *tensor_; + VALUETYPE **p_tensor = &tensor_; + int size; + int *p_size = &size; + + _DP_DeepTensorComputeTensor(dt, natoms, coord_, atype_, box_, p_tensor, p_size); + + tensor.resize(size); + std::copy(tensor_, tensor_ + size, tensor.begin()); + delete[] tensor_; + }; + + /** + * @brief Evaluate the tensor, force and virial by using this Deep Tensor with the neighbor list. + * @param[out] tensor The tensor. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + * @param[in] nghost The number of ghost atoms. + * @param[in] nlist The neighbor list. + **/ + template + void compute(std::vector &tensor, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const int nghost, + const InputNlist &lmp_list) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) + { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + + VALUETYPE *tensor_; + VALUETYPE **p_tensor = &tensor_; + int size; + int *p_size = &size; + + _DP_DeepTensorComputeTensorNList(dt, natoms, coord_, atype_, box_, nghost, lmp_list.nl, p_tensor, p_size); + + tensor.resize(size); + std::copy(tensor_, tensor_ + size, tensor.begin()); + delete[] tensor_; + }; + + /** + * @brief Evaluate the global tensor, force and virial by using this Deep Tensor. + * @param[out] global_tensor The global tensor. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + **/ + template + void compute(std::vector &global_tensor, + std::vector &force, + std::vector &virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + global_tensor.resize(odim); + force.resize(odim * natoms * 3); + virial.resize(odim * 9); + VALUETYPE *global_tensor_ = &global_tensor[0]; + VALUETYPE *force_ = &force[0]; + VALUETYPE *virial_ = &virial[0]; + + _DP_DeepTensorCompute(dt, natoms, coord_, atype_, box_, global_tensor_, force_, virial_, nullptr, nullptr, nullptr); + }; + /** + * @brief Evaluate the global tensor, force, virial, atomic tensor, and atomic virial by using this Deep Tensor. + * @param[out] global_tensor The global tensor. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[out] atom_tensor The atomic tensor. + * @param[out] atom_virial The atomic virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + **/ + template + void compute(std::vector &global_tensor, + std::vector &force, + std::vector &virial, + std::vector &atom_tensor, + std::vector &atom_virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + + global_tensor.resize(odim); + force.resize(odim * natoms * 3); + virial.resize(odim * 9); + atom_virial.resize(odim * natoms * 9); + VALUETYPE *global_tensor_ = &global_tensor[0]; + VALUETYPE *force_ = &force[0]; + VALUETYPE *virial_ = &virial[0]; + VALUETYPE *atomic_virial_ = &atom_virial[0]; + + VALUETYPE *atomic_tensor_; + VALUETYPE **p_atomic_tensor = &atomic_tensor_; + int size_at; + int *p_size_at = &size_at; + + _DP_DeepTensorCompute(dt, natoms, coord_, atype_, box_, global_tensor_, force_, virial_, p_atomic_tensor, atomic_virial_, p_size_at); + + atom_tensor.resize(size_at); + std::copy(atomic_tensor_, atomic_tensor_ + size_at, atom_tensor.begin()); + delete[] atomic_tensor_; + }; + + /** + * @brief Evaluate the global tensor, force and virial by using this Deep Tensor with the neighbor list. + * @param[out] global_tensor The global tensor. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + * @param[in] nghost The number of ghost atoms. + * @param[in] nlist The neighbor list. + **/ + template + void compute(std::vector &global_tensor, + std::vector &force, + std::vector &virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const int nghost, + const InputNlist &lmp_list) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) + { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + global_tensor.resize(odim); + force.resize(odim * natoms * 3); + virial.resize(odim * 9); + VALUETYPE *global_tensor_ = &global_tensor[0]; + VALUETYPE *force_ = &force[0]; + VALUETYPE *virial_ = &virial[0]; + + _DP_DeepTensorComputeNList(dt, natoms, coord_, atype_, box_, nghost, lmp_list.nl, global_tensor_, force_, virial_, nullptr, nullptr, nullptr); + }; + /** + * @brief Evaluate the global tensor, force, virial, atomic tensor, and atomic virial by using this Deep Tensor with the neighbor list. + * @param[out] global_tensor The global tensor. + * @param[out] force The force on each atom. + * @param[out] virial The virial. + * @param[out] atom_tensor The atomic tensor. + * @param[out] atom_virial The atomic virial. + * @param[in] coord The coordinates of atoms. The array should be of size nframes x natoms x 3. + * @param[in] atype The atom types. The list should contain natoms ints. + * @param[in] box The cell of the region. The array should be of size nframes x 9 (PBC) or empty (no PBC). + * @param[in] nghost The number of ghost atoms. + * @param[in] nlist The neighbor list. + **/ + template + void compute(std::vector &global_tensor, + std::vector &force, + std::vector &virial, + std::vector &atom_tensor, + std::vector &atom_virial, + const std::vector &coord, + const std::vector &atype, + const std::vector &box, + const int nghost, + const InputNlist &lmp_list) + { + unsigned int natoms = atype.size(); + assert(natoms * 3 == coord.size()); + if (!box.empty()) + { + assert(box.size() == 9); + } + const VALUETYPE *coord_ = &coord[0]; + const VALUETYPE *box_ = !box.empty() ? &box[0] : nullptr; + const int *atype_ = &atype[0]; + + global_tensor.resize(odim); + force.resize(odim * natoms * 3); + virial.resize(odim * 9); + atom_virial.resize(odim * natoms * 9); + VALUETYPE *global_tensor_ = &global_tensor[0]; + VALUETYPE *force_ = &force[0]; + VALUETYPE *virial_ = &virial[0]; + VALUETYPE *atomic_virial_ = &atom_virial[0]; + + VALUETYPE *atomic_tensor_; + VALUETYPE **p_atomic_tensor = &atomic_tensor_; + int size_at; + int *p_size_at = &size_at; + + _DP_DeepTensorComputeNList(dt, natoms, coord_, atype_, box_, nghost, lmp_list.nl, global_tensor_, force_, virial_, p_atomic_tensor, atomic_virial_, p_size_at); + + atom_tensor.resize(size_at); + std::copy(atomic_tensor_, atomic_tensor_ + size_at, atom_tensor.begin()); + delete[] atomic_tensor_; + }; + /** + * @brief Get the cutoff radius. + * @return The cutoff radius. + **/ + double cutoff() const + { + assert(dt); + return DP_DeepTensorGetCutoff(dt); + }; + /** + * @brief Get the number of types. + * @return The number of types. + **/ + int numb_types() const + { + assert(dt); + return DP_DeepTensorGetNumbTypes(dt); + }; + /** + * @brief Get the output dimension. + * @return The output dimension. + **/ + int output_dim() const + { + assert(dt); + return DP_DeepTensorGetOutputDim(dt); + } + + std::vector sel_types() const + { + int* sel_types_arr = DP_DeepTensorGetSelTypes(dt); + std::vector sel_types_vec = std::vector(sel_types_arr, sel_types_arr + nsel_types); + return sel_types_vec; + } + + private: + DP_DeepTensor *dt; + int odim; + int nsel_types; + }; + } +} diff --git a/source/api_c/src/c_api.cc b/source/api_c/src/c_api.cc new file mode 100644 index 0000000000..5fbf40bcd2 --- /dev/null +++ b/source/api_c/src/c_api.cc @@ -0,0 +1,840 @@ +#include "c_api.h" + +#include +#include +#include +#include "c_api_internal.h" +#include "common.h" +#include "DeepPot.h" +#include "DeepTensor.h" + +extern "C" { + +DP_Nlist::DP_Nlist(deepmd::InputNlist& nl) : nl(nl) {} + +DP_Nlist* DP_NewNlist( + int inum_, + int * ilist_, + int * numneigh_, + int ** firstneigh_){ + deepmd::InputNlist nl(inum_, ilist_, numneigh_, firstneigh_); + DP_Nlist* new_nl = new DP_Nlist(nl); + return new_nl; +} + +DP_DeepPot::DP_DeepPot(deepmd::DeepPot& dp) + : dp(dp) {} + +DP_DeepPot* DP_NewDeepPot(const char* c_model) { + std::string model(c_model); + deepmd::DeepPot dp(model); + DP_DeepPot* new_dp = new DP_DeepPot(dp); + return new_dp; +} + +DP_DeepPotModelDevi::DP_DeepPotModelDevi(deepmd::DeepPotModelDevi& dp) + : dp(dp) {} + +DP_DeepPotModelDevi* DP_NewDeepPotModelDevi(const char** c_models, int n_models) { + std::vector model(c_models, c_models + n_models); + deepmd::DeepPotModelDevi dp(model); + DP_DeepPotModelDevi* new_dp = new DP_DeepPotModelDevi(dp); + return new_dp; +} + +DP_DeepTensor::DP_DeepTensor(deepmd::DeepTensor& dt) + : dt(dt) {} + +DP_DeepTensor* DP_NewDeepTensor(const char* c_model) { + std::string model(c_model); + deepmd::DeepTensor dt(model); + DP_DeepTensor* new_dt = new DP_DeepTensor(dt); + return new_dt; +} + +} // extern "C" + +template +inline +void DP_DeepPotCompute_variant ( + DP_DeepPot* dp, + const int natoms, + const VALUETYPE* coord, + const int* atype, + const VALUETYPE* cell, + double* energy, + VALUETYPE* force, + VALUETYPE* virial, + VALUETYPE* atomic_energy, + VALUETYPE* atomic_virial + ) { + // init C++ vectors from C arrays + std::vector coord_(coord, coord+natoms*3); + std::vector atype_(atype, atype+natoms); + std::vector cell_; + if (cell) { + // pbc + cell_.assign(cell, cell+9); + } + double e; + std::vector f, v, ae, av; + + dp->dp.compute(e, f, v, ae, av, coord_, atype_, cell_); + // copy from C++ vectors to C arrays, if not NULL pointer + if(energy) *energy = e; + if(force) std::copy(f.begin(), f.end(), force); + if(virial) std::copy(v.begin(), v.end(), virial); + if(atomic_energy) std::copy(ae.begin(), ae.end(), atomic_energy); + if(atomic_virial) std::copy(av.begin(), av.end(), atomic_virial); +} + +template +void DP_DeepPotCompute_variant ( + DP_DeepPot* dp, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + double* energy, + double* force, + double* virial, + double* atomic_energy, + double* atomic_virial + ); + +template +void DP_DeepPotCompute_variant ( + DP_DeepPot* dp, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + double* energy, + float* force, + float* virial, + float* atomic_energy, + float* atomic_virial + ); + +template +inline +void DP_DeepPotComputeNList_variant ( + DP_DeepPot* dp, + const int natoms, + const VALUETYPE* coord, + const int* atype, + const VALUETYPE* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + VALUETYPE* force, + VALUETYPE* virial, + VALUETYPE* atomic_energy, + VALUETYPE* atomic_virial + ) { + // init C++ vectors from C arrays + std::vector coord_(coord, coord+natoms*3); + std::vector atype_(atype, atype+natoms); + std::vector cell_; + if (cell) { + // pbc + cell_.assign(cell, cell+9); + } + double e; + std::vector f, v, ae, av; + + dp->dp.compute(e, f, v, ae, av, coord_, atype_, cell_, nghost, nlist->nl, ago); + // copy from C++ vectors to C arrays, if not NULL pointer + if(energy) *energy = e; + if(force) std::copy(f.begin(), f.end(), force); + if(virial) std::copy(v.begin(), v.end(), virial); + if(atomic_energy) std::copy(ae.begin(), ae.end(), atomic_energy); + if(atomic_virial) std::copy(av.begin(), av.end(), atomic_virial); +} + +template +void DP_DeepPotComputeNList_variant ( + DP_DeepPot* dp, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + double* force, + double* virial, + double* atomic_energy, + double* atomic_virial + ); + +template +void DP_DeepPotComputeNList_variant ( + DP_DeepPot* dp, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + float* force, + float* virial, + float* atomic_energy, + float* atomic_virial + ); + +template +inline +void flatten_vector(std::vector & onedv, const std::vector>& twodv) { + onedv.clear(); + for (size_t ii = 0; ii < twodv.size(); ++ii) { + onedv.insert(onedv.end(), twodv[ii].begin(), twodv[ii].end()); + } +} + + +template +void DP_DeepPotModelDeviComputeNList_variant ( + DP_DeepPotModelDevi* dp, + const int natoms, + const VALUETYPE* coord, + const int* atype, + const VALUETYPE* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + VALUETYPE* force, + VALUETYPE* virial, + VALUETYPE* atomic_energy, + VALUETYPE* atomic_virial + ) { + // init C++ vectors from C arrays + std::vector coord_(coord, coord+natoms*3); + std::vector atype_(atype, atype+natoms); + std::vector cell_; + if (cell) { + // pbc + cell_.assign(cell, cell+9); + } + // different from DeepPot + std::vector e; + std::vector> f, v, ae, av; + + dp->dp.compute(e, f, v, ae, av, coord_, atype_, cell_, nghost, nlist->nl, ago); + // 2D vector to 2D array, flatten first + if(energy) { + std::copy(e.begin(), e.end(), energy); + } + if(force) { + std::vector f_flat; + flatten_vector(f_flat, f); + std::copy(f_flat.begin(), f_flat.end(), force); + } + if(virial) { + std::vector v_flat; + flatten_vector(v_flat, v); + std::copy(v_flat.begin(), v_flat.end(), virial); + } + if(atomic_energy) { + std::vector ae_flat; + flatten_vector(ae_flat, ae); + std::copy(ae_flat.begin(), ae_flat.end(), atomic_energy); + } + if(atomic_virial) { + std::vector av_flat; + flatten_vector(av_flat, av); + std::copy(av_flat.begin(), av_flat.end(), atomic_virial); + } +} + +template +void DP_DeepPotModelDeviComputeNList_variant ( + DP_DeepPotModelDevi* dp, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + double* force, + double* virial, + double* atomic_energy, + double* atomic_virial + ); + +template +void DP_DeepPotModelDeviComputeNList_variant ( + DP_DeepPotModelDevi* dp, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + float* force, + float* virial, + float* atomic_energy, + float* atomic_virial + ); + +template +inline +void DP_DeepTensorComputeTensor_variant ( + DP_DeepTensor* dt, + const int natoms, + const VALUETYPE* coord, + const int* atype, + const VALUETYPE* cell, + VALUETYPE** tensor, + int* size + ) { + // init C++ vectors from C arrays + std::vector coord_(coord, coord+natoms*3); + std::vector atype_(atype, atype+natoms); + std::vector cell_; + if (cell) { + // pbc + cell_.assign(cell, cell+9); + } + std::vector t; + + dt->dt.compute(t, coord_, atype_, cell_); + // do not know the size of tensor in advance... + *tensor = new VALUETYPE[t.size()]; + std::copy(t.begin(), t.end(), *tensor); + *size = t.size(); +} + +template +void DP_DeepTensorComputeTensor_variant ( + DP_DeepTensor* dt, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + double** tensor, + int* size + ); + +template +void DP_DeepTensorComputeTensor_variant ( + DP_DeepTensor* dt, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + float** tensor, + int* size + ); + +template +inline +void DP_DeepTensorComputeTensorNList_variant ( + DP_DeepTensor* dt, + const int natoms, + const VALUETYPE* coord, + const int* atype, + const VALUETYPE* cell, + const int nghost, + const DP_Nlist* nlist, + VALUETYPE** tensor, + int* size + ) { + // init C++ vectors from C arrays + std::vector coord_(coord, coord+natoms*3); + std::vector atype_(atype, atype+natoms); + std::vector cell_; + if (cell) { + // pbc + cell_.assign(cell, cell+9); + } + std::vector t; + + dt->dt.compute(t, coord_, atype_, cell_, nghost, nlist->nl); + // do not know the size of tensor in advance... + *tensor = new VALUETYPE[t.size()]; + std::copy(t.begin(), t.end(), *tensor); + *size = t.size(); +} + +template +void DP_DeepTensorComputeTensorNList_variant ( + DP_DeepTensor* dt, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + double** tensor, + int* size + ); + +template +void DP_DeepTensorComputeTensorNList_variant ( + DP_DeepTensor* dt, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + float** tensor, + int* size + ); + +template +inline +void DP_DeepTensorCompute_variant ( + DP_DeepTensor* dt, + const int natoms, + const VALUETYPE* coord, + const int* atype, + const VALUETYPE* cell, + VALUETYPE* global_tensor, + VALUETYPE* force, + VALUETYPE* virial, + VALUETYPE** atomic_tensor, + VALUETYPE* atomic_virial, + int* size_at + ) { + // init C++ vectors from C arrays + std::vector coord_(coord, coord+natoms*3); + std::vector atype_(atype, atype+natoms); + std::vector cell_; + if (cell) { + // pbc + cell_.assign(cell, cell+9); + } + std::vector t, f, v, at, av; + + dt->dt.compute(t, f, v, at, av, coord_, atype_, cell_); + // copy from C++ vectors to C arrays, if not NULL pointer + if(global_tensor) std::copy(t.begin(), t.end(), global_tensor); + if(force) std::copy(f.begin(), f.end(), force); + if(virial) std::copy(v.begin(), v.end(), virial); + if(atomic_virial) std::copy(av.begin(), av.end(), atomic_virial); + // do not know the size of atomic tensor in advance... + if(atomic_tensor) { + *atomic_tensor = new VALUETYPE[at.size()]; + std::copy(at.begin(), at.end(), *atomic_tensor); + } + if(size_at) *size_at = at.size(); +} + +template +void DP_DeepTensorCompute_variant ( + DP_DeepTensor* dt, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + double* global_tensor, + double* force, + double* virial, + double** atomic_tensor, + double* atomic_virial, + int* size_at + ); + +template +void DP_DeepTensorCompute_variant ( + DP_DeepTensor* dt, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + float* global_tensor, + float* force, + float* virial, + float** atomic_tensor, + float* atomic_virial, + int* size_at + ); + +template +inline +void DP_DeepTensorComputeNList_variant ( + DP_DeepTensor* dt, + const int natoms, + const VALUETYPE* coord, + const int* atype, + const VALUETYPE* cell, + const int nghost, + const DP_Nlist* nlist, + VALUETYPE* global_tensor, + VALUETYPE* force, + VALUETYPE* virial, + VALUETYPE** atomic_tensor, + VALUETYPE* atomic_virial, + int* size_at + ) { + // init C++ vectors from C arrays + std::vector coord_(coord, coord+natoms*3); + std::vector atype_(atype, atype+natoms); + std::vector cell_; + if (cell) { + // pbc + cell_.assign(cell, cell+9); + } + std::vector t, f, v, at, av; + + dt->dt.compute(t, f, v, at, av, coord_, atype_, cell_, nghost, nlist->nl); + // copy from C++ vectors to C arrays, if not NULL pointer + if(global_tensor) std::copy(t.begin(), t.end(), global_tensor); + if(force) std::copy(f.begin(), f.end(), force); + if(virial) std::copy(v.begin(), v.end(), virial); + if(atomic_virial) std::copy(av.begin(), av.end(), atomic_virial); + // do not know the size of atomic tensor in advance... + if(atomic_tensor) { + *atomic_tensor = new VALUETYPE[at.size()]; + std::copy(at.begin(), at.end(), *atomic_tensor); + } + if(size_at) *size_at = at.size(); +} + +template +void DP_DeepTensorComputeNList_variant ( + DP_DeepTensor* dt, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + double* global_tensor, + double* force, + double* virial, + double** atomic_tensor, + double* atomic_virial, + int* size_at + ); + +template +void DP_DeepTensorComputeNList_variant ( + DP_DeepTensor* dt, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + float* global_tensor, + float* force, + float* virial, + float** atomic_tensor, + float* atomic_virial, + int* size_at + ); + +extern "C" { + +void DP_DeepPotCompute ( + DP_DeepPot* dp, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + double* energy, + double* force, + double* virial, + double* atomic_energy, + double* atomic_virial + ) { + DP_DeepPotCompute_variant(dp, natoms, coord, atype, cell, energy, force, virial, atomic_energy, atomic_virial); +} + +void DP_DeepPotComputef ( + DP_DeepPot* dp, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + double* energy, + float* force, + float* virial, + float* atomic_energy, + float* atomic_virial + ) { + DP_DeepPotCompute_variant(dp, natoms, coord, atype, cell, energy, force, virial, atomic_energy, atomic_virial); +} + +void DP_DeepPotComputeNList ( + DP_DeepPot* dp, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + double* force, + double* virial, + double* atomic_energy, + double* atomic_virial + ) { + DP_DeepPotComputeNList_variant(dp, natoms, coord, atype, cell, nghost, nlist, ago, energy, force, virial, atomic_energy, atomic_virial); +} + +void DP_DeepPotComputeNListf ( + DP_DeepPot* dp, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + float* force, + float* virial, + float* atomic_energy, + float* atomic_virial + ) { + DP_DeepPotComputeNList_variant(dp, natoms, coord, atype, cell, nghost, nlist, ago, energy, force, virial, atomic_energy, atomic_virial); +} + +const char* DP_DeepPotGetTypeMap( + DP_DeepPot* dp + ) { + std::string type_map; + dp->dp.get_type_map(type_map); + // copy from string to char* + const std::string::size_type size = type_map.size(); + // +1 for '\0' + char *buffer = new char[size + 1]; + std::copy(type_map.begin(), type_map.end(), buffer); + buffer[size] = '\0'; + return buffer; +} + +double DP_DeepPotGetCutoff( + DP_DeepPot* dp + ) { + return dp->dp.cutoff(); +} + +int DP_DeepPotGetNumbTypes( + DP_DeepPot* dp + ) { + return dp->dp.numb_types(); +} + +void DP_DeepPotModelDeviComputeNList ( + DP_DeepPotModelDevi* dp, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + double* force, + double* virial, + double* atomic_energy, + double* atomic_virial + ) { + DP_DeepPotModelDeviComputeNList_variant(dp, natoms, coord, atype, cell, nghost, nlist, ago, energy, force, virial, atomic_energy, atomic_virial); +} + +void DP_DeepPotModelDeviComputeNListf ( + DP_DeepPotModelDevi* dp, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + const int ago, + double* energy, + float* force, + float* virial, + float* atomic_energy, + float* atomic_virial + ) { + DP_DeepPotModelDeviComputeNList_variant(dp, natoms, coord, atype, cell, nghost, nlist, ago, energy, force, virial, atomic_energy, atomic_virial); +} + +double DP_DeepPotModelDeviGetCutoff( + DP_DeepPotModelDevi* dp + ) { + return dp->dp.cutoff(); +} + +int DP_DeepPotModelDeviGetNumbTypes( + DP_DeepPotModelDevi* dp + ) { + return dp->dp.numb_types(); +} + +void DP_DeepTensorComputeTensor ( + DP_DeepTensor* dt, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + double** tensor, + int* size + ) { + DP_DeepTensorComputeTensor_variant(dt, natoms, coord, atype, cell, tensor, size); +} + +void DP_DeepTensorComputeTensorf ( + DP_DeepTensor* dt, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + float** tensor, + int* size + ) { + DP_DeepTensorComputeTensor_variant(dt, natoms, coord, atype, cell, tensor, size); +} + +void DP_DeepTensorComputeTensorNList ( + DP_DeepTensor* dt, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + double** tensor, + int* size + ) { + DP_DeepTensorComputeTensorNList_variant(dt, natoms, coord, atype, cell, nghost, nlist, tensor, size); +} + +void DP_DeepTensorComputeTensorNListf ( + DP_DeepTensor* dt, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + float** tensor, + int* size + ) { + DP_DeepTensorComputeTensorNList_variant(dt, natoms, coord, atype, cell, nghost, nlist, tensor, size); +} + +void DP_DeepTensorCompute ( + DP_DeepTensor* dt, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + double* global_tensor, + double* force, + double* virial, + double** atomic_tensor, + double* atomic_virial, + int* size_at + ) { + DP_DeepTensorCompute_variant(dt, natoms, coord, atype, cell, global_tensor, force, virial, atomic_tensor, atomic_virial, size_at); +} + +void DP_DeepTensorComputef ( + DP_DeepTensor* dt, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + float* global_tensor, + float* force, + float* virial, + float** atomic_tensor, + float* atomic_virial, + int* size_at + ) { + DP_DeepTensorCompute_variant(dt, natoms, coord, atype, cell, global_tensor, force, virial, atomic_tensor, atomic_virial, size_at); +} + +void DP_DeepTensorComputeNList ( + DP_DeepTensor* dt, + const int natoms, + const double* coord, + const int* atype, + const double* cell, + const int nghost, + const DP_Nlist* nlist, + double* global_tensor, + double* force, + double* virial, + double** atomic_tensor, + double* atomic_virial, + int* size_at + ) { + DP_DeepTensorComputeNList_variant(dt, natoms, coord, atype, cell, nghost, nlist, global_tensor, force, virial, atomic_tensor, atomic_virial, size_at); +} + +void DP_DeepTensorComputeNListf ( + DP_DeepTensor* dt, + const int natoms, + const float* coord, + const int* atype, + const float* cell, + const int nghost, + const DP_Nlist* nlist, + float* global_tensor, + float* force, + float* virial, + float** atomic_tensor, + float* atomic_virial, + int* size_at + ) { + DP_DeepTensorComputeNList_variant(dt, natoms, coord, atype, cell, nghost, nlist, global_tensor, force, virial, atomic_tensor, atomic_virial, size_at); +} + +double DP_DeepTensorGetCutoff( + DP_DeepTensor* dt + ) { + return dt->dt.cutoff(); +} + +int DP_DeepTensorGetNumbTypes( + DP_DeepTensor* dt + ) { + return dt->dt.numb_types(); +} + +int DP_DeepTensorGetOutputDim( + DP_DeepTensor* dt + ) { + return dt->dt.output_dim(); +} + +int* DP_DeepTensorGetSelTypes( + DP_DeepTensor* dt + ) { + return (int*) &(dt->dt.sel_types())[0]; +} + +int DP_DeepTensorGetNumbSelTypes( + DP_DeepTensor* dt + ) { + return dt->dt.sel_types().size(); +} + +void DP_ConvertPbtxtToPb( + const char* c_pbtxt, + const char* c_pb + ) { + std::string pbtxt(c_pbtxt); + std::string pb(c_pb); + deepmd::convert_pbtxt_to_pb(pbtxt, pb); +} + +} // extern "C" \ No newline at end of file diff --git a/source/api_c/tests/CMakeLists.txt b/source/api_c/tests/CMakeLists.txt new file mode 100644 index 0000000000..7d864ee295 --- /dev/null +++ b/source/api_c/tests/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.9) +project(deepmd_api_c_test) + +file(GLOB TEST_SRC test_*.cc) + +set_target_properties( + ${LIB_DEEPMD_C} + PROPERTIES + INSTALL_RPATH "$ORIGIN;${TensorFlow_LIBRARY_PATH}" +) + +add_executable( runUnitTests_c ${TEST_SRC} ) +target_link_libraries(runUnitTests_c PRIVATE GTest::gtest_main ${LIB_DEEPMD_C} rt coverage_config) +target_link_libraries(runUnitTests_c PRIVATE ${LIB_DEEPMD}) +target_precompile_headers(runUnitTests_c PRIVATE test_utils.h [["deepmd.hpp"]]) +add_test( runUnitTests_c runUnitTests_c ) +set_target_properties( + runUnitTests_c + PROPERTIES + INSTALL_RPATH "$ORIGIN/../lib" +) +install(TARGETS runUnitTests_c DESTINATION bin/) + diff --git a/source/api_c/tests/test_deepdipole_hpp.cc b/source/api_c/tests/test_deepdipole_hpp.cc new file mode 100644 index 0000000000..6d02e5ccdd --- /dev/null +++ b/source/api_c/tests/test_deepdipole_hpp.cc @@ -0,0 +1,428 @@ +#include +#include +#include +#include +#include +#include "deepmd.hpp" +#include "test_utils.h" + +template +class TestInferDeepDipole : public ::testing::Test +{ +protected: + std::vector coord = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + std::vector atype = { + 0, 1, 1, 0, 1, 1 + }; + std::vector box = { + 13., 0., 0., 0., 13., 0., 0., 0., 13. + }; + std::vector expected_d = { + -9.274180565967479195e-01,2.698028341272042496e+00,2.521268387140979117e-01,2.927260638453461628e+00,-8.571926301526779923e-01,1.667785136187720063e+00 + }; + int natoms = 6; + + deepmd::hpp::DeepTensor dp; + + void SetUp() override { + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deepdipole.pbtxt", "deepdipole.pb"); + + dp.init("deepdipole.pb"); + }; + + void TearDown() override { + remove( "deepdipole.pb" ) ; + }; +}; + +TYPED_TEST_SUITE(TestInferDeepDipole, ValueTypes); + +TYPED_TEST(TestInferDeepDipole, cpu_build_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::hpp::DeepTensor& dp = this -> dp; + EXPECT_EQ(dp.cutoff(), 4.); + EXPECT_EQ(dp.numb_types(), 2); + EXPECT_EQ(dp.output_dim(), 3); + std::vector sel_types = dp.sel_types(); + EXPECT_EQ(sel_types.size(), 1); + EXPECT_EQ(sel_types[0], 0); + + std::vector value; + dp.compute(value, coord, atype, box); + + EXPECT_EQ(value.size(), expected_d.size()); + for(int ii = 0; ii < expected_d.size(); ++ii){ + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); + } +} + + +TYPED_TEST(TestInferDeepDipole, cpu_lmp_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::hpp::DeepTensor& dp = this -> dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + std::vector > nlist_data; + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + convert_nlist(inlist, nlist_data); + + std::vector value; + dp.compute(value, coord_cpy, atype_cpy, box, nall-nloc, inlist); + + EXPECT_EQ(value.size(), expected_d.size()); + for(int ii = 0; ii < expected_d.size(); ++ii){ + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); + } +} + + +template +class TestInferDeepDipoleNew : public ::testing::Test +{ +protected: + std::vector coord = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + std::vector atype = { + 0, 1, 1, 0, 1, 1 + }; + std::vector box = { + 13., 0., 0., 0., 13., 0., 0., 0., 13. + }; + std::vector expected_t = { + -1.128427726201255282e-01, 2.654103846999197880e-01, 2.625816377288122533e-02, 3.027556488877700680e-01, -7.475444785689989990e-02, 1.526291164572509684e-01 + }; + std::vector expected_f = { + 8.424897862241968738e-02, -3.823566783202275721e-02, 3.570797165027734810e-01, 6.102563129736437997e-02, -1.351209759852018133e-01, -2.438224487466488510e-01, -1.403204771681088869e-01, 1.719596545791735875e-01, -1.136584427103610045e-01, 2.761686212947551955e-02, -7.247860200915196005e-02, 6.208831127377397591e-02, -2.605870723577520809e-01, -4.504074577536486268e-02, 7.340240097998475266e-02, 2.280160774766013809e-01, 1.189163370225677641e-01, -1.350895372995223886e-01, -4.294311497114180337e-02, 1.524802094783661577e-01, 1.070451777645946290e-01, -1.259336332521076574e-01, -2.087610788959351760e-01, 9.447141346538817652e-02, 1.668125597515543457e-01, 5.487037060760904805e-02, -2.014994036104674757e-01, -7.411985441205551361e-02, 3.614456658821710300e-01, 2.901174891391154476e-01, -4.871926969937838414e-02, -1.252747945819455699e-01, -2.555459318266457558e-01, 1.249033125831290059e-01, -2.347603724902655176e-01, -3.458874493198500766e-02, 3.563990394229877290e-01, 1.052342031228763047e-01, 1.907268232932498031e-01, -2.432737821373903708e-01, 1.016781829972335099e-01, -7.707616437996064884e-02, -1.139199805053340564e-01, -2.068592154909300040e-01, -1.156337826476897951e-01, 6.583817133933017596e-02, 2.902207490750204344e-01, 9.945482314729316153e-02, 7.986986504051810098e-02, -2.549975565538568079e-01, 1.275343199697696051e-01, -1.449133131601115787e-01, -3.527636315034351350e-02, -2.250060193826620980e-01 + }; + std::vector expected_v = { + 3.479789535931299138e-02, 4.337414719007849292e-03, -3.647371468256610082e-03, 8.053492919528318708e-03, 1.003834811499279773e-03, -8.441338187607602033e-04, -6.695998268698949256e-03, -8.346286793845711892e-04, 7.018468440279366279e-04, -4.515896716004976635e-02, 1.891794570218296306e-02, 3.417435352652402336e-02, 9.998952222904963771e-02, -4.188750255541257711e-02, -7.566774655171297492e-02, 1.804286120725206444e-01, -7.558495911146115298e-02, -1.365405712981232755e-01, -1.002593446510361419e-01, -1.117945222697993429e-01, 7.449172735713084637e-02, 7.770237313970995707e-02, 1.313723119887387492e-01, -8.655414676270002661e-02, -4.973937467461287537e-02, -8.663006083493235421e-02, 5.703914957966123994e-02, -3.382231967662072125e-02, -4.215813217482468345e-03, 3.545115660155720612e-03, -8.247565860499378454e-03, -1.028025206407854253e-03, 8.644757417520612143e-04, 6.761330949063471332e-03, 8.427721296283078580e-04, -7.086947453692606178e-04, -1.622698090933780493e-02, 1.305372051650728060e-01, -2.082599910094798112e-01, -7.109985131471197733e-03, 2.202585658101286273e-02, -3.554509763049529952e-02, 1.436400379134906459e-02, -3.554915857551419617e-02, 5.763638171798115412e-02, 2.074946305037073946e-01, 5.016353704485233822e-02, -5.700401936915034523e-02, 1.082138666905367308e-01, 2.616159414496492877e-02, -2.972908425564194101e-02, -1.229314789425654392e-01, -2.971969820589494271e-02, 3.377238432488059716e-02, 7.622024445219390681e-03, 9.500540384976005961e-04, -7.989090778275298932e-04, -2.952148931042387209e-02, -3.679732378636401541e-03, 3.094320409307891630e-03, -9.534268115386618486e-04, -1.188407357158671420e-04, 9.993425503379762414e-05, 9.319088860655992679e-02, -3.903942630815338682e-02, -7.052283462118023871e-02, 1.544831983829924038e-01, -6.471593445773991815e-02, -1.169062041817236081e-01, -6.990884596438741438e-02, 2.928613817427033750e-02, 5.290399154061733306e-02, 7.491400658274136037e-02, 1.273824184577304897e-01, -8.391492311946648075e-02, 3.543872837542783732e-02, 4.324623973455964804e-02, -2.873418641045778418e-02, -8.444981234074398768e-02, -1.531171183141288306e-01, 1.007308415346981068e-01, -6.396885751015785743e-03, -7.973455327045167592e-04, 6.704951070469818575e-04, 2.915483242551994078e-02, 3.634030104030812076e-03, -3.055888951116827318e-03, 6.608747470375698129e-04, 8.237532257692081912e-05, -6.927015762150179410e-05, -6.099175331115514430e-03, 2.402310352789886402e-02, -3.861491558256636286e-02, -2.583867422346154685e-02, 6.050621302336450097e-02, -9.822840263095998503e-02, -3.827994718203701213e-02, 1.252239810257823327e-01, -2.018867305507059950e-01, 1.136620144506474833e-01, 2.747872876828840599e-02, -3.122582814578225147e-02, -2.136319389661417989e-01, -5.164728194785846160e-02, 5.869009312256637939e-02, -3.147575788810638014e-02, -7.609523885036708832e-03, 8.647186232996251914e-03, -5.990706138603461330e-03, -7.467169124604876177e-04, 6.279210400235934152e-04, -9.287887182821588476e-04, -1.157696985960763821e-04, 9.735179200124630735e-05, -2.966271471326579340e-02, -3.697335544996301071e-03, 3.109123071928715683e-03, 1.800225987816693740e-01, -7.541487246259104271e-02, -1.362333179969384966e-01, -7.524185541795300192e-02, 3.152023672914239238e-02, 5.693978247845072477e-02, 5.703636164117102669e-02, -2.389361095778780308e-02, -4.316265205277792366e-02, -4.915584336537091176e-02, -8.674240294138457763e-02, 5.709724154860432860e-02, -8.679070528401405804e-02, -1.572017650485294793e-01, 1.034201569997979520e-01, -3.557746655862283752e-02, -8.626268394893003844e-02, 5.645546718878535764e-02, 6.848075985139651621e-03, 8.535845420570665554e-04, -7.177870012752625602e-04, 8.266638576582277997e-04, 1.030402542123569647e-04, -8.664748649675494882e-05, 2.991751925173294011e-02, 3.729095884068693231e-03, -3.135830629785046203e-03, 1.523793442834292522e-02, -3.873020552543556677e-02, 6.275576045602117292e-02, -3.842536616563556329e-02, 1.249268983543572881e-01, -2.014296501045876875e-01, 1.288704808602599873e-02, -6.326999354443738066e-02, 1.014064886873057153e-01, -1.318711149757016143e-01, -3.188092889522457091e-02, 3.622832829002789468e-02, -3.210149046681261276e-02, -7.760799893075580151e-03, 8.819090787585878374e-03, -2.047554776382226327e-01, -4.950132426418570042e-02, 5.625150484566552450e-02 + }; + std::vector expected_gt; + std::vector expected_gv; + int natoms = 6; + int nsel = 2; + int odim; + deepmd::hpp::DeepTensor dp; + + void SetUp() override { + std::string file_name = "../../tests/infer/deepdipole_new.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deepdipole_new.pbtxt", "deepdipole_new.pb"); + dp.init("deepdipole_new.pb"); + odim = dp.output_dim (); + + expected_gt.resize(odim); + for(int ii = 0; ii < nsel; ++ii){ + for(int dd = 0; dd < odim; ++dd){ + expected_gt[dd] += expected_t[ii*odim+dd]; + } + } + + expected_gv.resize(odim * 9); + for (int kk = 0; kk < odim; ++kk){ + for(int ii = 0; ii < natoms; ++ii){ + for(int dd = 0; dd < 9; ++dd){ + expected_gv[kk*9 + dd] += expected_v[kk*natoms*9 + ii*9 + dd]; + } + } + } + }; + + void TearDown() override { + remove( "deepdipole_new.pb" ) ; + }; +}; + +TYPED_TEST_SUITE(TestInferDeepDipoleNew, ValueTypes); + +TYPED_TEST(TestInferDeepDipoleNew, cpu_build_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_t = this -> expected_t; + std::vector& expected_f = this -> expected_f; + std::vector& expected_v = this -> expected_v; + std::vector& expected_gt = this -> expected_gt; + std::vector& expected_gv = this -> expected_gv; + int& natoms = this -> natoms; + int& nsel = this -> nsel; + int& odim = this -> odim; + deepmd::hpp::DeepTensor& dp = this -> dp; + EXPECT_EQ(dp.cutoff(), 4.); + EXPECT_EQ(dp.numb_types(), 2); + EXPECT_EQ(dp.output_dim(), 3); + std::vector sel_types = dp.sel_types(); + EXPECT_EQ(sel_types.size(), 1); + EXPECT_EQ(sel_types[0], 0); + + std::vector gt, ff, vv, at, av; + + dp.compute(at, coord, atype, box); + EXPECT_EQ(at.size(), expected_t.size()); + for(int ii = 0; ii < expected_t.size(); ++ii){ + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); + } + + dp.compute(gt, ff, vv, coord, atype, box); + EXPECT_EQ(gt.size(), expected_gt.size()); + for(int ii = 0; ii < expected_gt.size(); ++ii){ + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); + } + EXPECT_EQ(ff.size(), expected_f.size()); + for(int ii = 0; ii < expected_f.size(); ++ii){ + EXPECT_LT(fabs(ff[ii] - expected_f[ii]), EPSILON); + } + EXPECT_EQ(vv.size(), expected_gv.size()); + for(int ii = 0; ii < expected_gv.size(); ++ii){ + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); + } + + dp.compute(gt, ff, vv, at, av, coord, atype, box); + EXPECT_EQ(gt.size(), expected_gt.size()); + for(int ii = 0; ii < expected_gt.size(); ++ii){ + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); + } + EXPECT_EQ(ff.size(), expected_f.size()); + for(int ii = 0; ii < expected_f.size(); ++ii){ + EXPECT_LT(fabs(ff[ii] - expected_f[ii]), EPSILON); + } + EXPECT_EQ(vv.size(), expected_gv.size()); + for(int ii = 0; ii < expected_gv.size(); ++ii){ + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); + } + EXPECT_EQ(at.size(), expected_t.size()); + for(int ii = 0; ii < expected_t.size(); ++ii){ + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); + } + EXPECT_EQ(av.size(), expected_v.size()); + for(int ii = 0; ii < expected_v.size(); ++ii){ + EXPECT_LT(fabs(av[ii] - expected_v[ii]), EPSILON); + } +} + + +TYPED_TEST(TestInferDeepDipoleNew, cpu_lmp_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_t = this -> expected_t; + std::vector& expected_f = this -> expected_f; + std::vector& expected_v = this -> expected_v; + std::vector& expected_gt = this -> expected_gt; + std::vector& expected_gv = this -> expected_gv; + int& natoms = this -> natoms; + int& nsel = this -> nsel; + int& odim = this -> odim; + deepmd::hpp::DeepTensor& dp = this -> dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + std::vector > nlist_data; + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + convert_nlist(inlist, nlist_data); + + std::vector gt, ff, vv, at, av; + + dp.compute(at, coord_cpy, atype_cpy, box, nall-nloc, inlist); + + EXPECT_EQ(at.size(), expected_t.size()); + for(int ii = 0; ii < expected_t.size(); ++ii){ + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); + } + + + dp.compute(gt, ff, vv, coord_cpy, atype_cpy, box, nall-nloc, inlist); + + EXPECT_EQ(gt.size(), expected_gt.size()); + for(int ii = 0; ii < expected_gt.size(); ++ii){ + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); + } + // remove ghost atoms + std::vector rff (odim * nloc * 3); + for(int kk = 0; kk < odim; ++kk){ + _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); + } + EXPECT_EQ(rff.size(), expected_f.size()); + for(int ii = 0; ii < expected_f.size(); ++ii){ + EXPECT_LT(fabs(rff[ii] - expected_f[ii]), EPSILON); + } + // virial + EXPECT_EQ(vv.size(), expected_gv.size()); + for(int ii = 0; ii < expected_gv.size(); ++ii){ + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); + } + + + dp.compute(gt, ff, vv, at, av, coord_cpy, atype_cpy, box, nall-nloc, inlist); + + EXPECT_EQ(gt.size(), expected_gt.size()); + for(int ii = 0; ii < expected_gt.size(); ++ii){ + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); + } + // remove ghost atoms + for(int kk = 0; kk < odim; ++kk){ + _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); + } + EXPECT_EQ(rff.size(), expected_f.size()); + for(int ii = 0; ii < expected_f.size(); ++ii){ + EXPECT_LT(fabs(rff[ii] - expected_f[ii]), EPSILON); + } + // virial + EXPECT_EQ(vv.size(), expected_gv.size()); + for(int ii = 0; ii < expected_gv.size(); ++ii){ + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); + } + // atom tensor + EXPECT_EQ(at.size(), expected_t.size()); + for(int ii = 0; ii < expected_t.size(); ++ii){ + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); + } + // atom virial + std::vector rav (odim * nloc * 9); + for(int kk = 0; kk < odim; ++kk){ + _fold_back(rav.begin() + kk * nloc * 9, av.begin() + kk * nall * 9, mapping, nloc, nall, 9); + } + EXPECT_EQ(rav.size(), expected_v.size()); + for(int ii = 0; ii < expected_v.size(); ++ii){ + EXPECT_LT(fabs(rav[ii] - expected_v[ii]), EPSILON); + } +} + + +template +class TestInferDeepDipoleFake : public ::testing::Test +{ +protected: + std::vector coord = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + std::vector atype = { + 0, 1, 1, 0, 1, 1 + }; + std::vector box = { + 13., 0., 0., 0., 13., 0., 0., 0., 13. + }; + std::vector expected_d = { + -3.186217894664857830e-01, 1.082220317383403296e+00, 5.646623185237639730e-02, 7.426508038929955369e-01, -3.115996324658170114e-01, -5.619108089573777720e-01, -4.181578166874897473e-01, -7.579762930974662805e-01, 4.980618433125854616e-01, 1.059635561913792712e+00, -2.641989315855929332e-01, 5.307984468104405273e-01, -1.484512535335152095e-01, 4.978588497891502374e-01, -8.022467807199461509e-01, -9.165936539882671985e-01, -2.238112120606238209e-01, 2.553133145814526217e-01 + }; + int natoms = 6; + + deepmd::hpp::DeepTensor dp; + + void SetUp() override { + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deepdipole_fake.pbtxt", "deepdipole_fake.pb"); + + dp.init("deepdipole_fake.pb"); + }; + + void TearDown() override { + remove( "deepdipole_fake.pb" ) ; + }; +}; + +TYPED_TEST_SUITE(TestInferDeepDipoleFake, ValueTypes); + +TYPED_TEST(TestInferDeepDipoleFake, cpu_build_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::hpp::DeepTensor& dp = this -> dp; + EXPECT_EQ(dp.cutoff(), 2.); + EXPECT_EQ(dp.numb_types(), 2); + EXPECT_EQ(dp.output_dim(), 3); + std::vector sel_types = dp.sel_types(); + EXPECT_EQ(sel_types.size(), 2); + EXPECT_EQ(sel_types[0], 0); + EXPECT_EQ(sel_types[1], 1); + + std::vector value; + dp.compute(value, coord, atype, box); + + EXPECT_EQ(value.size(), expected_d.size()); + for(int ii = 0; ii < expected_d.size(); ++ii){ + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); + } +} + + +TYPED_TEST(TestInferDeepDipoleFake, cpu_lmp_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::hpp::DeepTensor& dp = this -> dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + std::vector > nlist_data; + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + convert_nlist(inlist, nlist_data); + + std::vector value; + dp.compute(value, coord_cpy, atype_cpy, box, nall-nloc, inlist); + + EXPECT_EQ(value.size(), expected_d.size()); + for(int ii = 0; ii < expected_d.size(); ++ii){ + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); + } +} + diff --git a/source/api_c/tests/test_deeppolar_hpp.cc b/source/api_c/tests/test_deeppolar_hpp.cc new file mode 100644 index 0000000000..741edcf48e --- /dev/null +++ b/source/api_c/tests/test_deeppolar_hpp.cc @@ -0,0 +1,335 @@ +#include +#include +#include +#include +#include +#include "deepmd.hpp" +#include "test_utils.h" + +template +class TestInferDeepPolar : public ::testing::Test +{ +protected: + std::vector coord = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + std::vector atype = { + 0, 1, 1, 0, 1, 1 + }; + std::vector box = { + 13., 0., 0., 0., 13., 0., 0., 0., 13. + }; + std::vector expected_d = { + 1.061407927405987051e-01,-3.569013342133873778e-01,-2.862108976089940138e-02,-3.569013342133875444e-01,1.304367268874677244e+00,1.037647501453442256e-01,-2.862108976089940138e-02,1.037647501453441284e-01,8.100521520762453409e-03,1.236797829492216616e+00,-3.717307430531632262e-01,7.371515676976750919e-01,-3.717307430531630041e-01,1.127222682121889058e-01,-2.239181552775717510e-01,7.371515676976746478e-01,-2.239181552775717787e-01,4.448255365635306879e-01 + }; + int natoms; + + deepmd::hpp::DeepTensor dp; + + void SetUp() override { + std::string file_name = "../../tests/infer/deeppolar.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deeppolar.pbtxt", "deeppolar.pb"); + + dp.init("deeppolar.pb"); + + natoms = expected_d.size(); + }; + + void TearDown() override { + remove( "deeppolar.pb" ) ; + }; +}; + +TYPED_TEST_SUITE(TestInferDeepPolar, ValueTypes); + +TYPED_TEST(TestInferDeepPolar, cpu_build_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::hpp::DeepTensor& dp = this -> dp; + + EXPECT_EQ(dp.cutoff(), 6.); + EXPECT_EQ(dp.numb_types(), 2); + EXPECT_EQ(dp.output_dim(), 9); + std::vector sel_types = dp.sel_types(); + EXPECT_EQ(sel_types.size(), 1); + EXPECT_EQ(sel_types[0], 0); + + std::vector value; + dp.compute(value, coord, atype, box); + + EXPECT_EQ(value.size(), expected_d.size()); + for(int ii = 0; ii < expected_d.size(); ++ii){ + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); + } +} + + +TYPED_TEST(TestInferDeepPolar, cpu_lmp_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::hpp::DeepTensor& dp = this -> dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + std::vector > nlist_data; + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + convert_nlist(inlist, nlist_data); + + std::vector value; + dp.compute(value, coord_cpy, atype_cpy, box, nall-nloc, inlist); + + EXPECT_EQ(value.size(), expected_d.size()); + for(int ii = 0; ii < expected_d.size(); ++ii){ + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); + } +} + + +template +class TestInferDeepPolarNew : public ::testing::Test +{ +protected: + std::vector coord = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + std::vector atype = { + 0, 1, 1, 0, 1, 1 + }; + std::vector box = { + 13., 0., 0., 0., 13., 0., 0., 0., 13. + }; + std::vector expected_t = { + 1.936327241487292961e+00, 5.198696351735779264e-02, 3.888336625074450149e-03, 5.198696351735781346e-02, 1.764967784387830196e+00, -1.354658545697527347e-02, 3.888336625074451016e-03, -1.354658545697527000e-02, 1.939288409902199639e+00, 1.786740420980893029e+00, 4.868765294055640847e-02, -9.812132615180739481e-02, 4.868765294055640847e-02, 1.925999147066305373e+00, 2.895028407651457567e-02, -9.812132615180743644e-02, 2.895028407651457220e-02, 1.883109989034779996e+00 + }; + std::vector expected_f = { + 5.305178446980116092e-02, -1.127314829623577049e-02, 1.136493514861047216e-01, 5.598130220328862322e-05, -4.352126938892845326e-02, -7.700608888887500170e-02, -1.050015668789053697e-01, 5.882396336737016895e-02, -3.723875897544067642e-02, -7.850322286760008650e-02, 7.279117637753844405e-02, -6.178451060078461732e-02, 3.404361490778949895e-01, 5.447934529195214842e-02, -8.698375128815737101e-02, -2.100391251033939810e-01, -1.313000673516965255e-01, 1.493637582671529240e-01, -9.589318874236771317e-02, 6.285887854370801608e-02, -1.824395427630142175e-01, -3.264267092869802683e-02, 3.637498661083633789e-02, 1.524859582123189172e-01, 1.442484990808054202e-01, -8.957992476622803069e-02, 3.076469140583825215e-02, 4.909822745881124717e-02, -2.559151672032903835e-01, -1.522830913546814324e-01, -2.885480042033320910e-02, 7.730841025065784966e-02, 1.553301391955271560e-01, -3.595606644821771475e-02, 1.689528165643162105e-01, -3.858154695988691516e-03, 5.018843026262573281e-02, 1.756005154318779349e-02, 3.489323893614350303e-02, -4.020411124876955428e-02, 2.218648284685413238e-02, -8.086177159691650476e-03, -2.222392408702593067e-02, -3.825892777133557687e-02, -1.689393838770965675e-02, -5.465804822761769627e-02, -1.398775875506316768e-01, -1.165702490994514756e-01, 5.449067849718619572e-02, 1.588580450812354106e-01, -8.209560373418453572e-02, 1.240697480360127003e-02, -2.046806414931008622e-02, 1.887527294448937965e-01, -9.589318874236771317e-02, 6.285887854370801608e-02, -1.824395427630142175e-01, -3.264267092869802683e-02, 3.637498661083633789e-02, 1.524859582123189172e-01, 1.442484990808054202e-01, -8.957992476622803069e-02, 3.076469140583825215e-02, 4.909822745881124717e-02, -2.559151672032903835e-01, -1.522830913546814324e-01, -2.885480042033320910e-02, 7.730841025065784966e-02, 1.553301391955271560e-01, -3.595606644821771475e-02, 1.689528165643162105e-01, -3.858154695988691516e-03, 4.038746042068122599e-02, -2.549213597407858356e-01, -1.131801705114504619e-01, 1.489732376295762606e-01, 2.734584831542113958e-01, -1.125511889088352951e-01, -1.908551011160136424e-01, -2.400995606986339528e-02, 2.255650484976146619e-01, -2.185213968874370055e-02, 1.475333123369945709e-01, 9.584417756169674729e-02, -1.576380405016522893e-02, -5.153693137796186430e-02, -8.489897831367294867e-02, 3.911034680466508873e-02, -9.052354830259493057e-02, -1.077888832535272776e-02, -1.970229486427777510e-01, -6.538978166042377915e-02, -1.570533119125729904e-01, 1.417940206277617798e-01, -4.684714285705613573e-02, 6.070882964241105378e-02, 5.715183445260185735e-02, 1.138024049318459713e-01, 9.374622673558237473e-02, 3.096927839536914306e-02, -9.232883741117139942e-02, -6.499836527010099951e-02, 2.839980861544661936e-02, 8.097497759757724123e-03, 1.006700103228213017e-01, -6.129199344840163821e-02, 8.266585923704758421e-02, -3.307338951814068478e-02, 5.018843026262574669e-02, 1.756005154318778308e-02, 3.489323893614350997e-02, -4.020411124876957509e-02, 2.218648284685414279e-02, -8.086177159691652211e-03, -2.222392408702593067e-02, -3.825892777133557687e-02, -1.689393838770965675e-02, -5.465804822761770321e-02, -1.398775875506316491e-01, -1.165702490994514756e-01, 5.449067849718619572e-02, 1.588580450812354106e-01, -8.209560373418453572e-02, 1.240697480360125615e-02, -2.046806414931009316e-02, 1.887527294448937965e-01, -1.970229486427777510e-01, -6.538978166042375140e-02, -1.570533119125729626e-01, 1.417940206277618076e-01, -4.684714285705613573e-02, 6.070882964241105378e-02, 5.715183445260184347e-02, 1.138024049318459713e-01, 9.374622673558236086e-02, 3.096927839536912919e-02, -9.232883741117139942e-02, -6.499836527010102727e-02, 2.839980861544661589e-02, 8.097497759757731062e-03, 1.006700103228213017e-01, -6.129199344840162433e-02, 8.266585923704758421e-02, -3.307338951814066397e-02, -3.078161564779093723e-02, -8.748776750553553111e-03, -2.162930108693108394e-02, 2.135313622214399243e-02, -8.845621737097757523e-03, 9.365293934359546560e-03, 8.562579091543631032e-03, 1.772751551871581607e-02, 1.573655414890783033e-02, -3.649820158632081230e-02, -1.904914900326310223e-01, -1.076542087674599024e-01, -5.186655049718805199e-02, 1.686765146765009937e-01, -6.620206332305828001e-02, 8.923065241761217459e-02, 2.168185832506550753e-02, 1.703837250941818704e-01 + }; + std::vector expected_v = { + -2.123013313652813774e-03, -2.646248889538913257e-04, 2.225254748021367093e-04, 9.843593195853941446e-04, 1.226963457840150472e-04, -1.031764725911038809e-04, -8.467513732241481721e-04, -1.055440805151912256e-04, 8.875297679686559459e-05, 1.829118379697145316e-02, 2.302438731350108913e-03, -1.890198823577125386e-03, 3.300229266409118040e-02, -1.339230641165423293e-02, -2.445540228188634868e-02, 5.127826101331301595e-02, -2.458314752619149279e-02, -4.252530480245884925e-02, 9.733043787604266084e-02, -6.217238566516904152e-02, 3.767656091618994812e-02, 6.674680725588777973e-03, 4.245867422406505304e-02, -2.752200660186601699e-02, -8.318636634138946995e-03, -2.738884420387305285e-02, 1.785195524121836741e-02, -3.151218435289559073e-03, -3.927864338604547816e-04, 3.302976830190196104e-04, 1.387198082848713948e-06, 1.729085429046553641e-07, -1.454003656243721975e-07, -4.056191292896940703e-05, -5.055875832506090064e-06, 4.251531950061960394e-06, 7.087482338961141604e-02, -1.643445525800983908e-01, 2.668682182870234509e-01, 7.752581706917366366e-03, -2.674714571946596939e-02, 4.308263417785011123e-02, -9.385640612496094423e-03, 4.307848167667025635e-02, -6.910099104451945806e-02, -1.822493611414978121e-01, -4.510097387143227610e-02, 5.157836206906134952e-02, -1.170389534066011428e-01, -2.858136680923874240e-02, 3.256883555835647648e-02, 1.336331160725280354e-01, 3.257484898923947853e-02, -3.710113093740719653e-02, 3.343993600586595179e-03, 4.168150663620683060e-04, -3.505035785317401481e-04, -4.312491363797464269e-03, -5.375343342977005178e-04, 4.520175083867039156e-04, -5.045304632809267465e-04, -6.288764981405317546e-05, 5.288279643454484632e-05, 2.176577726533836937e-02, -1.041710664445027849e-02, -1.802940684978692962e-02, -3.097121964369356495e-02, 1.077096511204005125e-02, 2.079488766754130843e-02, -1.120464690158002596e-01, 4.736950869652114399e-02, 8.530900293808066359e-02, 3.029112757823893692e-02, 1.058529311156591879e-01, -6.894903720238335088e-02, -5.089618157121258979e-02, -6.973511953466600410e-02, 4.618114280030299196e-02, 1.143309394598741001e-02, 2.319568285212985151e-02, -1.522637168466081138e-02, -1.535733649675188493e-03, -1.914228911776438445e-04, 1.609692493993826663e-04, -2.603290366421702733e-03, -3.244894507721100851e-04, 2.728661290583660171e-04, 6.938458118266074663e-04, 8.648503036932213837e-05, -7.272604826511198082e-05, -2.609239945314979423e-02, 1.142603664459106681e-02, -2.051406106454568487e-02, 5.779549344910496142e-03, -3.860615030463052100e-02, 6.168332781226748551e-02, 2.068839156841529789e-02, -7.643723474881176927e-02, 1.229844977392647865e-01, -3.554667688747349674e-02, -8.262665730398828859e-03, 9.285295046969522723e-03, 1.497274901467501862e-01, 3.666859638982037511e-02, -4.181688913175674732e-02, -3.257377626487627069e-03, -8.171909213273372040e-04, 9.379633299917983094e-04, 5.408910405506226968e-04, 6.741984641424190365e-05, -5.669396175743082354e-05, 4.696290607396237790e-04, 5.853733334998140626e-05, -4.922457577157541143e-05, -5.350269144276139158e-03, -6.668890718077903363e-04, 5.607930831110977251e-04, 3.013271000130106694e-02, -1.241570117891089425e-02, -2.255430712666738058e-02, -1.643158253499693577e-02, 6.876116339617440766e-03, 1.242585434168311936e-02, 2.120265775977717496e-03, -2.988284987993197143e-03, -4.123302560925387432e-03, 3.528008965720315360e-02, -1.132921329184741026e-02, 6.435692645130823564e-03, -2.115291124444698342e-02, -2.971050496327276927e-02, 1.966236467455729359e-02, -2.194244461519655187e-02, -1.469000955331024871e-02, 1.000316933044766328e-02, -2.208576023807404254e-03, -2.752899293131040766e-04, 2.314938041951108548e-04, -5.840262773118632192e-04, -7.279647649213021596e-05, 6.121521886838239123e-05, -1.263538670848133802e-03, -1.574949051482092536e-04, 1.324388975109944740e-04, 8.955566031735841259e-03, -2.660296383100100095e-02, 4.296567375352825652e-02, 2.380373596470350059e-02, -7.784355459714024927e-02, 1.255004729498893912e-01, -1.824501349606120690e-02, 3.948761180940744964e-02, -6.423389834199008663e-02, 1.038606825469970407e-02, 2.616819816765628484e-03, -3.006960935423359793e-03, -1.864007491704058883e-02, -4.504736174636920880e-03, 5.118497771104377897e-03, 1.680266347982039554e-01, 4.105963063126880086e-02, -4.679634408112137711e-02, 3.343993600586595179e-03, 4.168150663620683060e-04, -3.505035785317401481e-04, -4.312491363797464269e-03, -5.375343342977005178e-04, 4.520175083867039156e-04, -5.045304632809267465e-04, -6.288764981405317546e-05, 5.288279643454484632e-05, 2.176577726533836937e-02, -1.041710664445027849e-02, -1.802940684978692962e-02, -3.097121964369356495e-02, 1.077096511204005125e-02, 2.079488766754130843e-02, -1.120464690158002596e-01, 4.736950869652114399e-02, 8.530900293808066359e-02, 3.029112757823893692e-02, 1.058529311156591879e-01, -6.894903720238335088e-02, -5.089618157121258979e-02, -6.973511953466600410e-02, 4.618114280030299196e-02, 1.143309394598741001e-02, 2.319568285212985151e-02, -1.522637168466081138e-02, -1.535733649675188493e-03, -1.914228911776438445e-04, 1.609692493993826663e-04, -2.603290366421702733e-03, -3.244894507721100851e-04, 2.728661290583660171e-04, 6.938458118266074663e-04, 8.648503036932213837e-05, -7.272604826511198082e-05, -2.609239945314979423e-02, 1.142603664459106681e-02, -2.051406106454568487e-02, 5.779549344910496142e-03, -3.860615030463052100e-02, 6.168332781226748551e-02, 2.068839156841529789e-02, -7.643723474881176927e-02, 1.229844977392647865e-01, -3.554667688747349674e-02, -8.262665730398828859e-03, 9.285295046969522723e-03, 1.497274901467501862e-01, 3.666859638982037511e-02, -4.181688913175674732e-02, -3.257377626487627069e-03, -8.171909213273372040e-04, 9.379633299917983094e-04, 1.097257666720985849e-03, 1.367686610077148478e-04, -1.150100103928514269e-04, -3.252401295559594844e-03, -4.053984617694676175e-04, 3.409032519425078027e-04, -1.217154259382106555e-04, -1.517132787898375553e-05, 1.275770753460001047e-05, -1.104423096905816498e-01, 4.615651100464009809e-02, 8.344619780982527601e-02, -1.998235369855275168e-01, 8.508819942125579738e-02, 1.528709647298205909e-01, 8.333302476347614896e-02, -3.488524142655123617e-02, -6.303339769808283255e-02, -7.468341447282240975e-02, -1.443673498458480642e-01, 9.485360739696327426e-02, -2.685004652445167612e-04, -1.702408228533323561e-02, 1.097613894113106531e-02, 9.496752299747332482e-02, 1.714581306702349373e-01, -1.128066531362114239e-01, -2.109671824413435984e-03, -2.629619271223545066e-04, 2.211270750801623281e-04, 1.011694656468142307e-02, 1.261035832424879221e-03, -1.060416495448196581e-03, 2.326027531269699879e-04, 2.899297772687444119e-05, -2.438045854305356789e-05, -9.775618976121780001e-04, 7.897148922927013995e-03, -1.259878571596698138e-02, -5.534571406250721713e-03, 2.552681480358522451e-02, -4.094434810336724379e-02, -1.258721457759937913e-02, 4.161890111720080443e-02, -6.708566706120022705e-02, 3.521744971093632853e-02, 8.557787631933998912e-03, -9.738493960065902622e-03, -8.446926488038911107e-02, -2.017604402799078392e-02, 2.285024948138817888e-02, -9.755577915095828626e-03, -2.364722966186930900e-03, 2.689144780896026744e-03, 8.392348196279006065e-05, 1.046071729847805219e-05, -8.796512273720217211e-06, -2.967282659264359589e-03, -3.698595949224694123e-04, 3.110182957302592738e-04, -1.688223115474902841e-03, -2.104300767164184042e-04, 1.769525645115341121e-04, -1.040849854787611189e-01, 4.406117175034113265e-02, 7.931633477513304331e-02, 3.539829580561168476e-02, -1.443144702217136026e-02, -2.631106338063535569e-02, -4.383990895980735547e-02, 1.895493123709470276e-02, 3.388325869579450478e-02, 1.809448338386955915e-02, 4.269882582195522885e-02, -2.795653019460052346e-02, 4.363124777259473619e-02, 8.597058258914810902e-02, -5.646456449126337207e-02, 4.431189331687027805e-02, 7.186269332716928304e-02, -4.739074421553418626e-02, 7.807665162715203382e-05, 9.731933913865978996e-06, -8.183671700296416994e-06, 2.525821455836478949e-03, 3.148332692827336839e-04, -2.647461582604813284e-04, 5.088778918832323993e-03, 6.342953893162101269e-04, -5.333847591977234877e-04, 1.765533347871811772e-03, -1.422682766506909793e-02, 2.269730547460076936e-02, 2.888222424864686153e-04, -4.083171371247279469e-03, 6.494062010930001794e-03, 1.594130471018519873e-02, -4.922350239779287734e-02, 7.944117864515577720e-02, -5.516443865142822006e-02, -1.340804559261108905e-02, 1.525892700429632917e-02, 7.450140187529649682e-02, 1.809617933997387934e-02, -2.059052256811338619e-02, -3.118940445306414219e-02, -7.412336287839308216e-03, 8.382871287998559101e-03, 5.408910405506207452e-04, 6.741984641424155129e-05, -5.669396175743063380e-05, 4.696290607396231285e-04, 5.853733334998132494e-05, -4.922457577157534367e-05, -5.350269144276134821e-03, -6.668890718077897942e-04, 5.607930831110975083e-04, 3.013271000130106694e-02, -1.241570117891090119e-02, -2.255430712666738752e-02, -1.643158253499694271e-02, 6.876116339617444236e-03, 1.242585434168312457e-02, 2.120265775977718363e-03, -2.988284987993198010e-03, -4.123302560925387432e-03, 3.528008965720314666e-02, -1.132921329184741026e-02, 6.435692645130823564e-03, -2.115291124444698342e-02, -2.971050496327276927e-02, 1.966236467455729012e-02, -2.194244461519655881e-02, -1.469000955331024871e-02, 1.000316933044766501e-02, -2.208576023807403820e-03, -2.752899293131040766e-04, 2.314938041951108548e-04, -5.840262773118632192e-04, -7.279647649213021596e-05, 6.121521886838239123e-05, -1.263538670848133802e-03, -1.574949051482092536e-04, 1.324388975109944740e-04, 8.955566031735841259e-03, -2.660296383100100095e-02, 4.296567375352825652e-02, 2.380373596470350059e-02, -7.784355459714024927e-02, 1.255004729498893912e-01, -1.824501349606121037e-02, 3.948761180940744964e-02, -6.423389834199008663e-02, 1.038606825469969019e-02, 2.616819816765625015e-03, -3.006960935423356324e-03, -1.864007491704059577e-02, -4.504736174636922615e-03, 5.118497771104379632e-03, 1.680266347982039554e-01, 4.105963063126880086e-02, -4.679634408112137711e-02, 8.392348196278930170e-05, 1.046071729847797087e-05, -8.796512273720142672e-06, -2.967282659264356987e-03, -3.698595949224691413e-04, 3.110182957302590027e-04, -1.688223115474903708e-03, -2.104300767164184855e-04, 1.769525645115341934e-04, -1.040849854787611189e-01, 4.406117175034113265e-02, 7.931633477513304331e-02, 3.539829580561167782e-02, -1.443144702217136026e-02, -2.631106338063535569e-02, -4.383990895980735547e-02, 1.895493123709470276e-02, 3.388325869579450478e-02, 1.809448338386955221e-02, 4.269882582195521498e-02, -2.795653019460051653e-02, 4.363124777259472925e-02, 8.597058258914809514e-02, -5.646456449126335819e-02, 4.431189331687027111e-02, 7.186269332716926916e-02, -4.739074421553417932e-02, 7.807665162715246750e-05, 9.731933913866019654e-06, -8.183671700296457651e-06, 2.525821455836478515e-03, 3.148332692827336297e-04, -2.647461582604812742e-04, 5.088778918832324860e-03, 6.342953893162102353e-04, -5.333847591977235961e-04, 1.765533347871809603e-03, -1.422682766506909793e-02, 2.269730547460076589e-02, 2.888222424864694826e-04, -4.083171371247282938e-03, 6.494062010930008733e-03, 1.594130471018519873e-02, -4.922350239779287040e-02, 7.944117864515577720e-02, -5.516443865142821312e-02, -1.340804559261108558e-02, 1.525892700429632570e-02, 7.450140187529649682e-02, 1.809617933997387934e-02, -2.059052256811338966e-02, -3.118940445306412831e-02, -7.412336287839304746e-03, 8.382871287998553897e-03, -9.575909105642434974e-04, -1.193597735547498307e-04, 1.003707186710399045e-04, -9.520061199010912585e-05, -1.186636523389461756e-05, 9.978534401229592523e-06, -5.876800709203859434e-03, -7.325190685693192200e-04, 6.159819440242017292e-04, -1.659431774532551043e-02, 6.520628417529478540e-03, 1.204087494393247214e-02, 6.518824051016284399e-03, -2.745500204548994606e-03, -4.950724849051978994e-03, -5.340810191179472081e-03, 3.101366677982481286e-03, 5.077959020099345744e-03, 7.727976016970144156e-03, 7.022558645366243878e-03, -4.714356496325102820e-03, 7.018017321145150929e-03, 1.341962078953426278e-02, -8.818944869050635710e-03, -2.755773236988961865e-03, 1.079245666846929096e-02, -6.886663303228377636e-03, 9.801230913130992879e-04, 1.221683173308112048e-04, -1.027324486645460452e-04, 1.233918620327190629e-04, 1.538028875195364422e-05, -1.293342463232469071e-05, 4.892751025155074075e-03, 6.098613175830685205e-04, -5.128379261493998297e-04, -7.792305682365031905e-03, 2.541307371885552502e-02, -4.097328323558844382e-02, 2.530143617608526449e-02, -8.265149730513186854e-02, 1.332544508945474881e-01, -1.184335640259520997e-02, 3.220055758982264676e-02, -5.209911236104310117e-02, 8.090761694886683397e-02, 1.959431243541279177e-02, -2.227702786419644143e-02, 1.968691296265078980e-02, 4.764576998712748319e-03, -5.415896903683155988e-03, 1.534638141861073557e-01, 3.728680895816388619e-02, -4.242975875503233324e-02 + }; + std::vector expected_gt; + std::vector expected_gv; + int natoms = 6; + int nsel = 2; + int odim; + deepmd::hpp::DeepTensor dp; + + void SetUp() override { + std::string file_name = "../../tests/infer/deeppolar_new.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deeppolar_new.pbtxt", "deeppolar_new.pb"); + dp.init("deeppolar_new.pb"); + odim = dp.output_dim (); + + expected_gt.resize(odim); + for(int ii = 0; ii < nsel; ++ii){ + for(int dd = 0; dd < odim; ++dd){ + expected_gt[dd] += expected_t[ii*odim+dd]; + } + } + + expected_gv.resize(odim * 9); + for (int kk = 0; kk < odim; ++kk){ + for(int ii = 0; ii < natoms; ++ii){ + for(int dd = 0; dd < 9; ++dd){ + expected_gv[kk*9 + dd] += expected_v[kk*natoms*9 + ii*9 + dd]; + } + } + } + }; + + void TearDown() override { + remove( "deeppolar_new.pb" ) ; + }; +}; + +TYPED_TEST_SUITE(TestInferDeepPolarNew, ValueTypes); + +TYPED_TEST(TestInferDeepPolarNew, cpu_build_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_t = this->expected_t; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + std::vector& expected_gt = this->expected_gt; + std::vector& expected_gv = this->expected_gv; + int& natoms = this->natoms; + int& nsel = this->nsel; + int& odim = this->odim; + deepmd::hpp::DeepTensor& dp = this->dp; + EXPECT_EQ(dp.cutoff(), 6.); + EXPECT_EQ(dp.numb_types(), 2); + EXPECT_EQ(dp.output_dim(), 9); + std::vector sel_types = dp.sel_types(); + EXPECT_EQ(sel_types.size(), 1); + EXPECT_EQ(sel_types[0], 0); + + std::vector gt, ff, vv, at, av; + + dp.compute(at, coord, atype, box); + EXPECT_EQ(at.size(), expected_t.size()); + for(int ii = 0; ii < expected_t.size(); ++ii){ + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); + } + + dp.compute(gt, ff, vv, coord, atype, box); + EXPECT_EQ(gt.size(), expected_gt.size()); + for(int ii = 0; ii < expected_gt.size(); ++ii){ + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); + } + EXPECT_EQ(ff.size(), expected_f.size()); + for(int ii = 0; ii < expected_f.size(); ++ii){ + EXPECT_LT(fabs(ff[ii] - expected_f[ii]), EPSILON); + } + EXPECT_EQ(vv.size(), expected_gv.size()); + for(int ii = 0; ii < expected_gv.size(); ++ii){ + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); + } + + dp.compute(gt, ff, vv, at, av, coord, atype, box); + EXPECT_EQ(gt.size(), expected_gt.size()); + for(int ii = 0; ii < expected_gt.size(); ++ii){ + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); + } + EXPECT_EQ(ff.size(), expected_f.size()); + for(int ii = 0; ii < expected_f.size(); ++ii){ + EXPECT_LT(fabs(ff[ii] - expected_f[ii]), EPSILON); + } + EXPECT_EQ(vv.size(), expected_gv.size()); + for(int ii = 0; ii < expected_gv.size(); ++ii){ + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); + } + EXPECT_EQ(at.size(), expected_t.size()); + for(int ii = 0; ii < expected_t.size(); ++ii){ + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); + } + EXPECT_EQ(av.size(), expected_v.size()); + for(int ii = 0; ii < expected_v.size(); ++ii){ + EXPECT_LT(fabs(av[ii] - expected_v[ii]), EPSILON); + } +} + + +TYPED_TEST(TestInferDeepPolarNew, cpu_lmp_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_t = this->expected_t; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + std::vector& expected_gt = this->expected_gt; + std::vector& expected_gv = this->expected_gv; + int& natoms = this->natoms; + int& nsel = this->nsel; + int& odim = this->odim; + deepmd::hpp::DeepTensor& dp = this->dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + std::vector > nlist_data; + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + convert_nlist(inlist, nlist_data); + + std::vector gt, ff, vv, at, av; + + dp.compute(at, coord_cpy, atype_cpy, box, nall-nloc, inlist); + + EXPECT_EQ(at.size(), expected_t.size()); + for(int ii = 0; ii < expected_t.size(); ++ii){ + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); + } + + + dp.compute(gt, ff, vv, coord_cpy, atype_cpy, box, nall-nloc, inlist); + + EXPECT_EQ(gt.size(), expected_gt.size()); + for(int ii = 0; ii < expected_gt.size(); ++ii){ + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); + } + // remove ghost atoms + std::vector rff (odim * nloc * 3); + for(int kk = 0; kk < odim; ++kk){ + _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); + } + EXPECT_EQ(rff.size(), expected_f.size()); + for(int ii = 0; ii < expected_f.size(); ++ii){ + EXPECT_LT(fabs(rff[ii] - expected_f[ii]), EPSILON); + } + // virial + EXPECT_EQ(vv.size(), expected_gv.size()); + for(int ii = 0; ii < expected_gv.size(); ++ii){ + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); + } + + + dp.compute(gt, ff, vv, at, av, coord_cpy, atype_cpy, box, nall-nloc, inlist); + + EXPECT_EQ(gt.size(), expected_gt.size()); + for(int ii = 0; ii < expected_gt.size(); ++ii){ + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); + } + // remove ghost atoms + for(int kk = 0; kk < odim; ++kk){ + _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); + } + EXPECT_EQ(rff.size(), expected_f.size()); + for(int ii = 0; ii < expected_f.size(); ++ii){ + EXPECT_LT(fabs(rff[ii] - expected_f[ii]), EPSILON); + } + // virial + EXPECT_EQ(vv.size(), expected_gv.size()); + for(int ii = 0; ii < expected_gv.size(); ++ii){ + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); + } + // atom tensor + EXPECT_EQ(at.size(), expected_t.size()); + for(int ii = 0; ii < expected_t.size(); ++ii){ + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); + } + // atom virial + std::vector rav (odim * nloc * 9); + for(int kk = 0; kk < odim; ++kk){ + _fold_back(rav.begin() + kk * nloc * 9, av.begin() + kk * nall * 9, mapping, nloc, nall, 9); + } + EXPECT_EQ(rav.size(), expected_v.size()); + for(int ii = 0; ii < expected_v.size(); ++ii){ + EXPECT_LT(fabs(rav[ii] - expected_v[ii]), EPSILON); + } +} + diff --git a/source/api_c/tests/test_deeppot_a.cc b/source/api_c/tests/test_deeppot_a.cc new file mode 100644 index 0000000000..52d252a92f --- /dev/null +++ b/source/api_c/tests/test_deeppot_a.cc @@ -0,0 +1,287 @@ +#include +#include +#include +#include "c_api.h" + +class TestInferDeepPotA : public ::testing::Test +{ +protected: + double coord[18] = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + float coordf[18] = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + int atype[6] = { + 0, 1, 1, 0, 1, 1 + }; + double box[9] = { + 13., 0., 0., 0., 13., 0., 0., 0., 13. + }; + float boxf[9] = { + 13., 0., 0., 0., 13., 0., 0., 0., 13. + }; + std::vector expected_e = { + -9.275780747115504710e+01,-1.863501786584258468e+02,-1.863392472863538103e+02,-9.279281325486221021e+01,-1.863671545232153903e+02,-1.863619822847602165e+02 + }; + std::vector expected_f = { + -3.034045420701179663e-01,8.405844663871177014e-01,7.696947487118485642e-02,7.662001266663505117e-01,-1.880601391333554251e-01,-6.183333871091722944e-01,-5.036172391059643427e-01,-6.529525836149027151e-01,5.432962643022043459e-01,6.382357912332115024e-01,-1.748518296794561167e-01,3.457363524891907125e-01,1.286482986991941552e-03,3.757251165286925043e-01,-5.972588700887541124e-01,-5.987006197104716154e-01,-2.004450304880958100e-01,2.495901655353461868e-01 + }; + std::vector expected_v = { + -2.912234126853306959e-01,-3.800610846612756388e-02,2.776624987489437202e-01,-5.053761003913598976e-02,-3.152373041953385746e-01,1.060894290092162379e-01,2.826389131596073745e-01,1.039129970665329250e-01,-2.584378792325942586e-01,-3.121722367954994914e-01,8.483275876786681990e-02,2.524662342344257682e-01,4.142176771106586414e-02,-3.820285230785245428e-02,-2.727311173065460545e-02,2.668859789777112135e-01,-6.448243569420382404e-02,-2.121731470426218846e-01,-8.624335220278558922e-02,-1.809695356746038597e-01,1.529875294531883312e-01,-1.283658185172031341e-01,-1.992682279795223999e-01,1.409924999632362341e-01,1.398322735274434292e-01,1.804318474574856390e-01,-1.470309318999652726e-01,-2.593983661598450730e-01,-4.236536279233147489e-02,3.386387920184946720e-02,-4.174017537818433543e-02,-1.003500282164128260e-01,1.525690815194478966e-01,3.398976109910181037e-02,1.522253908435125536e-01,-2.349125581341701963e-01,9.515545977581392825e-04,-1.643218849228543846e-02,1.993234765412972564e-02,6.027265332209678569e-04,-9.563256398907417355e-02,1.510815124001868293e-01,-7.738094816888557714e-03,1.502832772532304295e-01,-2.380965783745832010e-01,-2.309456719810296654e-01,-6.666961081213038098e-02,7.955566551234216632e-02,-8.099093777937517447e-02,-3.386641099800401927e-02,4.447884755740908608e-02,1.008593228579038742e-01,4.556718179228393811e-02,-6.078081273849572641e-02 + }; + int natoms; + double expected_tot_e; + std::vectorexpected_tot_v; + + DP_DeepPot* dp; + + void SetUp() override { + const char* file_name = "../../tests/infer/deeppot.pbtxt"; + const char* model_file = "deeppot.pb"; + DP_ConvertPbtxtToPb(file_name, model_file); + + dp = DP_NewDeepPot(model_file); + + natoms = expected_e.size(); + EXPECT_EQ(natoms * 3, expected_f.size()); + EXPECT_EQ(natoms * 9, expected_v.size()); + expected_tot_e = 0.; + expected_tot_v.resize(9); + std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + for(int ii = 0; ii < natoms; ++ii){ + expected_tot_e += expected_e[ii]; + } + for(int ii = 0; ii < natoms; ++ii){ + for(int dd = 0; dd < 9; ++dd){ + expected_tot_v[dd] += expected_v[ii*9+dd]; + } + } + }; + + void TearDown() override { + remove( "deeppot.pb" ) ; + }; +}; + +TEST_F(TestInferDeepPotA, double_infer) +{ + double* ener_ = new double; + double* force_ = new double[natoms * 3]; + double* virial_ = new double[9]; + double* atomic_ener_ = new double[natoms]; + double* atomic_virial_ = new double[natoms * 9]; + + DP_DeepPotCompute (dp, natoms, coord, atype, box, ener_, force_, virial_, atomic_ener_, atomic_virial_); + + double ener = *ener_; + std::vector force(force_, force_ + natoms * 3); + std::vector virial(virial_, virial_ + 9); + std::vector atomic_ener(atomic_ener_, atomic_ener_ + natoms); + std::vector atomic_virial(atomic_virial_, atomic_virial_ + natoms * 9); + + EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + } + for(int ii = 0; ii < natoms; ++ii){ + EXPECT_LT(fabs(atomic_ener[ii] - expected_e[ii]), 1e-10); + } + for(int ii = 0; ii < natoms * 9; ++ii){ + EXPECT_LT(fabs(atomic_virial[ii] - expected_v[ii]), 1e-10); + } +} + +TEST_F(TestInferDeepPotA, float_infer) +{ + double* ener_ = new double; + float* force_ = new float[natoms * 3]; + float* virial_ = new float[9]; + float* atomic_ener_ = new float[natoms]; + float* atomic_virial_ = new float[natoms * 9]; + + DP_DeepPotComputef (dp, natoms, coordf, atype, boxf, ener_, force_, virial_, atomic_ener_, atomic_virial_); + + double ener = *ener_; + std::vector force(force_, force_ + natoms * 3); + std::vector virial(virial_, virial_ + 9); + std::vector atomic_ener(atomic_ener_, atomic_ener_ + natoms); + std::vector atomic_virial(atomic_virial_, atomic_virial_ + natoms * 9); + + EXPECT_LT(fabs(ener - expected_tot_e), 1e-6); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-6); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-6); + } + + for(int ii = 0; ii < natoms; ++ii){ + EXPECT_LT(fabs(atomic_ener[ii] - expected_e[ii]), 1e-5); + } + for(int ii = 0; ii < natoms * 9; ++ii){ + EXPECT_LT(fabs(atomic_virial[ii] - expected_v[ii]), 1e-6); + } +} + + +TEST_F(TestInferDeepPotA, cutoff) +{ + double cutoff = DP_DeepPotGetCutoff (dp); + EXPECT_EQ(cutoff, 6.0); +} + +TEST_F(TestInferDeepPotA, numb_types) +{ + int numb_types = DP_DeepPotGetNumbTypes (dp); + EXPECT_EQ(numb_types, 2); +} + +TEST_F(TestInferDeepPotA, type_map) +{ + const char* type_map = DP_DeepPotGetTypeMap (dp); + char expected_type_map[] = "O H"; + EXPECT_EQ(strcmp(type_map, expected_type_map), 0); +} + + +class TestInferDeepPotANoPBC : public ::testing::Test +{ +protected: + double coord[18] = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + float coordf[18] = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + int atype[6] = { + 0, 1, 1, 0, 1, 1 + }; + std::vector expected_e = { + -9.255934839310273787e+01,-1.863253376736990106e+02,-1.857237299341402945e+02,-9.279308539717486326e+01,-1.863708105823244239e+02,-1.863635196514972563e+02 + }; + std::vector expected_f = { + -2.161037360255332107e+00,9.052994347015581589e-01,1.635379623977007979e+00,2.161037360255332107e+00,-9.052994347015581589e-01,-1.635379623977007979e+00,-1.167128117249453811e-02,1.371975700096064992e-03,-1.575265180249604477e-03,6.226508593971802341e-01,-1.816734122009256991e-01,3.561766019664774907e-01,-1.406075393906316626e-02,3.789140061530929526e-01,-6.018777878642909140e-01,-5.969188242856223736e-01,-1.986125696522633155e-01,2.472764510780630642e-01 + }; + std::vector expected_v = { + -7.042445481792056761e-01,2.950213647777754078e-01,5.329418202437231633e-01,2.950213647777752968e-01,-1.235900311906896754e-01,-2.232594111831812944e-01,5.329418202437232743e-01,-2.232594111831813499e-01,-4.033073234276823849e-01,-8.949230984097404917e-01,3.749002169013777030e-01,6.772391014992630298e-01,3.749002169013777586e-01,-1.570527935667933583e-01,-2.837082722496912512e-01,6.772391014992631408e-01,-2.837082722496912512e-01,-5.125052659994422388e-01,4.858210330291591605e-02,-6.902596153269104431e-03,6.682612642430500391e-03,-5.612247004554610057e-03,9.767795567660207592e-04,-9.773758942738038254e-04,5.638322117219018645e-03,-9.483806049779926932e-04,8.493873281881353637e-04,-2.941738570564985666e-01,-4.482529909499673171e-02,4.091569840186781021e-02,-4.509020615859140463e-02,-1.013919988807244071e-01,1.551440772665269030e-01,4.181857726606644232e-02,1.547200233064863484e-01,-2.398213304685777592e-01,-3.218625798524068354e-02,-1.012438450438508421e-02,1.271639330380921855e-02,3.072814938490859779e-03,-9.556241797915024372e-02,1.512251983492413077e-01,-8.277872384009607454e-03,1.505412040827929787e-01,-2.386150620881526407e-01,-2.312295470054945568e-01,-6.631490213524345034e-02,7.932427266386249398e-02,-8.053754366323923053e-02,-3.294595881137418747e-02,4.342495071150231922e-02,1.004599500126941436e-01,4.450400364869536163e-02,-5.951077548033092968e-02 + }; + int natoms; + double expected_tot_e; + std::vectorexpected_tot_v; + + DP_DeepPot* dp; + + void SetUp() override { + const char* file_name = "../../tests/infer/deeppot.pbtxt"; + const char* model_file = "deeppot.pb"; + DP_ConvertPbtxtToPb(file_name, model_file); + + dp = DP_NewDeepPot(model_file); + + natoms = expected_e.size(); + EXPECT_EQ(natoms * 3, expected_f.size()); + EXPECT_EQ(natoms * 9, expected_v.size()); + expected_tot_e = 0.; + expected_tot_v.resize(9); + std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + for(int ii = 0; ii < natoms; ++ii){ + expected_tot_e += expected_e[ii]; + } + for(int ii = 0; ii < natoms; ++ii){ + for(int dd = 0; dd < 9; ++dd){ + expected_tot_v[dd] += expected_v[ii*9+dd]; + } + } + }; + + void TearDown() override { + remove( "deeppot.pb" ) ; + }; +}; + +TEST_F(TestInferDeepPotANoPBC, double_infer) +{ + double* ener_ = new double; + double* force_ = new double[natoms * 3]; + double* virial_ = new double[9]; + double* atomic_ener_ = new double[natoms]; + double* atomic_virial_ = new double[natoms * 9]; + + DP_DeepPotCompute (dp, natoms, coord, atype, nullptr, ener_, force_, virial_, atomic_ener_, atomic_virial_); + + double ener = *ener_; + std::vector force(force_, force_ + natoms * 3); + std::vector virial(virial_, virial_ + 9); + std::vector atomic_ener(atomic_ener_, atomic_ener_ + natoms); + std::vector atomic_virial(atomic_virial_, atomic_virial_ + natoms * 9); + + EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + } + for(int ii = 0; ii < natoms; ++ii){ + EXPECT_LT(fabs(atomic_ener[ii] - expected_e[ii]), 1e-10); + } + for(int ii = 0; ii < natoms * 9; ++ii){ + EXPECT_LT(fabs(atomic_virial[ii] - expected_v[ii]), 1e-10); + } +} + +TEST_F(TestInferDeepPotANoPBC, float_infer) +{ + double* ener_ = new double; + float* force_ = new float[natoms * 3]; + float* virial_ = new float[9]; + float* atomic_ener_ = new float[natoms]; + float* atomic_virial_ = new float[natoms * 9]; + + DP_DeepPotComputef (dp, natoms, coordf, atype, nullptr, ener_, force_, virial_, atomic_ener_, atomic_virial_); + + double ener = *ener_; + std::vector force(force_, force_ + natoms * 3); + std::vector virial(virial_, virial_ + 9); + std::vector atomic_ener(atomic_ener_, atomic_ener_ + natoms); + std::vector atomic_virial(atomic_virial_, atomic_virial_ + natoms * 9); + + EXPECT_LT(fabs(ener - expected_tot_e), 1e-6); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-6); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-6); + } + + for(int ii = 0; ii < natoms; ++ii){ + EXPECT_LT(fabs(atomic_ener[ii] - expected_e[ii]), 1e-5); + } + for(int ii = 0; ii < natoms * 9; ++ii){ + EXPECT_LT(fabs(atomic_virial[ii] - expected_v[ii]), 1e-6); + } +} \ No newline at end of file diff --git a/source/api_c/tests/test_deeppot_a_hpp.cc b/source/api_c/tests/test_deeppot_a_hpp.cc new file mode 100644 index 0000000000..88cae72a8b --- /dev/null +++ b/source/api_c/tests/test_deeppot_a_hpp.cc @@ -0,0 +1,551 @@ +#include +#include +#include +#include +#include +#include "deepmd.hpp" +#include "test_utils.h" + +template +class TestInferDeepPotAHPP : public ::testing::Test +{ +protected: + std::vector coord = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + std::vector atype = { + 0, 1, 1, 0, 1, 1 + }; + std::vector box = { + 13., 0., 0., 0., 13., 0., 0., 0., 13. + }; + std::vector expected_e = { + -9.275780747115504710e+01,-1.863501786584258468e+02,-1.863392472863538103e+02,-9.279281325486221021e+01,-1.863671545232153903e+02,-1.863619822847602165e+02 + }; + std::vector expected_f = { + -3.034045420701179663e-01,8.405844663871177014e-01,7.696947487118485642e-02,7.662001266663505117e-01,-1.880601391333554251e-01,-6.183333871091722944e-01,-5.036172391059643427e-01,-6.529525836149027151e-01,5.432962643022043459e-01,6.382357912332115024e-01,-1.748518296794561167e-01,3.457363524891907125e-01,1.286482986991941552e-03,3.757251165286925043e-01,-5.972588700887541124e-01,-5.987006197104716154e-01,-2.004450304880958100e-01,2.495901655353461868e-01 + }; + std::vector expected_v = { + -2.912234126853306959e-01,-3.800610846612756388e-02,2.776624987489437202e-01,-5.053761003913598976e-02,-3.152373041953385746e-01,1.060894290092162379e-01,2.826389131596073745e-01,1.039129970665329250e-01,-2.584378792325942586e-01,-3.121722367954994914e-01,8.483275876786681990e-02,2.524662342344257682e-01,4.142176771106586414e-02,-3.820285230785245428e-02,-2.727311173065460545e-02,2.668859789777112135e-01,-6.448243569420382404e-02,-2.121731470426218846e-01,-8.624335220278558922e-02,-1.809695356746038597e-01,1.529875294531883312e-01,-1.283658185172031341e-01,-1.992682279795223999e-01,1.409924999632362341e-01,1.398322735274434292e-01,1.804318474574856390e-01,-1.470309318999652726e-01,-2.593983661598450730e-01,-4.236536279233147489e-02,3.386387920184946720e-02,-4.174017537818433543e-02,-1.003500282164128260e-01,1.525690815194478966e-01,3.398976109910181037e-02,1.522253908435125536e-01,-2.349125581341701963e-01,9.515545977581392825e-04,-1.643218849228543846e-02,1.993234765412972564e-02,6.027265332209678569e-04,-9.563256398907417355e-02,1.510815124001868293e-01,-7.738094816888557714e-03,1.502832772532304295e-01,-2.380965783745832010e-01,-2.309456719810296654e-01,-6.666961081213038098e-02,7.955566551234216632e-02,-8.099093777937517447e-02,-3.386641099800401927e-02,4.447884755740908608e-02,1.008593228579038742e-01,4.556718179228393811e-02,-6.078081273849572641e-02 + }; + unsigned int natoms; + double expected_tot_e; + std::vectorexpected_tot_v; + + deepmd::hpp::DeepPot dp; + + void SetUp() override { + std::string file_name = "../../tests/infer/deeppot.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deeppot.pbtxt", "deeppot.pb"); + + dp.init("deeppot.pb"); + + natoms = expected_e.size(); + EXPECT_EQ(natoms * 3, expected_f.size()); + EXPECT_EQ(natoms * 9, expected_v.size()); + expected_tot_e = 0.; + expected_tot_v.resize(9); + std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + for(unsigned int ii = 0; ii < natoms; ++ii){ + expected_tot_e += expected_e[ii]; + } + for(unsigned int ii = 0; ii < natoms; ++ii){ + for(int dd = 0; dd < 9; ++dd){ + expected_tot_v[dd] += expected_v[ii*9+dd]; + } + } + }; + + void TearDown() override { + remove( "deeppot.pb" ) ; + }; +}; + +TYPED_TEST_SUITE(TestInferDeepPotAHPP, ValueTypes); + +TYPED_TEST(TestInferDeepPotAHPP, cpu_build_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + unsigned int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + double ener; + std::vector force, virial; + + dp.compute(ener, force, virial, coord, atype, box); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +TYPED_TEST(TestInferDeepPotAHPP, cpu_build_nlist_numfv) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + unsigned int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + class MyModel : public EnergyModelTest + { + deepmd::hpp::DeepPot & mydp; + const std::vector atype; +public: + MyModel( + deepmd::hpp::DeepPot & dp_, + const std::vector & atype_ + ) : mydp(dp_), atype(atype_) {}; + virtual void compute ( + double & ener, + std::vector & force, + std::vector & virial, + const std::vector & coord, + const std::vector & box) { + mydp.compute(ener, force, virial, coord, atype, box); + } + }; + MyModel model(dp, atype); + model.test_f(coord, box); + model.test_v(coord, box); + std::vector box_(box); + box_[1] -= 0.4; + model.test_f(coord, box_); + model.test_v(coord, box_); + box_[2] += 0.5; + model.test_f(coord, box_); + model.test_v(coord, box_); + box_[4] += 0.2; + model.test_f(coord, box_); + model.test_v(coord, box_); + box_[3] -= 0.3; + model.test_f(coord, box_); + model.test_v(coord, box_); + box_[6] -= 0.7; + model.test_f(coord, box_); + model.test_v(coord, box_); + box_[7] += 0.6; + model.test_f(coord, box_); + model.test_v(coord, box_); +} + + +TYPED_TEST(TestInferDeepPotAHPP, cpu_build_nlist_atomic) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + unsigned int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + double ener; + std::vector force, virial, atom_ener, atom_vir; + dp.compute(ener, force, virial, atom_ener, atom_vir, coord, atype, box); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + EXPECT_EQ(atom_ener.size(), natoms); + EXPECT_EQ(atom_vir.size(), natoms*9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for(int ii = 0; ii < natoms; ++ii){ + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for(int ii = 0; ii < natoms*9; ++ii){ + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } +} + + +TYPED_TEST(TestInferDeepPotAHPP, cpu_lmp_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + unsigned int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + deepmd::hpp::convert_nlist(inlist, nlist_data); + double ener; + std::vector force_, virial; + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + + ener = 0.; + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 1); + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + + +TYPED_TEST(TestInferDeepPotAHPP, cpu_lmp_nlist_atomic) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + unsigned int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + deepmd::hpp::convert_nlist(inlist, nlist_data); + + double ener; + std::vector force_, atom_ener_, atom_vir_, virial; + std::vector force, atom_ener, atom_vir; + dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + EXPECT_EQ(atom_ener.size(), natoms); + EXPECT_EQ(atom_vir.size(), natoms*9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for(int ii = 0; ii < natoms; ++ii){ + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for(int ii = 0; ii < natoms*9; ++ii){ + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } + + ener = 0.; + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + std::fill(atom_ener_.begin(), atom_ener_.end(), 0.0); + std::fill(atom_vir_.begin(), atom_vir_.end(), 0.0); + dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 1); + _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + EXPECT_EQ(atom_ener.size(), natoms); + EXPECT_EQ(atom_vir.size(), natoms*9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + for(int ii = 0; ii < natoms; ++ii){ + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); + } + for(int ii = 0; ii < natoms*9; ++ii){ + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); + } +} + + +TYPED_TEST(TestInferDeepPotAHPP, cpu_lmp_nlist_2rc) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + unsigned int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc*2); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + deepmd::hpp::convert_nlist(inlist, nlist_data); + + double ener; + std::vector force_(nall*3, 0.0), virial(9, 0.0); + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } + + ener = 0.; + std::fill(force_.begin(), force_.end(), 0.0); + std::fill(virial.begin(), virial.end(), 0.0); + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 1); + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + + +TYPED_TEST(TestInferDeepPotAHPP, cpu_lmp_nlist_type_sel) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + unsigned int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + + // add vir atoms + int nvir = 2; + std::vector coord_vir(nvir*3); + std::vector atype_vir(nvir, 2); + for(int ii = 0; ii < nvir; ++ii){ + coord_vir[ii] = coord[ii]; + } + coord.insert(coord.begin(), coord_vir.begin(), coord_vir.end()); + atype.insert(atype.begin(), atype_vir.begin(), atype_vir.end()); + natoms += nvir; + std::vector expected_f_vir(nvir*3, 0.0); + expected_f.insert(expected_f.begin(), expected_f_vir.begin(), expected_f_vir.end()); + + // build nlist + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + deepmd::hpp::convert_nlist(inlist, nlist_data); + + // dp compute + double ener; + std::vector force_(nall*3, 0.0), virial(9, 0.0); + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + // fold back + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + + +template +class TestInferDeepPotANoPbcHPP : public ::testing::Test +{ +protected: + std::vector coord = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + std::vector atype = { + 0, 1, 1, 0, 1, 1 + }; + std::vector box = {}; + std::vector expected_e = { + -9.255934839310273787e+01,-1.863253376736990106e+02,-1.857237299341402945e+02,-9.279308539717486326e+01,-1.863708105823244239e+02,-1.863635196514972563e+02 + }; + std::vector expected_f = { + -2.161037360255332107e+00,9.052994347015581589e-01,1.635379623977007979e+00,2.161037360255332107e+00,-9.052994347015581589e-01,-1.635379623977007979e+00,-1.167128117249453811e-02,1.371975700096064992e-03,-1.575265180249604477e-03,6.226508593971802341e-01,-1.816734122009256991e-01,3.561766019664774907e-01,-1.406075393906316626e-02,3.789140061530929526e-01,-6.018777878642909140e-01,-5.969188242856223736e-01,-1.986125696522633155e-01,2.472764510780630642e-01 + }; + std::vector expected_v = { + -7.042445481792056761e-01,2.950213647777754078e-01,5.329418202437231633e-01,2.950213647777752968e-01,-1.235900311906896754e-01,-2.232594111831812944e-01,5.329418202437232743e-01,-2.232594111831813499e-01,-4.033073234276823849e-01,-8.949230984097404917e-01,3.749002169013777030e-01,6.772391014992630298e-01,3.749002169013777586e-01,-1.570527935667933583e-01,-2.837082722496912512e-01,6.772391014992631408e-01,-2.837082722496912512e-01,-5.125052659994422388e-01,4.858210330291591605e-02,-6.902596153269104431e-03,6.682612642430500391e-03,-5.612247004554610057e-03,9.767795567660207592e-04,-9.773758942738038254e-04,5.638322117219018645e-03,-9.483806049779926932e-04,8.493873281881353637e-04,-2.941738570564985666e-01,-4.482529909499673171e-02,4.091569840186781021e-02,-4.509020615859140463e-02,-1.013919988807244071e-01,1.551440772665269030e-01,4.181857726606644232e-02,1.547200233064863484e-01,-2.398213304685777592e-01,-3.218625798524068354e-02,-1.012438450438508421e-02,1.271639330380921855e-02,3.072814938490859779e-03,-9.556241797915024372e-02,1.512251983492413077e-01,-8.277872384009607454e-03,1.505412040827929787e-01,-2.386150620881526407e-01,-2.312295470054945568e-01,-6.631490213524345034e-02,7.932427266386249398e-02,-8.053754366323923053e-02,-3.294595881137418747e-02,4.342495071150231922e-02,1.004599500126941436e-01,4.450400364869536163e-02,-5.951077548033092968e-02 + }; + unsigned int natoms; + double expected_tot_e; + std::vectorexpected_tot_v; + + deepmd::hpp::DeepPot dp; + + void SetUp() override { + std::string file_name = "../../tests/infer/deeppot.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb(file_name, "deeppot.pb"); + + dp.init("deeppot.pb"); + + natoms = expected_e.size(); + EXPECT_EQ(natoms * 3, expected_f.size()); + EXPECT_EQ(natoms * 9, expected_v.size()); + expected_tot_e = 0.; + expected_tot_v.resize(9); + std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); + for(unsigned int ii = 0; ii < natoms; ++ii){ + expected_tot_e += expected_e[ii]; + } + for(unsigned int ii = 0; ii < natoms; ++ii){ + for(int dd = 0; dd < 9; ++dd){ + expected_tot_v[dd] += expected_v[ii*9+dd]; + } + } + }; + + void TearDown() override { + remove( "deeppot.pb" ) ; + }; +}; + +TYPED_TEST_SUITE(TestInferDeepPotANoPbcHPP, ValueTypes); + +TYPED_TEST(TestInferDeepPotANoPbcHPP, cpu_build_nlist) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + unsigned int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::hpp::DeepPot& dp = this->dp; + double ener; + std::vector force, virial; + dp.compute(ener, force, virial, coord, atype, box); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(unsigned int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(unsigned int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} diff --git a/source/api_c/tests/test_deeppot_model_devi_hpp.cc b/source/api_c/tests/test_deeppot_model_devi_hpp.cc new file mode 100644 index 0000000000..6a8232d838 --- /dev/null +++ b/source/api_c/tests/test_deeppot_model_devi_hpp.cc @@ -0,0 +1,285 @@ +#include +#include +#include +#include +#include +#include "deepmd.hpp" +#include "test_utils.h" + +template +class TestInferDeepPotModeDevi : public ::testing::Test +{ +protected: + std::vector coord = { + 12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56 + }; + std::vector atype = { + 0, 1, 1, 0, 1, 1 + }; + std::vector box = { + 13., 0., 0., 0., 13., 0., 0., 0., 13. + }; + int natoms; + + deepmd::hpp::DeepPot dp0; + deepmd::hpp::DeepPot dp1; + deepmd::hpp::DeepPotModelDevi dp_md; + + void SetUp() override { + { + std::string file_name = "../../tests/infer/deeppot.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deeppot.pbtxt", "deeppot.pb"); + dp0.init("deeppot.pb"); + } + { + std::string file_name = "../../tests/infer/deeppot-1.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deeppot-1.pbtxt", "deeppot-1.pb"); + dp1.init("deeppot-1.pb"); + } + dp_md.init(std::vector({"deeppot.pb", "deeppot-1.pb"})); + }; + + void TearDown() override { + remove( "deeppot.pb" ) ; + remove( "deeppot-1.pb" ) ; + }; +}; + +TYPED_TEST_SUITE(TestInferDeepPotModeDevi, ValueTypes); + +template +class TestInferDeepPotModeDeviPython : public ::testing::Test +{ +protected: + std::vector coord = { + 4.170220047025740423e-02,7.203244934421580703e-02,1.000114374817344942e-01, + 4.053881673400336005e+00,4.191945144032948461e-02,6.852195003967595510e-02, + 1.130233257263184132e+00,1.467558908171130543e-02,1.092338594768797883e-01, + 1.862602113776709242e-02,1.134556072704304919e+00,1.396767474230670159e-01, + 5.120445224973151355e+00,8.781174363909455272e-02,2.738759319792616331e-03, + 4.067046751017840300e+00,1.141730480236712753e+00,5.586898284457517128e-02, + }; + std::vector atype = { + 0, 0, 1, 1, 1, 1 + }; + std::vector box = { + 20., 0., 0., 0., 20., 0., 0., 0., 20. + }; + int natoms; + std::vector expected_md_f = { + 0.509504727653, 0.458424067748, 0.481978258466 + }; // max min avg + std::vector expected_md_v = { + 0.167004837423,0.00041822790564,0.0804864867641 + }; // max min avg + + deepmd::hpp::DeepPot dp0; + deepmd::hpp::DeepPot dp1; + deepmd::hpp::DeepPotModelDevi dp_md; + + void SetUp() override { + { + std::string file_name = "../../tests/infer/deeppot.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deeppot.pbtxt", "deeppot.pb"); + dp0.init("deeppot.pb"); + } + { + std::string file_name = "../../tests/infer/deeppot-1.pbtxt"; + deepmd::hpp::convert_pbtxt_to_pb("../../tests/infer/deeppot-1.pbtxt", "deeppot-1.pb"); + dp1.init("deeppot-1.pb"); + } + dp_md.init(std::vector({"deeppot.pb", "deeppot-1.pb"})); + }; + + void TearDown() override { + remove( "deeppot.pb" ) ; + remove( "deeppot-1.pb" ) ; + }; +}; + +TYPED_TEST_SUITE(TestInferDeepPotModeDeviPython, ValueTypes); + +TYPED_TEST(TestInferDeepPotModeDevi, attrs) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + int& natoms = this->natoms; + deepmd::hpp::DeepPot& dp0 = this->dp0; + deepmd::hpp::DeepPot& dp1 = this->dp1; + deepmd::hpp::DeepPotModelDevi& dp_md = this->dp_md; + EXPECT_EQ(dp0.cutoff(), dp_md.cutoff()); + EXPECT_EQ(dp0.numb_types(), dp_md.numb_types()); + //EXPECT_EQ(dp0.dim_fparam(), dp_md.dim_fparam()); + //EXPECT_EQ(dp0.dim_aparam(), dp_md.dim_aparam()); + EXPECT_EQ(dp1.cutoff(), dp_md.cutoff()); + EXPECT_EQ(dp1.numb_types(), dp_md.numb_types()); + //EXPECT_EQ(dp1.dim_fparam(), dp_md.dim_fparam()); + //EXPECT_EQ(dp1.dim_aparam(), dp_md.dim_aparam()); +} + +TYPED_TEST(TestInferDeepPotModeDevi, cpu_lmp_list) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + int& natoms = this->natoms; + deepmd::hpp::DeepPot& dp0 = this->dp0; + deepmd::hpp::DeepPot& dp1 = this->dp1; + deepmd::hpp::DeepPotModelDevi& dp_md = this->dp_md; + float rc = dp_md.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + deepmd::hpp::convert_nlist(inlist, nlist_data); + + int nmodel = 2; + std::vector edir(nmodel), emd; + std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd; + dp0.compute(edir[0], fdir_[0], vdir[0], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + dp1.compute(edir[1], fdir_[1], vdir[1], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + dp_md.compute(emd, fmd_, vmd, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + for(int kk = 0; kk < nmodel; ++kk){ + _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); + _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); + } + + EXPECT_EQ(edir.size(), emd.size()); + EXPECT_EQ(fdir.size(), fmd.size()); + EXPECT_EQ(vdir.size(), vmd.size()); + for(int kk = 0; kk < nmodel; ++kk){ + EXPECT_EQ(fdir[kk].size(), fmd[kk].size()); + EXPECT_EQ(vdir[kk].size(), vmd[kk].size()); + } + for(int kk = 0; kk < nmodel; ++kk){ + EXPECT_LT(fabs(edir[kk] - emd[kk]), EPSILON); + for(int ii = 0; ii < fdir[0].size(); ++ii){ + EXPECT_LT(fabs(fdir[kk][ii] - fmd[kk][ii]), EPSILON); + } + for(int ii = 0; ii < vdir[0].size(); ++ii){ + EXPECT_LT(fabs(vdir[kk][ii] - vmd[kk][ii]), EPSILON); + } + } +} + + +TYPED_TEST(TestInferDeepPotModeDevi, cpu_lmp_list_atomic) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + int& natoms = this->natoms; + deepmd::hpp::DeepPot& dp0 = this->dp0; + deepmd::hpp::DeepPot& dp1 = this->dp1; + deepmd::hpp::DeepPotModelDevi& dp_md = this->dp_md; + float rc = dp_md.cutoff(); + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::hpp::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + deepmd::hpp::convert_nlist(inlist, nlist_data); + + int nmodel = 2; + std::vector edir(nmodel), emd; + std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd, aedir(nmodel), aemd, avdir(nmodel), avdir_(nmodel), avmd(nmodel), avmd_; + dp0.compute(edir[0], fdir_[0], vdir[0], aedir[0], avdir_[0], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + dp1.compute(edir[1], fdir_[1], vdir[1], aedir[1], avdir_[1], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + dp_md.compute(emd, fmd_, vmd, aemd, avmd_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + for(int kk = 0; kk < nmodel; ++kk){ + _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); + _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); + _fold_back(avdir[kk], avdir_[kk], mapping, nloc, nall, 9); + _fold_back(avmd[kk], avmd_[kk], mapping, nloc, nall, 9); + } + + EXPECT_EQ(edir.size(), emd.size()); + EXPECT_EQ(fdir.size(), fmd.size()); + EXPECT_EQ(vdir.size(), vmd.size()); + EXPECT_EQ(aedir.size(), aemd.size()); + EXPECT_EQ(avdir.size(), avmd.size()); + for(int kk = 0; kk < nmodel; ++kk){ + EXPECT_EQ(fdir[kk].size(), fmd[kk].size()); + EXPECT_EQ(vdir[kk].size(), vmd[kk].size()); + EXPECT_EQ(aedir[kk].size(), aemd[kk].size()); + EXPECT_EQ(avdir[kk].size(), avmd[kk].size()); + } + for(int kk = 0; kk < nmodel; ++kk){ + EXPECT_LT(fabs(edir[kk] - emd[kk]), EPSILON); + for(int ii = 0; ii < fdir[0].size(); ++ii){ + EXPECT_LT(fabs(fdir[kk][ii] - fmd[kk][ii]), EPSILON); + } + for(int ii = 0; ii < vdir[0].size(); ++ii){ + EXPECT_LT(fabs(vdir[kk][ii] - vmd[kk][ii]), EPSILON); + } + for(int ii = 0; ii < aedir[0].size(); ++ii){ + EXPECT_LT(fabs(aedir[kk][ii] - aemd[kk][ii]), EPSILON); + } + for(int ii = 0; ii < avdir[0].size(); ++ii){ + EXPECT_LT(fabs(avdir[kk][ii] - avmd[kk][ii]), EPSILON); + } + } +} + + +template +inline VALUETYPE mymax(const std::vector & xx) +{ + VALUETYPE ret = 0; + for (int ii = 0; ii < xx.size(); ++ii){ + if (xx[ii] > ret) { + ret = xx[ii]; + } + } + return ret; +}; +template +inline VALUETYPE mymin(const std::vector & xx) +{ + VALUETYPE ret = 1e10; + for (int ii = 0; ii < xx.size(); ++ii){ + if (xx[ii] < ret) { + ret = xx[ii]; + } + } + return ret; +}; +template +inline VALUETYPE myavg(const std::vector & xx) +{ + VALUETYPE ret = 0; + for (int ii = 0; ii < xx.size(); ++ii){ + ret += xx[ii]; + } + return (ret / xx.size()); +}; +template +inline VALUETYPE mystd(const std::vector & xx) +{ + VALUETYPE ret = 0; + for (int ii = 0; ii < xx.size(); ++ii){ + ret += xx[ii] * xx[ii]; + } + return sqrt(ret / xx.size()); +}; + diff --git a/source/api_c/tests/test_utils.h b/source/api_c/tests/test_utils.h new file mode 100644 index 0000000000..64d38ea60c --- /dev/null +++ b/source/api_c/tests/test_utils.h @@ -0,0 +1,166 @@ +#pragma once +#include +#include +#include "coord.h" +#include "neighbor_list.h" + +#define EPSILON (std::is_same::value ? 1e-10 : 1e-4) + +typedef testing::Types ValueTypes; + +template +inline void +_fold_back( + typename std::vector::iterator out, + const typename std::vector::const_iterator in, + const std::vector &mapping, + const int nloc, + const int nall, + const int ndim) +{ + // out.resize(nloc*ndim); + std::copy(in, in + nloc*ndim, out); + for(int ii = nloc; ii < nall; ++ii){ + int in_idx = ii; + int out_idx = mapping[in_idx]; + for(int dd = 0; dd < ndim; ++dd){ + *(out + out_idx * ndim + dd) += *(in + in_idx * ndim + dd); + } + } +} + +template +inline void +_fold_back( + std::vector &out, + const std::vector &in, + const std::vector &mapping, + const int nloc, + const int nall, + const int ndim) +{ + out.resize(nloc*ndim); + _fold_back(out.begin(), in.begin(), mapping, nloc, nall, ndim); +} + +template +inline void +_build_nlist( + std::vector> &nlist_data, + std::vector & coord_cpy, + std::vector & atype_cpy, + std::vector & mapping, + const std::vector & coord, + const std::vector & atype, + const std::vector & box, + const float & rc) +{ + // convert VALUETYPE to double, it looks like copy_coord only accepts double + std::vector coord_cpy_; + std::vector coord_(coord.begin(), coord.end()); + std::vector box_(box.begin(), box.end()); + + SimulationRegion region; + region.reinitBox(&box_[0]); + std::vector ncell, ngcell; + copy_coord(coord_cpy_, atype_cpy, mapping, ncell, ngcell, coord_, atype, rc, region); + std::vector nat_stt, ext_stt, ext_end; + nat_stt.resize(3); + ext_stt.resize(3); + ext_end.resize(3); + for (int dd = 0; dd < 3; ++dd){ + ext_stt[dd] = -ngcell[dd]; + ext_end[dd] = ncell[dd] + ngcell[dd]; + } + int nloc = coord_.size() / 3; + int nall = coord_cpy_.size() / 3; + std::vector> nlist_r_cpy; + build_nlist(nlist_data, nlist_r_cpy, coord_cpy_, nloc, rc, rc, nat_stt, ncell, ext_stt, ext_end, region, ncell); + + // convert double to VALUETYPE + coord_cpy.assign(coord_cpy_.begin(), coord_cpy_.end()); +} + +template +class EnergyModelTest +{ + double hh = std::is_same::value ? 1e-5 : 1e-2; + double level = std::is_same::value ? 1e-6 : 1e-2; // expected? +public: + virtual void compute ( + double & ener, + std::vector & force, + std::vector & virial, + const std::vector & coord, + const std::vector & box + ) = 0; + void test_f ( + const std::vector & coord, + const std::vector & box) { + int ndof = coord.size(); + double ener; + std::vector force, virial; + compute(ener, force, virial, coord, box); + for(int ii = 0; ii < ndof; ++ii){ + std::vector coord0(coord), coord1(coord); + double ener0, ener1; + std::vector forcet, virialt; + coord0[ii] += hh; + coord1[ii] -= hh; + compute(ener0, forcet, virialt, coord0, box); + compute(ener1, forcet, virialt, coord1, box); + VALUETYPE num = - (ener0 - ener1) / (2.*hh); + VALUETYPE ana = force[ii]; + EXPECT_LT(fabs(num - ana), level); + } + } + void test_v( + const std::vector & coord, + const std::vector & box) { + std::vector num_diff(9); + double ener; + std::vector force, virial; + compute(ener, force, virial, coord, box); + deepmd::Region region; + init_region_cpu(region, &box[0]); + for(int ii = 0; ii < 9; ++ii){ + std::vector box0(box), box1(box); + box0[ii] += hh; + box1[ii] -= hh; + deepmd::Region region0, region1; + init_region_cpu(region0, &box0[0]); + init_region_cpu(region1, &box1[0]); + std::vector coord0(coord), coord1(coord); + int natoms = coord.size() / 3; + for(int ii = 0; ii < natoms; ++ii){ + VALUETYPE pi[3]; + convert_to_inter_cpu(pi, region, &coord[ii*3]); + convert_to_phys_cpu(&coord0[ii*3], region0, pi); + } + for(int ii = 0; ii < natoms; ++ii){ + VALUETYPE pi[3]; + convert_to_inter_cpu(pi, region, &coord[ii*3]); + convert_to_phys_cpu(&coord1[ii*3], region1, pi); + } + double ener0, ener1; + std::vector forcet, virialt; + compute(ener0, forcet, virialt, coord0, box0); + compute(ener1, forcet, virialt, coord1, box1); + num_diff[ii] = - (ener0 - ener1) / (2.*hh); + } + std::vector num_virial(9, 0); + for(int dd0 = 0; dd0 < 3; ++dd0){ + for(int dd1 = 0; dd1 < 3; ++dd1){ + for(int dd = 0; dd < 3; ++dd){ + num_virial[dd0*3+dd1] += num_diff[dd*3+dd0] * box[dd*3+dd1]; + // num_virial[dd0*3+dd1] += num_diff[dd0*3+dd] * box[dd1*3+dd]; + } + } + } + for(int ii = 0; ii < 9; ++ii){ + EXPECT_LT(fabs(num_virial[ii] - virial[ii]), level); + } + } +}; + + diff --git a/source/api_cc/CMakeLists.txt b/source/api_cc/CMakeLists.txt index 6eb70c04b6..1ee043a45b 100644 --- a/source/api_cc/CMakeLists.txt +++ b/source/api_cc/CMakeLists.txt @@ -10,20 +10,24 @@ file(GLOB LIB_SRC src/*.cc src/*.cpp) file(GLOB INC_SRC include/*.h ${CMAKE_CURRENT_BINARY_DIR}/version.h) -function(_add_libapicc_variant variant_name prec_def) -set (libname "${LIB_DEEPMD_CC}${variant_name}") +set (libname "${LIB_DEEPMD_CC}") add_library(${libname} SHARED ${LIB_SRC}) # link: libdeepmd libdeepmd_op libtensorflow_cc libtensorflow_framework -target_link_libraries (${libname} PUBLIC ${LIB_DEEPMD} ${TensorFlow_LIBRARY} ${TensorFlowFramework_LIBRARY}) -target_include_directories(${libname} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) -target_include_directories(${libname} PRIVATE ${TensorFlow_INCLUDE_DIRS}) +target_link_libraries (${libname} PUBLIC ${LIB_DEEPMD}) +target_link_libraries (${libname} PRIVATE TensorFlow::tensorflow_cc TensorFlow::tensorflow_framework) +target_include_directories( + ${libname} PUBLIC + $ + $ + $ + ) +target_precompile_headers(${libname} PUBLIC [["common.h"]]) -# link: libpython3.x.so -if (USE_TF_PYTHON_LIBS) - target_link_libraries (${libname} PUBLIC ${Python_LIBRARIES}) -endif(USE_TF_PYTHON_LIBS) +if(Protobuf_LIBRARY) + target_link_libraries(${libname} PRIVATE ${Protobuf_LIBRARY}) +endif() set_target_properties( ${libname} @@ -31,18 +35,39 @@ set_target_properties( INSTALL_RPATH "$ORIGIN;${TensorFlow_LIBRARY_PATH}" ) target_compile_definitions(${libname} - PUBLIC ${prec_def} PRIVATE TF_PRIVATE ) +if (CMAKE_TESTING_ENABLED) + target_link_libraries(${libname} PRIVATE coverage_config) +endif() +target_compile_features(${libname} PUBLIC cxx_std_11) -install(TARGETS ${libname} DESTINATION lib/) +if(BUILD_PY_IF) + install( + TARGETS ${libname} + DESTINATION deepmd/op/ + ) +else(BUILD_PY_IF) +install( + TARGETS ${libname} + EXPORT ${CMAKE_PROJECT_NAME}Targets + DESTINATION lib/ +) install( FILES ${INC_SRC} DESTINATION include/deepmd ) -endfunction() +# make a link to libdeepmd_cc_low.so for compatibility +INSTALL(CODE "execute_process( \ +COMMAND ${CMAKE_COMMAND} -E create_symlink \ +${CMAKE_SHARED_LIBRARY_PREFIX}${libname}${CMAKE_SHARED_LIBRARY_SUFFIX} \ +${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}${libname}${LOW_PREC_VARIANT}${CMAKE_SHARED_LIBRARY_SUFFIX} \ +)" +) -_add_libapicc_variant("${HIGH_PREC_VARIANT}" "${HIGH_PREC_DEF}") -_add_libapicc_variant("${LOW_PREC_VARIANT}" "${LOW_PREC_DEF}") +if (CMAKE_TESTING_ENABLED) + add_subdirectory(tests) +endif() +endif(BUILD_PY_IF) \ No newline at end of file diff --git a/source/api_cc/include/AtomMap.h b/source/api_cc/include/AtomMap.h index bf9a8c650c..1cc3b6b67e 100644 --- a/source/api_cc/include/AtomMap.h +++ b/source/api_cc/include/AtomMap.h @@ -5,16 +5,17 @@ // using namespace std; namespace deepmd{ -template class AtomMap { public: AtomMap(); AtomMap(const std::vector::const_iterator in_begin, const std::vector::const_iterator in_end); + template void forward (typename std::vector::iterator out, const typename std::vector::const_iterator in, const int stride = 1) const ; + template void backward (typename std::vector::iterator out, const typename std::vector::const_iterator in, const int stride = 1) const ; diff --git a/source/api_cc/include/DataModifier.h b/source/api_cc/include/DataModifier.h index 6637ebb522..9c936939a1 100644 --- a/source/api_cc/include/DataModifier.h +++ b/source/api_cc/include/DataModifier.h @@ -16,6 +16,7 @@ class DipoleChargeModifier const std::string & name_scope = ""); void print_summary(const std::string &pre) const; public: + template void compute (std::vector & dfcorr_, std::vector & dvcorr_, const std::vector & dcoord_, @@ -25,7 +26,7 @@ class DipoleChargeModifier const std::vector & delef_, const int nghost, const InputNlist & lmp_list); - VALUETYPE cutoff () const {assert(inited); return rcut;}; + double cutoff () const {assert(inited); return rcut;}; int numb_types () const {assert(inited); return ntypes;}; std::vector sel_types () const {assert(inited); return sel_type;}; private: @@ -34,18 +35,20 @@ class DipoleChargeModifier int num_intra_nthreads, num_inter_nthreads; tensorflow::GraphDef* graph_def; bool inited; - VALUETYPE rcut; - VALUETYPE cell_size; + double rcut; + int dtype; + double cell_size; int ntypes; std::string model_type; std::vector sel_type; template VT get_scalar(const std::string & name) const; template void get_vector(std::vector & vec, const std::string & name) const; + template void run_model (std::vector & dforce, std::vector & dvirial, tensorflow::Session * session, const std::vector> & input_tensors, - const AtomMap & atommap, + const AtomMap & atommap, const int nghost); }; } diff --git a/source/api_cc/include/DeepPot.h b/source/api_cc/include/DeepPot.h index 48d2a3cd7f..9b928c47f1 100644 --- a/source/api_cc/include/DeepPot.h +++ b/source/api_cc/include/DeepPot.h @@ -51,6 +51,7 @@ class DeepPot * natoms x dim_aparam. Then all frames are assumed to be provided with the same aparam. * dim_aparam. Then all frames and atoms are provided with the same aparam. **/ + template void compute (ENERGYTYPE & ener, std::vector & force, std::vector & virial, @@ -78,6 +79,7 @@ class DeepPot * natoms x dim_aparam. Then all frames are assumed to be provided with the same aparam. * dim_aparam. Then all frames and atoms are provided with the same aparam. **/ + template void compute (ENERGYTYPE & ener, std::vector & force, std::vector & virial, @@ -107,6 +109,7 @@ class DeepPot * natoms x dim_aparam. Then all frames are assumed to be provided with the same aparam. * dim_aparam. Then all frames and atoms are provided with the same aparam. **/ + template void compute (ENERGYTYPE & ener, std::vector & force, std::vector & virial, @@ -138,6 +141,7 @@ class DeepPot * natoms x dim_aparam. Then all frames are assumed to be provided with the same aparam. * dim_aparam. Then all frames and atoms are provided with the same aparam. **/ + template void compute (ENERGYTYPE & ener, std::vector & force, std::vector & virial, @@ -155,7 +159,7 @@ class DeepPot * @brief Get the cutoff radius. * @return The cutoff radius. **/ - VALUETYPE cutoff () const {assert(inited); return rcut;}; + double cutoff () const {assert(inited); return rcut;}; /** * @brief Get the number of types. * @return The number of types. @@ -184,16 +188,19 @@ class DeepPot template VT get_scalar(const std::string & name) const; // VALUETYPE get_rcut () const; // int get_ntypes () const; - VALUETYPE rcut; - VALUETYPE cell_size; + double rcut; + int dtype; + double cell_size; std::string model_type; std::string model_version; int ntypes; int dfparam; int daparam; + template void validate_fparam_aparam(const int & nloc, const std::vector &fparam, const std::vector &aparam)const ; + template void compute_inner (ENERGYTYPE & ener, std::vector & force, std::vector & virial, @@ -210,7 +217,7 @@ class DeepPot std::vector sec_a; NeighborListData nlist_data; InputNlist nlist; - AtomMap atommap; + AtomMap atommap; // function used for neighbor list copy std::vector get_sel_a() const; @@ -258,6 +265,7 @@ class DeepPotModelDevi * natoms x dim_aparam. Then all frames are assumed to be provided with the same aparam. * dim_aparam. Then all frames and atoms are provided with the same aparam. **/ + template void compute (std::vector & all_ener, std::vector > & all_force, std::vector > & all_virial, @@ -290,6 +298,7 @@ class DeepPotModelDevi * natoms x dim_aparam. Then all frames are assumed to be provided with the same aparam. * dim_aparam. Then all frames and atoms are provided with the same aparam. **/ + template void compute (std::vector & all_ener, std::vector > & all_force, std::vector > & all_virial, @@ -307,7 +316,7 @@ class DeepPotModelDevi * @brief Get the cutoff radius. * @return The cutoff radius. **/ - VALUETYPE cutoff () const {assert(inited); return rcut;}; + double cutoff () const {assert(inited); return rcut;}; /** * @brief Get the number of types. * @return The number of types. @@ -323,20 +332,12 @@ class DeepPotModelDevi * @return The dimension of the atomic parameter. **/ int dim_aparam () const {assert(inited); return daparam;}; -#ifndef HIGH_PREC - /** - * @brief Compute the average energy. - * @param[out] dener The average energy. - * @param[in] all_energy The energies of all models. - **/ - void compute_avg (ENERGYTYPE & dener, - const std::vector & all_energy); -#endif /** * @brief Compute the average energy. * @param[out] dener The average energy. * @param[in] all_energy The energies of all models. **/ + template void compute_avg (VALUETYPE & dener, const std::vector & all_energy); /** @@ -344,6 +345,7 @@ class DeepPotModelDevi * @param[out] avg The average of vectors. * @param[in] xx The vectors of all models. **/ + template void compute_avg (std::vector & avg, const std::vector > & xx); /** @@ -353,6 +355,7 @@ class DeepPotModelDevi * @param[in] xx The vectors of all models. * @param[in] stride The stride to compute the deviation. **/ + template void compute_std ( std::vector & std, const std::vector & avg, @@ -365,6 +368,7 @@ class DeepPotModelDevi * @param[in] eps The level parameter for computing the deviation. * @param[in] stride The stride to compute the deviation. **/ + template void compute_relative_std ( std::vector & std, const std::vector & avg, @@ -376,6 +380,7 @@ class DeepPotModelDevi * @param[in] avg The average of atomic energies. * @param[in] xx The vectors of all atomic energies. **/ + template void compute_std_e (std::vector & std, const std::vector & avg, const std::vector >& xx); @@ -385,6 +390,7 @@ class DeepPotModelDevi * @param[in] avg The average of forces. * @param[in] xx The vectors of all forces. **/ + template void compute_std_f (std::vector & std, const std::vector & avg, const std::vector >& xx); @@ -394,6 +400,7 @@ class DeepPotModelDevi * @param[in] avg The relative average of forces. * @param[in] eps The level parameter for computing the deviation. **/ + template void compute_relative_std_f (std::vector & std, const std::vector & avg, const VALUETYPE eps); @@ -406,13 +413,15 @@ class DeepPotModelDevi template VT get_scalar(const std::string name) const; // VALUETYPE get_rcut () const; // int get_ntypes () const; - VALUETYPE rcut; - VALUETYPE cell_size; + double rcut; + double cell_size; + int dtype; std::string model_type; std::string model_version; int ntypes; int dfparam; int daparam; + template void validate_fparam_aparam(const int & nloc, const std::vector &fparam, const std::vector &aparam)const ; @@ -420,7 +429,7 @@ class DeepPotModelDevi // copy neighbor list info from host bool init_nbor; std::vector > sec; - deepmd::AtomMap atommap; + deepmd::AtomMap atommap; NeighborListData nlist_data; InputNlist nlist; diff --git a/source/api_cc/include/DeepTensor.h b/source/api_cc/include/DeepTensor.h index 02f579e04a..e21f3d25fb 100644 --- a/source/api_cc/include/DeepTensor.h +++ b/source/api_cc/include/DeepTensor.h @@ -46,6 +46,7 @@ class DeepTensor * @param[in] atype The atom types. The list should contain natoms ints. * @param[in] box The cell of the region. The array should be of size 9. **/ + template void compute (std::vector & value, const std::vector & coord, const std::vector & atype, @@ -59,6 +60,7 @@ class DeepTensor * @param[in] nghost The number of ghost atoms. * @param[in] inlist The input neighbour list. **/ + template void compute (std::vector & value, const std::vector & coord, const std::vector & atype, @@ -74,6 +76,7 @@ class DeepTensor * @param[in] atype The atom types. The list should contain natoms ints. * @param[in] box The cell of the region. The array should be of size 9. **/ + template void compute (std::vector & global_tensor, std::vector & force, std::vector & virial, @@ -91,6 +94,7 @@ class DeepTensor * @param[in] nghost The number of ghost atoms. * @param[in] inlist The input neighbour list. **/ + template void compute (std::vector & global_tensor, std::vector & force, std::vector & virial, @@ -110,6 +114,7 @@ class DeepTensor * @param[in] atype The atom types. The list should contain natoms ints. * @param[in] box The cell of the region. The array should be of size 9. **/ + template void compute (std::vector & global_tensor, std::vector & force, std::vector & virial, @@ -131,6 +136,7 @@ class DeepTensor * @param[in] nghost The number of ghost atoms. * @param[in] inlist The input neighbour list. **/ + template void compute (std::vector & global_tensor, std::vector & force, std::vector & virial, @@ -145,7 +151,7 @@ class DeepTensor * @brief Get the cutoff radius. * @return The cutoff radius. **/ - VALUETYPE cutoff () const {assert(inited); return rcut;}; + double cutoff () const {assert(inited); return rcut;}; /** * @brief Get the number of types. * @return The number of types. @@ -163,8 +169,9 @@ class DeepTensor int num_intra_nthreads, num_inter_nthreads; tensorflow::GraphDef* graph_def; bool inited; - VALUETYPE rcut; - VALUETYPE cell_size; + double rcut; + int dtype; + double cell_size; int ntypes; std::string model_type; std::string model_version; @@ -172,12 +179,14 @@ class DeepTensor std::vector sel_type; template VT get_scalar(const std::string & name) const; template void get_vector (std::vector & vec, const std::string & name) const; + template void run_model (std::vector & d_tensor_, tensorflow::Session * session, const std::vector> & input_tensors, - const AtomMap & atommap, + const AtomMap & atommap, const std::vector & sel_fwd, const int nghost = 0); + template void run_model (std::vector & dglobal_tensor_, std::vector & dforce_, std::vector & dvirial_, @@ -185,19 +194,22 @@ class DeepTensor std::vector & datom_virial_, tensorflow::Session * session, const std::vector> & input_tensors, - const AtomMap & atommap, + const AtomMap & atommap, const std::vector & sel_fwd, const int nghost = 0); + template void compute_inner (std::vector & value, const std::vector & coord, const std::vector & atype, const std::vector & box); + template void compute_inner (std::vector & value, const std::vector & coord, const std::vector & atype, const std::vector & box, const int nghost, const InputNlist& inlist); + template void compute_inner (std::vector & global_tensor, std::vector & force, std::vector & virial, @@ -206,6 +218,7 @@ class DeepTensor const std::vector & coord, const std::vector & atype, const std::vector & box); + template void compute_inner (std::vector & global_tensor, std::vector & force, std::vector & virial, diff --git a/source/api_cc/include/common.h b/source/api_cc/include/common.h index 4d82e5cf8b..dc8a3d8dff 100644 --- a/source/api_cc/include/common.h +++ b/source/api_cc/include/common.h @@ -17,13 +17,7 @@ namespace deepmd{ -#ifdef HIGH_PREC -typedef double VALUETYPE; typedef double ENERGYTYPE; -#else -typedef float VALUETYPE; -typedef double ENERGYTYPE; -#endif struct NeighborListData { @@ -38,7 +32,7 @@ struct NeighborListData public: void copy_from_nlist(const InputNlist & inlist); void shuffle(const std::vector & fwd_map); - void shuffle(const deepmd::AtomMap & map); + void shuffle(const deepmd::AtomMap & map); void shuffle_exclude_empty(const std::vector & fwd_map); void make_inlist(InputNlist & inlist); }; @@ -53,6 +47,7 @@ bool model_compatable( std::string & model_version); +template void select_by_type(std::vector & fwd_map, std::vector & bkw_map, @@ -62,6 +57,7 @@ select_by_type(std::vector & fwd_map, const int & nghost, const std::vector & sel_type_); +template void select_real_atoms(std::vector & fwd_map, std::vector & bkw_map, @@ -140,6 +136,13 @@ std::string name_prefix( const std::string & name_scope); +/** +* @brief Get the value of a tensor. +* @param[in] session TensorFlow session. +* @param[in] name The name of the tensor. +* @param[in] scope The scope of the tensor. +* @return The value of the tensor. +**/ template VT session_get_scalar( @@ -147,6 +150,13 @@ session_get_scalar( const std::string name, const std::string scope = ""); +/** +* @brief Get the vector of a tensor. +* @param[out] o_vec The output vector. +* @param[in] session TensorFlow session. +* @param[in] name The name of the tensor. +* @param[in] scope The scope of the tensor. +**/ template void session_get_vector( @@ -155,18 +165,60 @@ session_get_vector( const std::string name_, const std::string scope = ""); +/** +* @brief Get the type of a tensor. +* @param[in] session TensorFlow session. +* @param[in] name The name of the tensor. +* @param[in] scope The scope of the tensor. +* @return The type of the tensor as int. +**/ +int +session_get_dtype( + tensorflow::Session* session, + const std::string name, + const std::string scope = ""); + +/** +* @brief Get input tensors. +* @param[out] input_tensors Input tensors. +* @param[in] dcoord_ Coordinates of atoms. +* @param[in] ntypes Number of atom types. +* @param[in] datype_ Atom types. +* @param[in] dbox Box matrix. +* @param[in] cell_size Cell size. +* @param[in] fparam_ Frame parameters. +* @param[in] aparam_ Atom parameters. +* @param[in] atommap Atom map. +* @param[in] scope The scope of the tensors. +*/ +template int session_input_tensors (std::vector> & input_tensors, const std::vector & dcoord_, const int & ntypes, const std::vector & datype_, const std::vector & dbox, - const VALUETYPE & cell_size, + const double & cell_size, const std::vector & fparam_, const std::vector & aparam_, - const deepmd::AtomMap&atommap, + const deepmd::AtomMap&atommap, const std::string scope = ""); +/** +* @brief Get input tensors. +* @param[out] input_tensors Input tensors. +* @param[in] dcoord_ Coordinates of atoms. +* @param[in] ntypes Number of atom types. +* @param[in] datype_ Atom types. +* @param[in] dlist Neighbor list. +* @param[in] fparam_ Frame parameters. +* @param[in] aparam_ Atom parameters. +* @param[in] atommap Atom map. +* @param[in] nghost Number of ghost atoms. +* @param[in] ago Update the internal neighbour list if ago is 0. +* @param[in] scope The scope of the tensors. +*/ +template int session_input_tensors (std::vector> & input_tensors, const std::vector & dcoord_, @@ -176,7 +228,7 @@ session_input_tensors (std::vector> & InputNlist & dlist, const std::vector & fparam_, const std::vector & aparam_, - const deepmd::AtomMap&atommap, + const deepmd::AtomMap&atommap, const int nghost, const int ago, const std::string scope = ""); @@ -193,7 +245,7 @@ read_file_to_string(std::string model, std::string & file_content); /** * @brief Convert pbtxt to pb. * @param[in] fn_pb_txt Filename of the pb txt file. -* @param[out] fn_pb Filename of the pb file. +* @param[in] fn_pb Filename of the pb file. **/ void convert_pbtxt_to_pb(std::string fn_pb_txt, std::string fn_pb); diff --git a/source/api_cc/include/version.h.in b/source/api_cc/include/version.h.in index 23c22ae588..fa5e358f0b 100644 --- a/source/api_cc/include/version.h.in +++ b/source/api_cc/include/version.h.in @@ -3,11 +3,6 @@ #include // using namespace std; -#ifdef HIGH_PREC -const std::string global_float_prec="double"; -#else -const std::string global_float_prec="float"; -#endif const std::string global_install_prefix="@CMAKE_INSTALL_PREFIX@"; const std::string global_git_summ="@GIT_SUMM@"; diff --git a/source/api_cc/src/AtomMap.cc b/source/api_cc/src/AtomMap.cc index 8e7e82a1ce..8aeb8bbd23 100644 --- a/source/api_cc/src/AtomMap.cc +++ b/source/api_cc/src/AtomMap.cc @@ -5,12 +5,10 @@ using namespace deepmd; -template -AtomMap:: +AtomMap:: AtomMap() {} -template -AtomMap:: +AtomMap:: AtomMap(const std::vector::const_iterator in_begin, const std::vector::const_iterator in_end) { @@ -33,7 +31,7 @@ AtomMap(const std::vector::const_iterator in_begin, template void -AtomMap:: +AtomMap:: forward (typename std::vector::iterator out, const typename std::vector::const_iterator in, const int stride) const @@ -50,7 +48,7 @@ forward (typename std::vector::iterator out, template void -AtomMap:: +AtomMap:: backward (typename std::vector::iterator out, const typename std::vector::const_iterator in, const int stride) const @@ -65,6 +63,30 @@ backward (typename std::vector::iterator out, } } -template class AtomMap; -template class AtomMap; +template +void +AtomMap:: +forward (typename std::vector::iterator out, + const typename std::vector::const_iterator in, + const int stride) const ; + +template +void +AtomMap:: +forward (typename std::vector::iterator out, + const typename std::vector::const_iterator in, + const int stride) const ; + +template +void +AtomMap:: +backward (typename std::vector::iterator out, + const typename std::vector::const_iterator in, + const int stride) const ; +template +void +AtomMap:: +backward (typename std::vector::iterator out, + const typename std::vector::const_iterator in, + const int stride) const ; diff --git a/source/api_cc/src/DataModifier.cc b/source/api_cc/src/DataModifier.cc index 98fee6d230..06c04e3a79 100644 --- a/source/api_cc/src/DataModifier.cc +++ b/source/api_cc/src/DataModifier.cc @@ -48,7 +48,12 @@ init (const std::string & model, // for (int ii = 0; ii < nnodes; ++ii){ // cout << ii << " \t " << graph_def.node(ii).name() << endl; // } - rcut = get_scalar("descrpt_attr/rcut"); + dtype = session_get_dtype(session, "descrpt_attr/rcut"); + if (dtype == tensorflow::DT_DOUBLE) { + rcut = get_scalar("descrpt_attr/rcut"); + } else { + rcut = get_scalar("descrpt_attr/rcut"); + } cell_size = rcut; ntypes = get_scalar("descrpt_attr/ntypes"); model_type = get_scalar("model_attr/model_type"); @@ -73,13 +78,14 @@ get_vector (std::vector & vec, const std::string & name) const session_get_vector(vec, session, name, name_scope); } +template void DipoleChargeModifier:: run_model (std::vector & dforce, std::vector & dvirial, Session * session, const std::vector> & input_tensors, - const AtomMap & atommap, + const AtomMap & atommap, const int nghost) { unsigned nloc = atommap.get_type().size(); @@ -111,8 +117,8 @@ run_model (std::vector & dforce, assert (output_av.dim_size(0) == nframes), "nframes should match"; assert (output_av.dim_size(1) == natoms * 9), "dof of atom virial should be 9 * natoms"; - auto of = output_f.flat (); - auto ov = output_v.flat (); + auto of = output_f.flat (); + auto ov = output_v.flat (); dforce.resize(nall*3); dvirial.resize(9); @@ -124,8 +130,47 @@ run_model (std::vector & dforce, } } +template +void +DipoleChargeModifier:: +run_model (std::vector & dforce, + std::vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const AtomMap & atommap, + const int nghost); +template +void +DipoleChargeModifier:: +run_model (std::vector & dforce, + std::vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const AtomMap & atommap, + const int nghost); + +template +void +DipoleChargeModifier:: +run_model (std::vector & dforce, + std::vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const AtomMap & atommap, + const int nghost); + +template +void +DipoleChargeModifier:: +run_model (std::vector & dforce, + std::vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const AtomMap & atommap, + const int nghost); +template void DipoleChargeModifier:: compute (std::vector & dfcorr_, @@ -169,7 +214,7 @@ compute (std::vector & dfcorr_, nlist_data.copy_from_nlist(lmp_list); nlist_data.shuffle_exclude_empty(real_fwd_map); // sort atoms - AtomMap atommap (datype_real.begin(), datype_real.begin() + nloc_real); + AtomMap atommap (datype_real.begin(), datype_real.begin() + nloc_real); assert (nloc_real == atommap.get_type().size()); const std::vector & sort_fwd_map(atommap.get_fwd_map()); const std::vector & sort_bkw_map(atommap.get_bkw_map()); @@ -179,7 +224,12 @@ compute (std::vector & dfcorr_, nlist_data.make_inlist(nlist); // make input tensors std::vector> input_tensors; - int ret = session_input_tensors (input_tensors, dcoord_real, ntypes, datype_real, dbox, nlist, std::vector(), std::vector(), atommap, nghost_real, 0, name_scope); + int ret; + if (dtype == tensorflow::DT_DOUBLE) { + ret = session_input_tensors (input_tensors, dcoord_real, ntypes, datype_real, dbox, nlist, std::vector(), std::vector(), atommap, nghost_real, 0, name_scope); + } else { + ret = session_input_tensors (input_tensors, dcoord_real, ntypes, datype_real, dbox, nlist, std::vector(), std::vector(), atommap, nghost_real, 0, name_scope); + } assert (nloc_real == ret); // make bond idx map std::vector bd_idx(nall, -1); @@ -207,26 +257,35 @@ compute (std::vector & dfcorr_, TensorShape extf_shape ; extf_shape.AddDim (nframes); extf_shape.AddDim (dextf.size()); -#ifdef HIGH_PREC - Tensor extf_tensor (DT_DOUBLE, extf_shape); -#else - Tensor extf_tensor (DT_FLOAT, extf_shape); -#endif - auto extf = extf_tensor.matrix (); - for (int ii = 0; ii < nframes; ++ii){ - for (int jj = 0; jj < extf.size(); ++jj){ - extf(ii,jj) = dextf[jj]; + Tensor extf_tensor ((tensorflow::DataType) dtype, extf_shape); + if (dtype == tensorflow::DT_DOUBLE) { + auto extf = extf_tensor.matrix (); + for (int ii = 0; ii < nframes; ++ii){ + for (int jj = 0; jj < extf.size(); ++jj){ + extf(ii,jj) = dextf[jj]; + } + } + } else { + auto extf = extf_tensor.matrix (); + for (int ii = 0; ii < nframes; ++ii){ + for (int jj = 0; jj < extf.size(); ++jj){ + extf(ii,jj) = dextf[jj]; + } } } // append extf to input tensor input_tensors.push_back({"t_ef", extf_tensor}); // run model std::vector dfcorr, dvcorr; - run_model (dfcorr, dvcorr, session, input_tensors, atommap, nghost_real); + if (dtype == tensorflow::DT_DOUBLE) { + run_model (dfcorr, dvcorr, session, input_tensors, atommap, nghost_real); + } else { + run_model (dfcorr, dvcorr, session, input_tensors, atommap, nghost_real); + } assert(dfcorr.size() == nall_real * 3); // back map force std::vector dfcorr_1 = dfcorr; - atommap.backward (dfcorr_1.begin(), dfcorr.begin(), 3); + atommap.backward (dfcorr_1.begin(), dfcorr.begin(), 3); assert(dfcorr_1.size() == nall_real * 3); // resize to all and clear std::vector dfcorr_2(nall*3); @@ -258,3 +317,29 @@ compute (std::vector & dfcorr_, } dvcorr_ = dvcorr; } + +template +void +DipoleChargeModifier:: +compute (std::vector & dfcorr_, + std::vector & dvcorr_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const std::vector>& pairs, + const std::vector & delef_, + const int nghost, + const InputNlist & lmp_list); + +template +void +DipoleChargeModifier:: +compute (std::vector & dfcorr_, + std::vector & dvcorr_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const std::vector>& pairs, + const std::vector & delef_, + const int nghost, + const InputNlist & lmp_list); diff --git a/source/api_cc/src/DeepPot.cc b/source/api_cc/src/DeepPot.cc index 0dda00cb27..08c425badd 100644 --- a/source/api_cc/src/DeepPot.cc +++ b/source/api_cc/src/DeepPot.cc @@ -18,13 +18,14 @@ std::vector cum_sum (const std::vector & n_sel) { } +template static void run_model (ENERGYTYPE & dener, std::vector & dforce_, std::vector & dvirial, Session * session, const std::vector> & input_tensors, - const AtomMap& atommap, + const AtomMap& atommap, const int nghost = 0) { unsigned nloc = atommap.get_type().size(); @@ -52,8 +53,8 @@ run_model (ENERGYTYPE & dener, Tensor output_av = output_tensors[3]; auto oe = output_e.flat (); - auto of = output_f.flat (); - auto oav = output_av.flat (); + auto of = output_f.flat (); + auto oav = output_av.flat (); dener = oe(0); std::vector dforce (3 * nall); @@ -75,9 +76,50 @@ run_model (ENERGYTYPE & dener, dvirial[8] += (VALUETYPE)1.0 * oav(9*ii+8); } dforce_ = dforce; - atommap.backward (dforce_.begin(), dforce.begin(), 3); + atommap.backward (dforce_.begin(), dforce.begin(), 3); } +template +void +run_model (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const AtomMap& atommap, + const int nghost); + +template +void +run_model (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const AtomMap& atommap, + const int nghost); + +template +void +run_model (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const AtomMap& atommap, + const int nghost); + +template +void +run_model (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + Session * session, + const std::vector> & input_tensors, + const AtomMap& atommap, + const int nghost); + +template static void run_model (ENERGYTYPE & dener, std::vector& dforce_, std::vector& dvirial, @@ -85,7 +127,7 @@ static void run_model (ENERGYTYPE & dener, std::vector& datom_virial_, Session* session, const std::vector> & input_tensors, - const deepmd::AtomMap & atommap, + const deepmd::AtomMap & atommap, const int& nghost = 0) { unsigned nloc = atommap.get_type().size(); @@ -120,9 +162,9 @@ static void run_model (ENERGYTYPE & dener, Tensor output_av = output_tensors[3]; auto oe = output_e.flat (); - auto of = output_f.flat (); - auto oae = output_ae.flat (); - auto oav = output_av.flat (); + auto of = output_f.flat (); + auto oae = output_ae.flat (); + auto oav = output_av.flat (); dener = oe(0); std::vector dforce (3 * nall); @@ -154,11 +196,54 @@ static void run_model (ENERGYTYPE & dener, dforce_ = dforce; datom_energy_ = datom_energy; datom_virial_ = datom_virial; - atommap.backward (dforce_.begin(), dforce.begin(), 3); - atommap.backward (datom_energy_.begin(), datom_energy.begin(), 1); - atommap.backward (datom_virial_.begin(), datom_virial.begin(), 9); + atommap.backward (dforce_.begin(), dforce.begin(), 3); + atommap.backward (datom_energy_.begin(), datom_energy.begin(), 1); + atommap.backward (datom_virial_.begin(), datom_virial.begin(), 9); } +template +void run_model (ENERGYTYPE & dener, + std::vector& dforce_, + std::vector& dvirial, + std::vector& datom_energy_, + std::vector& datom_virial_, + Session* session, + const std::vector> & input_tensors, + const deepmd::AtomMap & atommap, + const int& nghost); + +template +void run_model (ENERGYTYPE & dener, + std::vector& dforce_, + std::vector& dvirial, + std::vector& datom_energy_, + std::vector& datom_virial_, + Session* session, + const std::vector> & input_tensors, + const deepmd::AtomMap & atommap, + const int& nghost); + +template +void run_model (ENERGYTYPE & dener, + std::vector& dforce_, + std::vector& dvirial, + std::vector& datom_energy_, + std::vector& datom_virial_, + Session* session, + const std::vector> & input_tensors, + const deepmd::AtomMap & atommap, + const int& nghost); + +template +void run_model (ENERGYTYPE & dener, + std::vector& dforce_, + std::vector& dvirial, + std::vector& datom_energy_, + std::vector& datom_virial_, + Session* session, + const std::vector> & input_tensors, + const deepmd::AtomMap & atommap, + const int& nghost); DeepPot:: DeepPot () @@ -212,7 +297,12 @@ init (const std::string & model, const int & gpu_rank, const std::string & file_ #endif // GOOGLE_CUDA || TENSORFLOW_USE_ROCM check_status (NewSession(options, &session)); check_status (session->Create(*graph_def)); - rcut = get_scalar("descrpt_attr/rcut"); + dtype = session_get_dtype(session, "descrpt_attr/rcut"); + if (dtype == tensorflow::DT_DOUBLE) { + rcut = get_scalar("descrpt_attr/rcut"); + } else { + rcut = get_scalar("descrpt_attr/rcut"); + } cell_size = rcut; ntypes = get_scalar("descrpt_attr/ntypes"); dfparam = get_scalar("fitting_attr/dfparam"); @@ -247,7 +337,6 @@ print_summary(const std::string &pre) const std::cout << pre << "source commit: " + global_git_hash << std::endl; std::cout << pre << "source commit at: " + global_git_date << std::endl; std::cout << pre << "surpport model ver.:" + global_model_version << std::endl; - std::cout << pre << "build float prec: " + global_float_prec << std::endl; #if defined(GOOGLE_CUDA) std::cout << pre << "build variant: cuda" << std::endl; #elif defined(TENSORFLOW_USE_ROCM) @@ -314,6 +403,7 @@ std::vector DeepPot::get_sel_a () const { return sel_a; } +template void DeepPot:: validate_fparam_aparam(const int & nloc, @@ -328,6 +418,21 @@ validate_fparam_aparam(const int & nloc, } } +template +void +DeepPot:: +validate_fparam_aparam(const int & nloc, + const std::vector &fparam, + const std::vector &aparam)const ; + +template +void +DeepPot:: +validate_fparam_aparam(const int & nloc, + const std::vector &fparam, + const std::vector &aparam)const ; + +template void DeepPot:: compute (ENERGYTYPE & dener, @@ -341,17 +446,48 @@ compute (ENERGYTYPE & dener, { int nall = dcoord_.size() / 3; int nloc = nall; - atommap = deepmd::AtomMap (datype_.begin(), datype_.begin() + nloc); + atommap = deepmd::AtomMap (datype_.begin(), datype_.begin() + nloc); assert (nloc == atommap.get_type().size()); validate_fparam_aparam(nloc, fparam, aparam); std::vector> input_tensors; - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, atommap); - assert (ret == nloc); - run_model (dener, dforce_, dvirial, session, input_tensors, atommap); + if (dtype == tensorflow::DT_DOUBLE) { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, atommap); + assert (ret == nloc); + run_model (dener, dforce_, dvirial, session, input_tensors, atommap); + } else { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, atommap); + assert (ret == nloc); + run_model (dener, dforce_, dvirial, session, input_tensors, atommap); + } } +template +void +DeepPot:: +compute (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const std::vector & fparam, + const std::vector & aparam); + +template +void +DeepPot:: +compute (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const std::vector & fparam, + const std::vector & aparam); + +template void DeepPot:: compute (ENERGYTYPE & dener, @@ -392,6 +528,37 @@ compute (ENERGYTYPE & dener, select_map(dforce_, dforce, bkw_map, 3); } +template +void +DeepPot:: +compute (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list, + const int& ago, + const std::vector & fparam, + const std::vector & aparam_); + +template +void +DeepPot:: +compute (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list, + const int& ago, + const std::vector & fparam, + const std::vector & aparam_); + +template void DeepPot:: compute_inner (ENERGYTYPE & dener, @@ -413,17 +580,37 @@ compute_inner (ENERGYTYPE & dener, // agp == 0 means that the LAMMPS nbor list has been updated if (ago == 0) { - atommap = deepmd::AtomMap (datype_.begin(), datype_.begin() + nloc); + atommap = deepmd::AtomMap (datype_.begin(), datype_.begin() + nloc); assert (nloc == atommap.get_type().size()); nlist_data.shuffle(atommap); nlist_data.make_inlist(nlist); } - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, atommap, nghost, ago); - assert (nloc == ret); - run_model (dener, dforce_, dvirial, session, input_tensors, atommap, nghost); + if (dtype == tensorflow::DT_DOUBLE) { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, atommap, nghost, ago); + assert (nloc == ret); + run_model (dener, dforce_, dvirial, session, input_tensors, atommap, nghost); + } else { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, atommap, nghost, ago); + assert (nloc == ret); + run_model (dener, dforce_, dvirial, session, input_tensors, atommap, nghost); + } } - +template +void +DeepPot:: +compute_inner (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const int& ago, + const std::vector & fparam, + const std::vector & aparam); + +template void DeepPot:: compute (ENERGYTYPE & dener, @@ -437,17 +624,49 @@ compute (ENERGYTYPE & dener, const std::vector & fparam, const std::vector & aparam) { - atommap = deepmd::AtomMap (datype_.begin(), datype_.end()); + atommap = deepmd::AtomMap (datype_.begin(), datype_.end()); validate_fparam_aparam(atommap.get_type().size(), fparam, aparam); std::vector> input_tensors; - int nloc = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, atommap); - run_model (dener, dforce_, dvirial, datom_energy_, datom_virial_, session, input_tensors, atommap); + if (dtype == tensorflow::DT_DOUBLE) { + int nloc = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, atommap); + run_model (dener, dforce_, dvirial, datom_energy_, datom_virial_, session, input_tensors, atommap); + } else { + int nloc = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, fparam, aparam, atommap); + run_model (dener, dforce_, dvirial, datom_energy_, datom_virial_, session, input_tensors, atommap); + } } - - +template +void +DeepPot:: +compute (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + std::vector & datom_energy_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const std::vector & fparam, + const std::vector & aparam); + +template +void +DeepPot:: +compute (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + std::vector & datom_energy_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const std::vector & fparam, + const std::vector & aparam); + +template void DeepPot:: compute (ENERGYTYPE & dener, @@ -478,28 +697,33 @@ compute (ENERGYTYPE & dener, int nloc_real = nall_real - nghost_real; dcoord.resize(nall_real * 3); datype.resize(nall_real); - datom_energy.resize(nall_real); // fwd map select_map(dcoord, dcoord_, fwd_map, 3); select_map(datype, datype_, fwd_map, 1); - select_map(datom_energy, datom_energy_, fwd_map, 1); // aparam if (daparam > 0){ aparam.resize(nloc_real); select_map(aparam, aparam_, fwd_map, daparam); } if (ago == 0) { - atommap = AtomMap (datype.begin(), datype.begin() + nloc_real); + atommap = deepmd::AtomMap (datype.begin(), datype.begin() + nloc_real); assert (nloc_real == atommap.get_type().size()); nlist_data.copy_from_nlist(lmp_list); + nlist_data.shuffle_exclude_empty(fwd_map); nlist_data.shuffle(atommap); nlist_data.make_inlist(nlist); } - int ret = session_input_tensors (input_tensors, dcoord, ntypes, datype, dbox, nlist, fparam, aparam, atommap, nghost_real, ago); - assert (nloc_real == ret); - run_model (dener, dforce, dvirial, datom_energy, datom_virial, session, input_tensors, atommap, nghost_real); + if (dtype == tensorflow::DT_DOUBLE) { + int ret = session_input_tensors (input_tensors, dcoord, ntypes, datype, dbox, nlist, fparam, aparam, atommap, nghost_real, ago); + assert (nloc_real == ret); + run_model (dener, dforce, dvirial, datom_energy, datom_virial, session, input_tensors, atommap, nghost_real); + } else { + int ret = session_input_tensors (input_tensors, dcoord, ntypes, datype, dbox, nlist, fparam, aparam, atommap, nghost_real, ago); + assert (nloc_real == ret); + run_model (dener, dforce, dvirial, datom_energy, datom_virial, session, input_tensors, atommap, nghost_real); + } // bkw map dforce_.resize(fwd_map.size() * 3); @@ -510,6 +734,40 @@ compute (ENERGYTYPE & dener, select_map(datom_virial_, datom_virial, bkw_map, 9); } +template +void +DeepPot:: +compute (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + std::vector & datom_energy_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list, + const int & ago, + const std::vector & fparam, + const std::vector & aparam_); + +template +void +DeepPot:: +compute (ENERGYTYPE & dener, + std::vector & dforce_, + std::vector & dvirial, + std::vector & datom_energy_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list, + const int & ago, + const std::vector & fparam, + const std::vector & aparam_); + void DeepPot:: get_type_map(std::string & type_map){ @@ -587,7 +845,12 @@ init (const std::vector & models, const int & gpu_rank, const std:: check_status (NewSession(options, &(sessions[ii]))); check_status (sessions[ii]->Create(*graph_defs[ii])); } - rcut = get_scalar("descrpt_attr/rcut"); + dtype = session_get_dtype(sessions[0], "descrpt_attr/rcut"); + if (dtype == tensorflow::DT_DOUBLE) { + rcut = get_scalar("descrpt_attr/rcut"); + } else { + rcut = get_scalar("descrpt_attr/rcut"); + } cell_size = rcut; ntypes = get_scalar("descrpt_attr/ntypes"); dfparam = get_scalar("fitting_attr/dfparam"); @@ -660,6 +923,7 @@ get_sel () const } +template void DeepPotModelDevi:: validate_fparam_aparam(const int & nloc, @@ -674,6 +938,20 @@ validate_fparam_aparam(const int & nloc, } } +template +void +DeepPotModelDevi:: +validate_fparam_aparam(const int & nloc, + const std::vector &fparam, + const std::vector &aparam)const ; + +template +void +DeepPotModelDevi:: +validate_fparam_aparam(const int & nloc, + const std::vector &fparam, + const std::vector &aparam)const ; + // void // DeepPotModelDevi:: // compute (ENERGYTYPE & dener, @@ -721,6 +999,7 @@ validate_fparam_aparam(const int & nloc, // // << model_devi[191] << endl; // } +template void DeepPotModelDevi:: compute (std::vector & all_energy, @@ -743,24 +1022,63 @@ compute (std::vector & all_energy, // agp == 0 means that the LAMMPS nbor list has been updated if (ago == 0) { - atommap = AtomMap (datype_.begin(), datype_.begin() + nloc); + atommap = AtomMap (datype_.begin(), datype_.begin() + nloc); assert (nloc == atommap.get_type().size()); nlist_data.copy_from_nlist(lmp_list); nlist_data.shuffle(atommap); nlist_data.make_inlist(nlist); } - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, atommap, nghost, ago); - + int ret; + if (dtype == tensorflow::DT_DOUBLE) { + ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, atommap, nghost, ago); + } else { + ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, atommap, nghost, ago); + } all_energy.resize (numb_models); all_force.resize (numb_models); all_virial.resize (numb_models); assert (nloc == ret); for (unsigned ii = 0; ii < numb_models; ++ii) { - run_model (all_energy[ii], all_force[ii], all_virial[ii], sessions[ii], input_tensors, atommap, nghost); + if (dtype == tensorflow::DT_DOUBLE) { + run_model (all_energy[ii], all_force[ii], all_virial[ii], sessions[ii], input_tensors, atommap, nghost); + } else { + run_model (all_energy[ii], all_force[ii], all_virial[ii], sessions[ii], input_tensors, atommap, nghost); + } } } +template +void +DeepPotModelDevi:: +compute (std::vector & all_energy, + std::vector> & all_force, + std::vector> & all_virial, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list, + const int & ago, + const std::vector & fparam, + const std::vector & aparam); + +template +void +DeepPotModelDevi:: +compute (std::vector & all_energy, + std::vector> & all_force, + std::vector> & all_virial, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list, + const int & ago, + const std::vector & fparam, + const std::vector & aparam); + +template void DeepPotModelDevi:: compute (std::vector & all_energy, @@ -785,14 +1103,19 @@ compute (std::vector & all_energy, // agp == 0 means that the LAMMPS nbor list has been updated if (ago == 0) { - atommap = AtomMap (datype_.begin(), datype_.begin() + nloc); + atommap = AtomMap (datype_.begin(), datype_.begin() + nloc); assert (nloc == atommap.get_type().size()); nlist_data.copy_from_nlist(lmp_list); nlist_data.shuffle(atommap); nlist_data.make_inlist(nlist); } - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, atommap, nghost, ago); + int ret; + if (dtype == tensorflow::DT_DOUBLE) { + ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, atommap, nghost, ago); + } else { + ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, fparam, aparam, atommap, nghost, ago); + } all_energy.resize (numb_models); all_force .resize (numb_models); @@ -801,10 +1124,49 @@ compute (std::vector & all_energy, all_atom_virial.resize (numb_models); assert (nloc == ret); for (unsigned ii = 0; ii < numb_models; ++ii) { - run_model (all_energy[ii], all_force[ii], all_virial[ii], all_atom_energy[ii], all_atom_virial[ii], sessions[ii], input_tensors, atommap, nghost); + if (dtype == tensorflow::DT_DOUBLE) { + run_model (all_energy[ii], all_force[ii], all_virial[ii], all_atom_energy[ii], all_atom_virial[ii], sessions[ii], input_tensors, atommap, nghost); + } else { + run_model (all_energy[ii], all_force[ii], all_virial[ii], all_atom_energy[ii], all_atom_virial[ii], sessions[ii], input_tensors, atommap, nghost); + } } } +template +void +DeepPotModelDevi:: +compute (std::vector & all_energy, + std::vector> & all_force, + std::vector> & all_virial, + std::vector> & all_atom_energy, + std::vector> & all_atom_virial, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list, + const int & ago, + const std::vector & fparam, + const std::vector & aparam); + +template +void +DeepPotModelDevi:: +compute (std::vector & all_energy, + std::vector> & all_force, + std::vector> & all_virial, + std::vector> & all_atom_energy, + std::vector> & all_atom_virial, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list, + const int & ago, + const std::vector & fparam, + const std::vector & aparam); + +template void DeepPotModelDevi:: compute_avg (VALUETYPE & dener, @@ -820,23 +1182,19 @@ compute_avg (VALUETYPE & dener, dener /= (VALUETYPE)(numb_models); } -#ifndef HIGH_PREC +template void DeepPotModelDevi:: -compute_avg (ENERGYTYPE & dener, - const std::vector& all_energy) -{ - assert (all_energy.size() == numb_models); - if (numb_models == 0) return; +compute_avg (double & dener, + const std::vector & all_energy); - dener = 0; - for (unsigned ii = 0; ii < numb_models; ++ii){ - dener += all_energy[ii]; - } - dener /= (ENERGYTYPE)(numb_models); -} -#endif +template +void +DeepPotModelDevi:: +compute_avg (float & dener, + const std::vector & all_energy); +template void DeepPotModelDevi:: compute_avg (std::vector & avg, @@ -859,7 +1217,19 @@ compute_avg (std::vector & avg, } } +template +void +DeepPotModelDevi:: +compute_avg (std::vector & avg, + const std::vector > & xx); + +template +void +DeepPotModelDevi:: +compute_avg (std::vector & avg, + const std::vector > & xx); +template void DeepPotModelDevi:: compute_std ( @@ -894,7 +1264,25 @@ compute_std ( } } +template +void +DeepPotModelDevi:: +compute_std ( + std::vector & std, + const std::vector & avg, + const std::vector >&xx, + const int & stride); +template +void +DeepPotModelDevi:: +compute_std ( + std::vector & std, + const std::vector & avg, + const std::vector >&xx, + const int & stride); + +template void DeepPotModelDevi:: compute_std_e (std::vector & std, @@ -904,6 +1292,23 @@ compute_std_e (std::vector & std, compute_std(std, avg, xx, 1); } +template +void +DeepPotModelDevi:: +compute_std_e ( + std::vector & std, + const std::vector & avg, + const std::vector >&xx); + +template +void +DeepPotModelDevi:: +compute_std_e ( + std::vector & std, + const std::vector & avg, + const std::vector >&xx); + +template void DeepPotModelDevi:: compute_std_f (std::vector & std, @@ -913,6 +1318,23 @@ compute_std_f (std::vector & std, compute_std(std, avg, xx, 3); } +template +void +DeepPotModelDevi:: +compute_std_f ( + std::vector & std, + const std::vector & avg, + const std::vector >&xx); + +template +void +DeepPotModelDevi:: +compute_std_f ( + std::vector & std, + const std::vector & avg, + const std::vector >&xx); + +template void DeepPotModelDevi:: compute_relative_std ( @@ -936,6 +1358,25 @@ compute_relative_std ( } } +template +void +DeepPotModelDevi:: +compute_relative_std ( + std::vector &std, + const std::vector &avg, + const double eps, + const int & stride); + +template +void +DeepPotModelDevi:: +compute_relative_std ( + std::vector &std, + const std::vector &avg, + const float eps, + const int & stride); + +template void DeepPotModelDevi:: compute_relative_std_f (std::vector &std, @@ -945,3 +1386,18 @@ compute_relative_std_f (std::vector &std, compute_relative_std(std, avg, eps, 3); } +template +void +DeepPotModelDevi:: +compute_relative_std_f ( + std::vector &std, + const std::vector &avg, + const double eps); + +template +void +DeepPotModelDevi:: +compute_relative_std_f ( + std::vector &std, + const std::vector &avg, + const float eps); diff --git a/source/api_cc/src/DeepTensor.cc b/source/api_cc/src/DeepTensor.cc index 777dd6dc07..92efda3a67 100644 --- a/source/api_cc/src/DeepTensor.cc +++ b/source/api_cc/src/DeepTensor.cc @@ -43,7 +43,12 @@ init (const std::string & model, deepmd::check_status (NewSession(options, &session)); deepmd::check_status (ReadBinaryProto(Env::Default(), model, graph_def)); deepmd::check_status (session->Create(*graph_def)); - rcut = get_scalar("descrpt_attr/rcut"); + dtype = session_get_dtype(session, "descrpt_attr/rcut"); + if (dtype == tensorflow::DT_DOUBLE) { + rcut = get_scalar("descrpt_attr/rcut"); + } else { + rcut = get_scalar("descrpt_attr/rcut"); + } cell_size = rcut; ntypes = get_scalar("descrpt_attr/ntypes"); odim = get_scalar("model_attr/output_dim"); @@ -69,7 +74,6 @@ print_summary(const std::string &pre) const std::cout << pre << "source commit: " + global_git_hash << std::endl; std::cout << pre << "source commit at: " + global_git_date << std::endl; std::cout << pre << "surpport model ver.:" + global_model_version << std::endl; - std::cout << pre << "build float prec: " + global_float_prec << std::endl; std::cout << pre << "build with tf inc: " + global_tf_include_dir << std::endl; std::cout << pre << "build with tf lib: " + global_tf_lib << std::endl; std::cout << pre << "set tf intra_op_parallelism_threads: " << num_intra_nthreads << std::endl; @@ -92,12 +96,13 @@ get_vector (std::vector & vec, const std::string & name) const session_get_vector(vec, session, name, name_scope); } +template void DeepTensor:: run_model (std::vector & d_tensor_, Session * session, const std::vector> & input_tensors, - const AtomMap &atommap, + const AtomMap &atommap, const std::vector & sel_fwd, const int nghost) { @@ -118,7 +123,7 @@ run_model (std::vector & d_tensor_, Tensor output_t = output_tensors[0]; // Yixiao: newer model may output rank 2 tensor [nframes x (natoms x noutdim)] // assert (output_t.dims() == 1), "dim of output tensor should be 1"; - auto ot = output_t.flat (); + auto ot = output_t.flat (); // this is an Eigen Tensor int o_size = ot.size(); @@ -137,6 +142,44 @@ run_model (std::vector & d_tensor_, select_map(d_tensor_, d_tensor, sel_srt, odim); } +template +void +DeepTensor:: +run_model (std::vector & d_tensor_, + Session * session, + const std::vector> & input_tensors, + const AtomMap &atommap, + const std::vector & sel_fwd, + const int nghost); +template +void +DeepTensor:: +run_model (std::vector & d_tensor_, + Session * session, + const std::vector> & input_tensors, + const AtomMap &atommap, + const std::vector & sel_fwd, + const int nghost); +template +void +DeepTensor:: +run_model (std::vector & d_tensor_, + Session * session, + const std::vector> & input_tensors, + const AtomMap &atommap, + const std::vector & sel_fwd, + const int nghost); +template +void +DeepTensor:: +run_model (std::vector & d_tensor_, + Session * session, + const std::vector> & input_tensors, + const AtomMap &atommap, + const std::vector & sel_fwd, + const int nghost); + +template void DeepTensor:: run_model (std::vector & dglobal_tensor_, @@ -146,7 +189,7 @@ run_model (std::vector & dglobal_tensor_, std::vector & datom_virial_, tensorflow::Session * session, const std::vector> & input_tensors, - const AtomMap & atommap, + const AtomMap & atommap, const std::vector & sel_fwd, const int nghost) { @@ -195,10 +238,10 @@ run_model (std::vector & dglobal_tensor_, assert (output_av.dim_size(1) == odim * nall * 9), "dof of atomic virial should be odim * nall * 9"; auto ogt = output_gt.flat (); - auto of = output_f.flat (); - auto ov = output_v.flat (); - auto oat = output_at.flat (); - auto oav = output_av.flat (); + auto of = output_f.flat (); + auto ov = output_v.flat (); + auto oat = output_at.flat (); + auto oav = output_av.flat (); // global tensor dglobal_tensor_.resize(odim); @@ -213,7 +256,7 @@ run_model (std::vector & dglobal_tensor_, } dforce_ = dforce; for (unsigned dd = 0; dd < odim; ++dd){ - atommap.backward (dforce_.begin() + (dd * nall * 3), dforce.begin() + (dd * nall * 3), 3); + atommap.backward (dforce_.begin() + (dd * nall * 3), dforce.begin() + (dd * nall * 3), 3); } // component-wise virial @@ -240,11 +283,66 @@ run_model (std::vector & dglobal_tensor_, } datom_virial_ = datom_virial; for (unsigned dd = 0; dd < odim; ++dd){ - atommap.backward (datom_virial_.begin() + (dd * nall * 9), datom_virial.begin() + (dd * nall * 9), 9); + atommap.backward (datom_virial_.begin() + (dd * nall * 9), datom_virial.begin() + (dd * nall * 9), 9); } } +template +void +DeepTensor:: +run_model (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + tensorflow::Session * session, + const std::vector> & input_tensors, + const AtomMap & atommap, + const std::vector & sel_fwd, + const int nghost); +template +void +DeepTensor:: +run_model (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + tensorflow::Session * session, + const std::vector> & input_tensors, + const AtomMap & atommap, + const std::vector & sel_fwd, + const int nghost); + +template +void +DeepTensor:: +run_model (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + tensorflow::Session * session, + const std::vector> & input_tensors, + const AtomMap & atommap, + const std::vector & sel_fwd, + const int nghost); + +template +void +DeepTensor:: +run_model (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + tensorflow::Session * session, + const std::vector> & input_tensors, + const AtomMap & atommap, + const std::vector & sel_fwd, + const int nghost); +template void DeepTensor:: compute (std::vector & dtensor_, @@ -266,6 +364,23 @@ compute (std::vector & dtensor_, compute_inner(dtensor_, dcoord, datype, dbox); } +template +void +DeepTensor:: +compute (std::vector & dtensor_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template +void +DeepTensor:: +compute (std::vector & dtensor_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template void DeepTensor:: compute (std::vector & dtensor_, @@ -294,6 +409,27 @@ compute (std::vector & dtensor_, compute_inner(dtensor_, dcoord, datype, dbox, nghost_real, nlist); } +template +void +DeepTensor:: +compute (std::vector & dtensor_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list); + +template +void +DeepTensor:: +compute (std::vector & dtensor_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list); + +template void DeepTensor:: compute (std::vector & dglobal_tensor_, @@ -307,6 +443,27 @@ compute (std::vector & dglobal_tensor_, compute(dglobal_tensor_, dforce_, dvirial_, tmp_at_, tmp_av_, dcoord_, datype_, dbox); } +template +void +DeepTensor:: +compute (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template +void +DeepTensor:: +compute (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template void DeepTensor:: compute (std::vector & dglobal_tensor_, @@ -322,6 +479,31 @@ compute (std::vector & dglobal_tensor_, compute(dglobal_tensor_, dforce_, dvirial_, tmp_at_, tmp_av_, dcoord_, datype_, dbox, nghost, lmp_list); } +template +void +DeepTensor:: +compute (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list); + +template +void +DeepTensor:: +compute (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list); + +template void DeepTensor:: compute (std::vector & dglobal_tensor_, @@ -356,6 +538,31 @@ compute (std::vector & dglobal_tensor_, } } +template +void +DeepTensor:: +compute (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template +void +DeepTensor:: +compute (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template void DeepTensor:: compute (std::vector & dglobal_tensor_, @@ -397,7 +604,36 @@ compute (std::vector & dglobal_tensor_, } } - +template +void +DeepTensor:: +compute (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list); + +template +void +DeepTensor:: +compute (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & lmp_list); + + +template void DeepTensor:: compute_inner (std::vector & dtensor_, @@ -407,7 +643,7 @@ compute_inner (std::vector & dtensor_, { int nall = dcoord_.size() / 3; int nloc = nall; - AtomMap atommap (datype_.begin(), datype_.begin() + nloc); + AtomMap atommap (datype_.begin(), datype_.begin() + nloc); assert (nloc == atommap.get_type().size()); std::vector sel_fwd, sel_bkw; @@ -416,12 +652,35 @@ compute_inner (std::vector & dtensor_, select_by_type(sel_fwd, sel_bkw, nghost_sel, dcoord_, datype_, 0, sel_type); std::vector> input_tensors; - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, std::vector(), std::vector(), atommap, name_scope); - assert (ret == nloc); - run_model (dtensor_, session, input_tensors, atommap, sel_fwd); + if (dtype == tensorflow::DT_DOUBLE) { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, std::vector(), std::vector(), atommap, name_scope); + assert (ret == nloc); + run_model (dtensor_, session, input_tensors, atommap, sel_fwd); + } else { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, std::vector(), std::vector(), atommap, name_scope); + assert (ret == nloc); + run_model (dtensor_, session, input_tensors, atommap, sel_fwd); + } } +template +void +DeepTensor:: +compute_inner (std::vector & dtensor_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template +void +DeepTensor:: +compute_inner (std::vector & dtensor_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template void DeepTensor:: compute_inner (std::vector & dtensor_, @@ -433,7 +692,7 @@ compute_inner (std::vector & dtensor_, { int nall = dcoord_.size() / 3; int nloc = nall - nghost; - AtomMap atommap (datype_.begin(), datype_.begin() + nloc); + AtomMap atommap (datype_.begin(), datype_.begin() + nloc); assert (nloc == atommap.get_type().size()); std::vector sel_fwd, sel_bkw; @@ -449,12 +708,39 @@ compute_inner (std::vector & dtensor_, nlist_data.make_inlist(nlist); std::vector> input_tensors; - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, std::vector(), std::vector(), atommap, nghost, 0, name_scope); - assert (nloc == ret); - run_model (dtensor_, session, input_tensors, atommap, sel_fwd, nghost); + if (dtype == tensorflow::DT_DOUBLE) { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, std::vector(), std::vector(), atommap, nghost, 0, name_scope); + assert (nloc == ret); + run_model (dtensor_, session, input_tensors, atommap, sel_fwd, nghost); + } else { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, std::vector(), std::vector(), atommap, nghost, 0, name_scope); + assert (nloc == ret); + run_model (dtensor_, session, input_tensors, atommap, sel_fwd, nghost); + } } +template +void +DeepTensor:: +compute_inner (std::vector & dtensor_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & nlist_); + +template +void +DeepTensor:: +compute_inner (std::vector & dtensor_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & nlist_); + +template void DeepTensor:: compute_inner (std::vector & dglobal_tensor_, @@ -468,7 +754,7 @@ compute_inner (std::vector & dglobal_tensor_, { int nall = dcoord_.size() / 3; int nloc = nall; - AtomMap atommap (datype_.begin(), datype_.begin() + nloc); + AtomMap atommap (datype_.begin(), datype_.begin() + nloc); assert (nloc == atommap.get_type().size()); std::vector sel_fwd, sel_bkw; @@ -477,12 +763,43 @@ compute_inner (std::vector & dglobal_tensor_, select_by_type(sel_fwd, sel_bkw, nghost_sel, dcoord_, datype_, 0, sel_type); std::vector> input_tensors; - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, std::vector(), std::vector(), atommap, name_scope); - assert (ret == nloc); - run_model (dglobal_tensor_, dforce_, dvirial_, datom_tensor_, datom_virial_, session, input_tensors, atommap, sel_fwd); + if (dtype == tensorflow::DT_DOUBLE) { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, std::vector(), std::vector(), atommap, name_scope); + assert (ret == nloc); + run_model (dglobal_tensor_, dforce_, dvirial_, datom_tensor_, datom_virial_, session, input_tensors, atommap, sel_fwd); + } else { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, cell_size, std::vector(), std::vector(), atommap, name_scope); + assert (ret == nloc); + run_model (dglobal_tensor_, dforce_, dvirial_, datom_tensor_, datom_virial_, session, input_tensors, atommap, sel_fwd); + } } +template +void +DeepTensor:: +compute_inner (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template +void +DeepTensor:: +compute_inner (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox); + +template void DeepTensor:: compute_inner (std::vector & dglobal_tensor_, @@ -498,7 +815,7 @@ compute_inner (std::vector & dglobal_tensor_, { int nall = dcoord_.size() / 3; int nloc = nall - nghost; - AtomMap atommap (datype_.begin(), datype_.begin() + nloc); + AtomMap atommap (datype_.begin(), datype_.begin() + nloc); assert (nloc == atommap.get_type().size()); std::vector sel_fwd, sel_bkw; @@ -514,9 +831,42 @@ compute_inner (std::vector & dglobal_tensor_, nlist_data.make_inlist(nlist); std::vector> input_tensors; - int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, std::vector(), std::vector(), atommap, nghost, 0, name_scope); - assert (nloc == ret); - run_model (dglobal_tensor_, dforce_, dvirial_, datom_tensor_, datom_virial_, session, input_tensors, atommap, sel_fwd, nghost); + if (dtype == tensorflow::DT_DOUBLE) { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, std::vector(), std::vector(), atommap, nghost, 0, name_scope); + assert (nloc == ret); + run_model (dglobal_tensor_, dforce_, dvirial_, datom_tensor_, datom_virial_, session, input_tensors, atommap, sel_fwd, nghost); + } else { + int ret = session_input_tensors (input_tensors, dcoord_, ntypes, datype_, dbox, nlist, std::vector(), std::vector(), atommap, nghost, 0, name_scope); + assert (nloc == ret); + run_model (dglobal_tensor_, dforce_, dvirial_, datom_tensor_, datom_virial_, session, input_tensors, atommap, sel_fwd, nghost); + } } +template +void +DeepTensor:: +compute_inner (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & nlist_); + +template +void +DeepTensor:: +compute_inner (std::vector & dglobal_tensor_, + std::vector & dforce_, + std::vector & dvirial_, + std::vector & datom_tensor_, + std::vector & datom_virial_, + const std::vector & dcoord_, + const std::vector & datype_, + const std::vector & dbox, + const int nghost, + const InputNlist & nlist_); diff --git a/source/api_cc/src/common.cc b/source/api_cc/src/common.cc index 01c2dd5f8d..3ec4f0f7eb 100644 --- a/source/api_cc/src/common.cc +++ b/source/api_cc/src/common.cc @@ -1,8 +1,22 @@ #include "common.h" #include "AtomMap.h" #include "device.h" -#include #include +#if defined(_WIN32) +#if defined(_WIN32_WINNT) +#undef _WIN32_WINNT +#endif + +// target Windows version is windows 7 and later +#define _WIN32_WINNT _WIN32_WINNT_WIN7 +#define PSAPI_VERSION 2 +#include +#include +#define O_RDONLY _O_RDONLY +#else +// not windows +#include +#endif #include "google/protobuf/text_format.h" #include "google/protobuf/io/zero_copy_stream_impl.h" @@ -49,12 +63,13 @@ model_compatable( } } +template void deepmd:: select_by_type(std::vector & fwd_map, std::vector & bkw_map, int & nghost_real, - const std::vector & dcoord_, + const std::vector & dcoord_, const std::vector & datype_, const int & nghost, const std::vector & sel_type_) @@ -90,13 +105,35 @@ select_by_type(std::vector & fwd_map, assert((nloc_real+nghost_real) == bkw_map.size()); } +template +void +deepmd:: +select_by_type (std::vector & fwd_map, + std::vector & bkw_map, + int & nghost_real, + const std::vector & dcoord_, + const std::vector & datype_, + const int & nghost, + const std::vector & sel_type_); +template +void +deepmd:: +select_by_type (std::vector & fwd_map, + std::vector & bkw_map, + int & nghost_real, + const std::vector & dcoord_, + const std::vector & datype_, + const int & nghost, + const std::vector & sel_type_); + +template void deepmd:: select_real_atoms(std::vector & fwd_map, std::vector & bkw_map, int & nghost_real, - const std::vector & dcoord_, + const std::vector & dcoord_, const std::vector & datype_, const int & nghost, const int & ntypes) @@ -108,6 +145,27 @@ select_real_atoms(std::vector & fwd_map, deepmd::select_by_type(fwd_map, bkw_map, nghost_real, dcoord_, datype_, nghost, sel_type); } +template +void +deepmd:: +select_real_atoms (std::vector & fwd_map, + std::vector & bkw_map, + int & nghost_real, + const std::vector & dcoord_, + const std::vector & datype_, + const int & nghost, + const int & ntypes); + +template +void +deepmd:: +select_real_atoms (std::vector & fwd_map, + std::vector & bkw_map, + int & nghost_real, + const std::vector & dcoord_, + const std::vector & datype_, + const int & nghost, + const int & ntypes); void deepmd::NeighborListData:: @@ -124,10 +182,9 @@ copy_from_nlist(const InputNlist & inlist) } } - void deepmd::NeighborListData:: -shuffle(const AtomMap & map) +shuffle(const AtomMap & map) { const std::vector & fwd_map = map.get_fwd_map(); shuffle(fwd_map); @@ -256,8 +313,13 @@ deepmd:: load_op_library() { tensorflow::Env* env = tensorflow::Env::Default(); - std::string dso_path = env->FormatLibraryFileName("deepmd_op", ""); +#if defined(_WIN32) + std::string dso_path = "deepmd_op.dll"; + void* dso_handle = LoadLibrary(dso_path.c_str()); +#else + std::string dso_path = "libdeepmd_op.so"; void* dso_handle = dlopen(dso_path.c_str(), RTLD_NOW | RTLD_LOCAL); +#endif if (!dso_handle) { throw deepmd::deepmd_exception(dso_path + " is not found! You can add the library directory to LD_LIBRARY_PATH"); } @@ -274,18 +336,19 @@ name_prefix(const std::string & scope) return prefix; } +template int deepmd:: session_input_tensors ( std::vector> & input_tensors, - const std::vector & dcoord_, + const std::vector & dcoord_, const int & ntypes, const std::vector & datype_, - const std::vector & dbox, - const deepmd::VALUETYPE & cell_size, - const std::vector & fparam_, - const std::vector & aparam_, - const deepmd::AtomMap& atommap, + const std::vector & dbox, + const double & cell_size, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap& atommap, const std::string scope) { bool b_pbc = (dbox.size() == 9); @@ -327,31 +390,35 @@ session_input_tensors ( aparam_shape.AddDim (nframes); aparam_shape.AddDim (aparam_.size()); -#ifdef HIGH_PREC - Tensor coord_tensor (DT_DOUBLE, coord_shape); - Tensor box_tensor (DT_DOUBLE, box_shape); - Tensor fparam_tensor (DT_DOUBLE, fparam_shape); - Tensor aparam_tensor (DT_DOUBLE, aparam_shape); -#else - Tensor coord_tensor (DT_FLOAT, coord_shape); - Tensor box_tensor (DT_FLOAT, box_shape); - Tensor fparam_tensor (DT_FLOAT, fparam_shape); - Tensor aparam_tensor (DT_FLOAT, aparam_shape); -#endif + tensorflow::DataType model_type; + if(std::is_same::value){ + model_type = tensorflow::DT_DOUBLE; + } + else if(std::is_same::value){ + model_type = tensorflow::DT_FLOAT; + } + else{ + throw deepmd::deepmd_exception("unsupported data type"); + } + Tensor coord_tensor (model_type, coord_shape); + Tensor box_tensor (model_type, box_shape); + Tensor fparam_tensor (model_type, fparam_shape); + Tensor aparam_tensor (model_type, aparam_shape); + Tensor type_tensor (DT_INT32, type_shape); Tensor mesh_tensor (DT_INT32, mesh_shape); Tensor natoms_tensor (DT_INT32, natoms_shape); - auto coord = coord_tensor.matrix (); + auto coord = coord_tensor.matrix (); auto type = type_tensor.matrix (); - auto box = box_tensor.matrix (); + auto box = box_tensor.matrix (); auto mesh = mesh_tensor.flat (); auto natoms = natoms_tensor.flat (); - auto fparam = fparam_tensor.matrix (); - auto aparam = aparam_tensor.matrix (); + auto fparam = fparam_tensor.matrix (); + auto aparam = aparam_tensor.matrix (); - std::vector dcoord (dcoord_); - atommap.forward (dcoord.begin(), dcoord_.begin(), 3); + std::vector dcoord (dcoord_); + atommap.forward (dcoord.begin(), dcoord_.begin(), 3); for (int ii = 0; ii < nframes; ++ii){ for (int jj = 0; jj < nall * 3; ++jj){ @@ -409,18 +476,19 @@ session_input_tensors ( return nloc; } +template int deepmd:: session_input_tensors ( std::vector> & input_tensors, - const std::vector & dcoord_, + const std::vector & dcoord_, const int & ntypes, const std::vector & datype_, - const std::vector & dbox, + const std::vector & dbox, InputNlist & dlist, - const std::vector & fparam_, - const std::vector & aparam_, - const deepmd::AtomMap& atommap, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap& atommap, const int nghost, const int ago, const std::string scope) @@ -459,31 +527,35 @@ session_input_tensors ( aparam_shape.AddDim (nframes); aparam_shape.AddDim (aparam_.size()); -#ifdef HIGH_PREC - Tensor coord_tensor (DT_DOUBLE, coord_shape); - Tensor box_tensor (DT_DOUBLE, box_shape); - Tensor fparam_tensor (DT_DOUBLE, fparam_shape); - Tensor aparam_tensor (DT_DOUBLE, aparam_shape); -#else - Tensor coord_tensor (DT_FLOAT, coord_shape); - Tensor box_tensor (DT_FLOAT, box_shape); - Tensor fparam_tensor (DT_FLOAT, fparam_shape); - Tensor aparam_tensor (DT_FLOAT, aparam_shape); -#endif + tensorflow::DataType model_type; + if(std::is_same::value){ + model_type = tensorflow::DT_DOUBLE; + } + else if(std::is_same::value){ + model_type = tensorflow::DT_FLOAT; + } + else{ + throw deepmd::deepmd_exception("unsupported data type"); + } + Tensor coord_tensor (model_type, coord_shape); + Tensor box_tensor (model_type, box_shape); + Tensor fparam_tensor (model_type, fparam_shape); + Tensor aparam_tensor (model_type, aparam_shape); + Tensor type_tensor (DT_INT32, type_shape); Tensor mesh_tensor (DT_INT32, mesh_shape); Tensor natoms_tensor (DT_INT32, natoms_shape); - auto coord = coord_tensor.matrix (); + auto coord = coord_tensor.matrix (); auto type = type_tensor.matrix (); - auto box = box_tensor.matrix (); + auto box = box_tensor.matrix (); auto mesh = mesh_tensor.flat (); auto natoms = natoms_tensor.flat (); - auto fparam = fparam_tensor.matrix (); - auto aparam = aparam_tensor.matrix (); + auto fparam = fparam_tensor.matrix (); + auto aparam = aparam_tensor.matrix (); - std::vector dcoord (dcoord_); - atommap.forward (dcoord.begin(), dcoord_.begin(), 3); + std::vector dcoord (dcoord_); + atommap.forward (dcoord.begin(), dcoord_.begin(), 3); for (int ii = 0; ii < nframes; ++ii){ for (int jj = 0; jj < nall * 3; ++jj){ @@ -584,6 +656,25 @@ session_get_vector(std::vector & o_vec, Session* session, const std::string } +int +deepmd:: +session_get_dtype(tensorflow::Session* session, const std::string name_, const std::string scope) +{ + std::string name = name_; + if (scope != "") { + name = scope + "/" + name; + } + std::vector output_tensors; + deepmd::check_status (session->Run(std::vector> ({}), + {name.c_str()}, + {}, + &output_tensors)); + Tensor output_rc = output_tensors[0]; + // cast enum to int + return (int)output_rc.dtype(); +} + + template void deepmd:: @@ -880,3 +971,119 @@ convert_pbtxt_to_pb(std::string fn_pb_txt, std::string fn_pb) std::fstream output(fn_pb, std::ios::out | std::ios::trunc | std::ios::binary); graph_def.SerializeToOstream(&output); } + +template +int +deepmd:: +session_input_tensors (std::vector> & input_tensors, + const std::vector & dcoord_, + const int & ntypes, + const std::vector & datype_, + const std::vector & dbox, + const double & cell_size, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap&atommap, + const std::string scope); +template +int +deepmd:: +session_input_tensors (std::vector> & input_tensors, + const std::vector & dcoord_, + const int & ntypes, + const std::vector & datype_, + const std::vector & dbox, + const double & cell_size, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap&atommap, + const std::string scope); + +template +int +deepmd:: +session_input_tensors (std::vector> & input_tensors, + const std::vector & dcoord_, + const int & ntypes, + const std::vector & datype_, + const std::vector & dbox, + const double & cell_size, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap&atommap, + const std::string scope); +template +int +deepmd:: +session_input_tensors (std::vector> & input_tensors, + const std::vector & dcoord_, + const int & ntypes, + const std::vector & datype_, + const std::vector & dbox, + const double & cell_size, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap&atommap, + const std::string scope); + +template +int +deepmd:: +session_input_tensors (std::vector> & input_tensors, + const std::vector & dcoord_, + const int & ntypes, + const std::vector & datype_, + const std::vector & dbox, + InputNlist & dlist, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap&atommap, + const int nghost, + const int ago, + const std::string scope); +template +int +deepmd:: +session_input_tensors (std::vector> & input_tensors, + const std::vector & dcoord_, + const int & ntypes, + const std::vector & datype_, + const std::vector & dbox, + InputNlist & dlist, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap&atommap, + const int nghost, + const int ago, + const std::string scope); + +template +int +deepmd:: +session_input_tensors (std::vector> & input_tensors, + const std::vector & dcoord_, + const int & ntypes, + const std::vector & datype_, + const std::vector & dbox, + InputNlist & dlist, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap&atommap, + const int nghost, + const int ago, + const std::string scope); +template +int +deepmd:: +session_input_tensors (std::vector> & input_tensors, + const std::vector & dcoord_, + const int & ntypes, + const std::vector & datype_, + const std::vector & dbox, + InputNlist & dlist, + const std::vector & fparam_, + const std::vector & aparam_, + const deepmd::AtomMap&atommap, + const int nghost, + const int ago, + const std::string scope); diff --git a/source/api_cc/tests/CMakeLists.txt b/source/api_cc/tests/CMakeLists.txt index 076bfe6995..e8e8e585a2 100644 --- a/source/api_cc/tests/CMakeLists.txt +++ b/source/api_cc/tests/CMakeLists.txt @@ -1,165 +1,19 @@ cmake_minimum_required(VERSION 3.9) project(deepmd_api_test) -if (NOT DEFINED BUILD_CPP_IF) - set(BUILD_CPP_IF TRUE) -endif (NOT DEFINED BUILD_CPP_IF) -add_definitions ("-DHIGH_PREC") - -enable_testing() - -find_package(OpenMP) -if (OPENMP_FOUND) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") -endif() - -set(DEEPMD_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../../..) -list (APPEND CMAKE_MODULE_PATH ${DEEPMD_SOURCE_DIR}/source/cmake/) - -# setup tensorflow libraries by python -if (USE_TF_PYTHON_LIBS) - set(DEEPMD_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../../..) - find_package (Python COMPONENTS Interpreter Development REQUIRED) - # find tensorflow, I need tf abi info - find_package(tensorflow REQUIRED) - # auto op_cxx_abi - try_run( - CPP_CXX_ABI_RUN_RESULT_VAR CPP_CXX_ABI_COMPILE_RESULT_VAR - ${CMAKE_CURRENT_BINARY_DIR}/tf_cxx_abi - "${DEEPMD_SOURCE_DIR}/source/cmake/tf_cxx_abi.cpp" - LINK_LIBRARIES ${TensorFlowFramework_LIBRARY} - CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${TensorFlow_INCLUDE_DIRS}" - RUN_OUTPUT_VARIABLE CPP_CXX_ABI - COMPILE_OUTPUT_VARIABLE CPP_CXX_ABI_COMPILE_OUTPUT_VAR - ) - if (NOT ${CPP_CXX_ABI_COMPILE_RESULT_VAR}) - message(FATAL_ERROR "Failed to compile: \n ${CPP_CXX_ABI_COMPILE_OUTPUT_VAR}" ) - endif() - if (NOT ${CPP_CXX_ABI_RUN_RESULT_VAR} EQUAL "0") - message(FATAL_ERROR "Failed to run, return code: ${CPP_CXX_ABI}" ) - endif() - if (DEFINED PY_CXX_ABI) - if (NOT (${CPP_CXX_ABI} EQUAL ${PY_CXX_ABI})) - message (WARNNING "NOT consistent CXX_ABIs: python interface of tf uses ${PY_CXX_ABI}, while c++ interface of tf uses ${CPP_CXX_ABI}, we follow c++ interface ") - endif() - endif() - set(OP_CXX_ABI ${CPP_CXX_ABI}) - message (STATUS "Automatically determined OP_CXX_ABI=${OP_CXX_ABI} ") - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=${OP_CXX_ABI}) -endif(USE_TF_PYTHON_LIBS) - -# model version -file(READ ${PROJECT_SOURCE_DIR}/../../config/MODEL_VER MODEL_VERSION) -string(REPLACE "\n" " " MODEL_VERSION ${MODEL_VERSION}) -message(STATUS "Supported model version: ${MODEL_VERSION}") - -set(libname "deepmd") -set(apiname "deepmd_api") - -set(opname "deepmd_op") - -find_package(tensorflow REQUIRED) -if (TENSORFLOW_VERSION VERSION_GREATER_EQUAL 2.10) - set (CMAKE_CXX_STANDARD 17) -elseif (TENSORFLOW_VERSION VERSION_GREATER_EQUAL 2.7) - set (CMAKE_CXX_STANDARD 14) -else() - set (CMAKE_CXX_STANDARD 11) -endif() - -find_package(Threads) -# find openmp -find_package(OpenMP) -if (OPENMP_FOUND) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") -endif() - -# Devices that have both ROCM and CUDA are not currently supported -if (USE_ROCM_TOOLKIT AND USE_CUDA_TOOLKIT) - message (FATAL_ERROR "Devices that have both ROCM and CUDA are not currently supported") -endif() - -# define USE_CUDA_TOOLKIT -if (USE_CUDA_TOOLKIT) - find_package(CUDA REQUIRED) - add_definitions("-DGOOGLE_CUDA") - message(STATUS "Found CUDA in ${CUDA_TOOLKIT_ROOT_DIR}, build nv GPU support") -else() - message(STATUS "Will not build nv GPU support") -endif(USE_CUDA_TOOLKIT) - -#define USE_ROCM_TOOLKIT -if (USE_ROCM_TOOLKIT) - find_package(ROCM REQUIRED) - add_definitions("-DTENSORFLOW_USE_ROCM") - add_compile_definitions(__HIP_PLATFORM_HCC__) -else() - message(STATUS "Will not build AMD GPU support") -endif (USE_ROCM_TOOLKIT) - -set(LIB_DEEPMD ${libname}) -add_subdirectory(${CMAKE_SOURCE_DIR}/../../lib lib) - -set(HIGH_PREC_DEF "HIGH_PREC") -set(LOW_PREC_DEF "LOW_PREC") -set(HIGH_PREC_VARIANT "") -set(LOW_PREC_VARIANT "_low") -set(LIB_DEEPMD_CC ${apiname}) -add_subdirectory(${CMAKE_SOURCE_DIR}/.. api_cc) - -set(LIB_DEEPMD_OP ${opname}) -add_subdirectory(${CMAKE_SOURCE_DIR}/../../op op) - file(GLOB TEST_SRC test_*.cc) -add_executable( runUnitTests ${TEST_SRC} ) - -add_library(coverage_config INTERFACE) -target_compile_options(coverage_config INTERFACE - -O0 # no optimization - -g # generate debug info - --coverage # sets all required flags -) -if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13) - target_link_options(coverage_config INTERFACE --coverage) -else() - target_link_libraries(coverage_config INTERFACE --coverage) -endif() - -target_link_libraries(runUnitTests gtest gtest_main ${apiname} rt coverage_config) - -add_test( runUnitTests runUnitTests ) - -find_package(GTest) -if(NOT GTEST_LIBRARIES) - configure_file(../../cmake/googletest.cmake.in googletest-download/CMakeLists.txt) - execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) - if(result) - message(FATAL_ERROR "CMake step for googletest failed: ${result}") - endif() - execute_process(COMMAND ${CMAKE_COMMAND} --build . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) - if(result) - message(FATAL_ERROR "Build step for googletest failed: ${result}") - endif() - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src ${CMAKE_CURRENT_BINARY_DIR}/googletest-build EXCLUDE_FROM_ALL) -else () - include_directories(${GTEST_INCLUDE_DIRS}) -endif () +add_executable( runUnitTests_cc ${TEST_SRC} ) +target_link_libraries(runUnitTests_cc GTest::gtest_main ${LIB_DEEPMD_CC} rt coverage_config) +target_precompile_headers(runUnitTests_cc PRIVATE test_utils.h) +add_test( runUnitTest_cc runUnitTests_cc ) set_target_properties( - runUnitTests + runUnitTests_cc PROPERTIES INSTALL_RPATH "$ORIGIN/../lib" ) -set_target_properties( - ${apiname} - PROPERTIES - INSTALL_RPATH "$ORIGIN;${TensorFlow_LIBRARY_PATH}" +target_compile_definitions( + runUnitTests_cc + PUBLIC ${prec_def} ) -install(TARGETS runUnitTests DESTINATION bin/) +install(TARGETS runUnitTests_cc DESTINATION bin/) diff --git a/source/api_cc/tests/test_deepdipole.cc b/source/api_cc/tests/test_deepdipole.cc index 23382f49df..f08825f21b 100644 --- a/source/api_cc/tests/test_deepdipole.cc +++ b/source/api_cc/tests/test_deepdipole.cc @@ -11,10 +11,11 @@ #include #include +template class TestInferDeepDipole : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -25,10 +26,10 @@ class TestInferDeepDipole : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = { + std::vector box = { 13., 0., 0., 0., 13., 0., 0., 0., 13. }; - std::vector expected_d = { + std::vector expected_d = { -9.274180565967479195e-01,2.698028341272042496e+00,2.521268387140979117e-01,2.927260638453461628e+00,-8.571926301526779923e-01,1.667785136187720063e+00 }; int natoms = 6; @@ -46,9 +47,17 @@ class TestInferDeepDipole : public ::testing::Test }; }; +TYPED_TEST_SUITE(TestInferDeepDipole, ValueTypes); -TEST_F(TestInferDeepDipole, cpu_build_nlist) +TYPED_TEST(TestInferDeepDipole, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::DeepTensor& dp = this -> dp; EXPECT_EQ(dp.cutoff(), 4.); EXPECT_EQ(dp.numb_types(), 2); EXPECT_EQ(dp.output_dim(), 3); @@ -56,46 +65,53 @@ TEST_F(TestInferDeepDipole, cpu_build_nlist) EXPECT_EQ(sel_types.size(), 1); EXPECT_EQ(sel_types[0], 0); - std::vector value; + std::vector value; dp.compute(value, coord, atype, box); EXPECT_EQ(value.size(), expected_d.size()); for(int ii = 0; ii < expected_d.size(); ++ii){ - EXPECT_LT(fabs(value[ii] - expected_d[ii]), 1e-10); + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); } } -TEST_F(TestInferDeepDipole, cpu_lmp_nlist) +TYPED_TEST(TestInferDeepDipole, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::DeepTensor& dp = this -> dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector ilist(nloc), numneigh(nloc); std::vector firstneigh(nloc); std::vector > nlist_data; deepmd::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; convert_nlist(inlist, nlist_data); - std::vector value; + std::vector value; dp.compute(value, coord_cpy, atype_cpy, box, nall-nloc, inlist); EXPECT_EQ(value.size(), expected_d.size()); for(int ii = 0; ii < expected_d.size(); ++ii){ - EXPECT_LT(fabs(value[ii] - expected_d[ii]), 1e-10); + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); } } - +template class TestInferDeepDipoleNew : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -106,20 +122,20 @@ class TestInferDeepDipoleNew : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = { + std::vector box = { 13., 0., 0., 0., 13., 0., 0., 0., 13. }; - std::vector expected_t = { + std::vector expected_t = { -1.128427726201255282e-01, 2.654103846999197880e-01, 2.625816377288122533e-02, 3.027556488877700680e-01, -7.475444785689989990e-02, 1.526291164572509684e-01 }; - std::vector expected_f = { + std::vector expected_f = { 8.424897862241968738e-02, -3.823566783202275721e-02, 3.570797165027734810e-01, 6.102563129736437997e-02, -1.351209759852018133e-01, -2.438224487466488510e-01, -1.403204771681088869e-01, 1.719596545791735875e-01, -1.136584427103610045e-01, 2.761686212947551955e-02, -7.247860200915196005e-02, 6.208831127377397591e-02, -2.605870723577520809e-01, -4.504074577536486268e-02, 7.340240097998475266e-02, 2.280160774766013809e-01, 1.189163370225677641e-01, -1.350895372995223886e-01, -4.294311497114180337e-02, 1.524802094783661577e-01, 1.070451777645946290e-01, -1.259336332521076574e-01, -2.087610788959351760e-01, 9.447141346538817652e-02, 1.668125597515543457e-01, 5.487037060760904805e-02, -2.014994036104674757e-01, -7.411985441205551361e-02, 3.614456658821710300e-01, 2.901174891391154476e-01, -4.871926969937838414e-02, -1.252747945819455699e-01, -2.555459318266457558e-01, 1.249033125831290059e-01, -2.347603724902655176e-01, -3.458874493198500766e-02, 3.563990394229877290e-01, 1.052342031228763047e-01, 1.907268232932498031e-01, -2.432737821373903708e-01, 1.016781829972335099e-01, -7.707616437996064884e-02, -1.139199805053340564e-01, -2.068592154909300040e-01, -1.156337826476897951e-01, 6.583817133933017596e-02, 2.902207490750204344e-01, 9.945482314729316153e-02, 7.986986504051810098e-02, -2.549975565538568079e-01, 1.275343199697696051e-01, -1.449133131601115787e-01, -3.527636315034351350e-02, -2.250060193826620980e-01 }; - std::vector expected_v = { + std::vector expected_v = { 3.479789535931299138e-02, 4.337414719007849292e-03, -3.647371468256610082e-03, 8.053492919528318708e-03, 1.003834811499279773e-03, -8.441338187607602033e-04, -6.695998268698949256e-03, -8.346286793845711892e-04, 7.018468440279366279e-04, -4.515896716004976635e-02, 1.891794570218296306e-02, 3.417435352652402336e-02, 9.998952222904963771e-02, -4.188750255541257711e-02, -7.566774655171297492e-02, 1.804286120725206444e-01, -7.558495911146115298e-02, -1.365405712981232755e-01, -1.002593446510361419e-01, -1.117945222697993429e-01, 7.449172735713084637e-02, 7.770237313970995707e-02, 1.313723119887387492e-01, -8.655414676270002661e-02, -4.973937467461287537e-02, -8.663006083493235421e-02, 5.703914957966123994e-02, -3.382231967662072125e-02, -4.215813217482468345e-03, 3.545115660155720612e-03, -8.247565860499378454e-03, -1.028025206407854253e-03, 8.644757417520612143e-04, 6.761330949063471332e-03, 8.427721296283078580e-04, -7.086947453692606178e-04, -1.622698090933780493e-02, 1.305372051650728060e-01, -2.082599910094798112e-01, -7.109985131471197733e-03, 2.202585658101286273e-02, -3.554509763049529952e-02, 1.436400379134906459e-02, -3.554915857551419617e-02, 5.763638171798115412e-02, 2.074946305037073946e-01, 5.016353704485233822e-02, -5.700401936915034523e-02, 1.082138666905367308e-01, 2.616159414496492877e-02, -2.972908425564194101e-02, -1.229314789425654392e-01, -2.971969820589494271e-02, 3.377238432488059716e-02, 7.622024445219390681e-03, 9.500540384976005961e-04, -7.989090778275298932e-04, -2.952148931042387209e-02, -3.679732378636401541e-03, 3.094320409307891630e-03, -9.534268115386618486e-04, -1.188407357158671420e-04, 9.993425503379762414e-05, 9.319088860655992679e-02, -3.903942630815338682e-02, -7.052283462118023871e-02, 1.544831983829924038e-01, -6.471593445773991815e-02, -1.169062041817236081e-01, -6.990884596438741438e-02, 2.928613817427033750e-02, 5.290399154061733306e-02, 7.491400658274136037e-02, 1.273824184577304897e-01, -8.391492311946648075e-02, 3.543872837542783732e-02, 4.324623973455964804e-02, -2.873418641045778418e-02, -8.444981234074398768e-02, -1.531171183141288306e-01, 1.007308415346981068e-01, -6.396885751015785743e-03, -7.973455327045167592e-04, 6.704951070469818575e-04, 2.915483242551994078e-02, 3.634030104030812076e-03, -3.055888951116827318e-03, 6.608747470375698129e-04, 8.237532257692081912e-05, -6.927015762150179410e-05, -6.099175331115514430e-03, 2.402310352789886402e-02, -3.861491558256636286e-02, -2.583867422346154685e-02, 6.050621302336450097e-02, -9.822840263095998503e-02, -3.827994718203701213e-02, 1.252239810257823327e-01, -2.018867305507059950e-01, 1.136620144506474833e-01, 2.747872876828840599e-02, -3.122582814578225147e-02, -2.136319389661417989e-01, -5.164728194785846160e-02, 5.869009312256637939e-02, -3.147575788810638014e-02, -7.609523885036708832e-03, 8.647186232996251914e-03, -5.990706138603461330e-03, -7.467169124604876177e-04, 6.279210400235934152e-04, -9.287887182821588476e-04, -1.157696985960763821e-04, 9.735179200124630735e-05, -2.966271471326579340e-02, -3.697335544996301071e-03, 3.109123071928715683e-03, 1.800225987816693740e-01, -7.541487246259104271e-02, -1.362333179969384966e-01, -7.524185541795300192e-02, 3.152023672914239238e-02, 5.693978247845072477e-02, 5.703636164117102669e-02, -2.389361095778780308e-02, -4.316265205277792366e-02, -4.915584336537091176e-02, -8.674240294138457763e-02, 5.709724154860432860e-02, -8.679070528401405804e-02, -1.572017650485294793e-01, 1.034201569997979520e-01, -3.557746655862283752e-02, -8.626268394893003844e-02, 5.645546718878535764e-02, 6.848075985139651621e-03, 8.535845420570665554e-04, -7.177870012752625602e-04, 8.266638576582277997e-04, 1.030402542123569647e-04, -8.664748649675494882e-05, 2.991751925173294011e-02, 3.729095884068693231e-03, -3.135830629785046203e-03, 1.523793442834292522e-02, -3.873020552543556677e-02, 6.275576045602117292e-02, -3.842536616563556329e-02, 1.249268983543572881e-01, -2.014296501045876875e-01, 1.288704808602599873e-02, -6.326999354443738066e-02, 1.014064886873057153e-01, -1.318711149757016143e-01, -3.188092889522457091e-02, 3.622832829002789468e-02, -3.210149046681261276e-02, -7.760799893075580151e-03, 8.819090787585878374e-03, -2.047554776382226327e-01, -4.950132426418570042e-02, 5.625150484566552450e-02 }; - std::vector expected_gt; - std::vector expected_gv; + std::vector expected_gt; + std::vector expected_gv; int natoms = 6; int nsel = 2; int odim; @@ -153,9 +169,23 @@ class TestInferDeepDipoleNew : public ::testing::Test }; }; +TYPED_TEST_SUITE(TestInferDeepDipoleNew, ValueTypes); -TEST_F(TestInferDeepDipoleNew, cpu_build_nlist) +TYPED_TEST(TestInferDeepDipoleNew, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_t = this -> expected_t; + std::vector& expected_f = this -> expected_f; + std::vector& expected_v = this -> expected_v; + std::vector& expected_gt = this -> expected_gt; + std::vector& expected_gv = this -> expected_gv; + int& natoms = this -> natoms; + int& nsel = this -> nsel; + int& odim = this -> odim; + deepmd::DeepTensor& dp = this -> dp; EXPECT_EQ(dp.cutoff(), 4.); EXPECT_EQ(dp.numb_types(), 2); EXPECT_EQ(dp.output_dim(), 3); @@ -163,74 +193,87 @@ TEST_F(TestInferDeepDipoleNew, cpu_build_nlist) EXPECT_EQ(sel_types.size(), 1); EXPECT_EQ(sel_types[0], 0); - std::vector gt, ff, vv, at, av; + std::vector gt, ff, vv, at, av; dp.compute(at, coord, atype, box); EXPECT_EQ(at.size(), expected_t.size()); for(int ii = 0; ii < expected_t.size(); ++ii){ - EXPECT_LT(fabs(at[ii] - expected_t[ii]), 1e-10); + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); } dp.compute(gt, ff, vv, coord, atype, box); EXPECT_EQ(gt.size(), expected_gt.size()); for(int ii = 0; ii < expected_gt.size(); ++ii){ - EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), 1e-10); + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); } EXPECT_EQ(ff.size(), expected_f.size()); for(int ii = 0; ii < expected_f.size(); ++ii){ - EXPECT_LT(fabs(ff[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(ff[ii] - expected_f[ii]), EPSILON); } EXPECT_EQ(vv.size(), expected_gv.size()); for(int ii = 0; ii < expected_gv.size(); ++ii){ - EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), 1e-10); + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); } dp.compute(gt, ff, vv, at, av, coord, atype, box); EXPECT_EQ(gt.size(), expected_gt.size()); for(int ii = 0; ii < expected_gt.size(); ++ii){ - EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), 1e-10); + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); } EXPECT_EQ(ff.size(), expected_f.size()); for(int ii = 0; ii < expected_f.size(); ++ii){ - EXPECT_LT(fabs(ff[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(ff[ii] - expected_f[ii]), EPSILON); } EXPECT_EQ(vv.size(), expected_gv.size()); for(int ii = 0; ii < expected_gv.size(); ++ii){ - EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), 1e-10); + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); } EXPECT_EQ(at.size(), expected_t.size()); for(int ii = 0; ii < expected_t.size(); ++ii){ - EXPECT_LT(fabs(at[ii] - expected_t[ii]), 1e-10); + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); } EXPECT_EQ(av.size(), expected_v.size()); for(int ii = 0; ii < expected_v.size(); ++ii){ - EXPECT_LT(fabs(av[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(av[ii] - expected_v[ii]), EPSILON); } } -TEST_F(TestInferDeepDipoleNew, cpu_lmp_nlist) +TYPED_TEST(TestInferDeepDipoleNew, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_t = this -> expected_t; + std::vector& expected_f = this -> expected_f; + std::vector& expected_v = this -> expected_v; + std::vector& expected_gt = this -> expected_gt; + std::vector& expected_gv = this -> expected_gv; + int& natoms = this -> natoms; + int& nsel = this -> nsel; + int& odim = this -> odim; + deepmd::DeepTensor& dp = this -> dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector ilist(nloc), numneigh(nloc); std::vector firstneigh(nloc); std::vector > nlist_data; deepmd::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; convert_nlist(inlist, nlist_data); - std::vector gt, ff, vv, at, av; + std::vector gt, ff, vv, at, av; dp.compute(at, coord_cpy, atype_cpy, box, nall-nloc, inlist); EXPECT_EQ(at.size(), expected_t.size()); for(int ii = 0; ii < expected_t.size(); ++ii){ - EXPECT_LT(fabs(at[ii] - expected_t[ii]), 1e-10); + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); } @@ -238,21 +281,21 @@ TEST_F(TestInferDeepDipoleNew, cpu_lmp_nlist) EXPECT_EQ(gt.size(), expected_gt.size()); for(int ii = 0; ii < expected_gt.size(); ++ii){ - EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), 1e-10); + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); } // remove ghost atoms - std::vector rff (odim * nloc * 3); + std::vector rff (odim * nloc * 3); for(int kk = 0; kk < odim; ++kk){ - _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); + _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); } EXPECT_EQ(rff.size(), expected_f.size()); for(int ii = 0; ii < expected_f.size(); ++ii){ - EXPECT_LT(fabs(rff[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(rff[ii] - expected_f[ii]), EPSILON); } // virial EXPECT_EQ(vv.size(), expected_gv.size()); for(int ii = 0; ii < expected_gv.size(); ++ii){ - EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), 1e-10); + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); } @@ -260,43 +303,43 @@ TEST_F(TestInferDeepDipoleNew, cpu_lmp_nlist) EXPECT_EQ(gt.size(), expected_gt.size()); for(int ii = 0; ii < expected_gt.size(); ++ii){ - EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), 1e-10); + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); } // remove ghost atoms for(int kk = 0; kk < odim; ++kk){ - _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); + _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); } EXPECT_EQ(rff.size(), expected_f.size()); for(int ii = 0; ii < expected_f.size(); ++ii){ - EXPECT_LT(fabs(rff[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(rff[ii] - expected_f[ii]), EPSILON); } // virial EXPECT_EQ(vv.size(), expected_gv.size()); for(int ii = 0; ii < expected_gv.size(); ++ii){ - EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), 1e-10); + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); } // atom tensor EXPECT_EQ(at.size(), expected_t.size()); for(int ii = 0; ii < expected_t.size(); ++ii){ - EXPECT_LT(fabs(at[ii] - expected_t[ii]), 1e-10); + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); } // atom virial - std::vector rav (odim * nloc * 9); + std::vector rav (odim * nloc * 9); for(int kk = 0; kk < odim; ++kk){ - _fold_back(rav.begin() + kk * nloc * 9, av.begin() + kk * nall * 9, mapping, nloc, nall, 9); + _fold_back(rav.begin() + kk * nloc * 9, av.begin() + kk * nall * 9, mapping, nloc, nall, 9); } EXPECT_EQ(rav.size(), expected_v.size()); for(int ii = 0; ii < expected_v.size(); ++ii){ - EXPECT_LT(fabs(rav[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(rav[ii] - expected_v[ii]), EPSILON); } } - +template class TestInferDeepDipoleFake : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -307,10 +350,10 @@ class TestInferDeepDipoleFake : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = { + std::vector box = { 13., 0., 0., 0., 13., 0., 0., 0., 13. }; - std::vector expected_d = { + std::vector expected_d = { -3.186217894664857830e-01, 1.082220317383403296e+00, 5.646623185237639730e-02, 7.426508038929955369e-01, -3.115996324658170114e-01, -5.619108089573777720e-01, -4.181578166874897473e-01, -7.579762930974662805e-01, 4.980618433125854616e-01, 1.059635561913792712e+00, -2.641989315855929332e-01, 5.307984468104405273e-01, -1.484512535335152095e-01, 4.978588497891502374e-01, -8.022467807199461509e-01, -9.165936539882671985e-01, -2.238112120606238209e-01, 2.553133145814526217e-01 }; int natoms = 6; @@ -328,9 +371,17 @@ class TestInferDeepDipoleFake : public ::testing::Test }; }; +TYPED_TEST_SUITE(TestInferDeepDipoleFake, ValueTypes); -TEST_F(TestInferDeepDipoleFake, cpu_build_nlist) +TYPED_TEST(TestInferDeepDipoleFake, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::DeepTensor& dp = this -> dp; EXPECT_EQ(dp.cutoff(), 2.); EXPECT_EQ(dp.numb_types(), 2); EXPECT_EQ(dp.output_dim(), 3); @@ -339,37 +390,44 @@ TEST_F(TestInferDeepDipoleFake, cpu_build_nlist) EXPECT_EQ(sel_types[0], 0); EXPECT_EQ(sel_types[1], 1); - std::vector value; + std::vector value; dp.compute(value, coord, atype, box); EXPECT_EQ(value.size(), expected_d.size()); for(int ii = 0; ii < expected_d.size(); ++ii){ - EXPECT_LT(fabs(value[ii] - expected_d[ii]), 1e-10); + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); } } -TEST_F(TestInferDeepDipoleFake, cpu_lmp_nlist) +TYPED_TEST(TestInferDeepDipoleFake, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::DeepTensor& dp = this -> dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector ilist(nloc), numneigh(nloc); std::vector firstneigh(nloc); std::vector > nlist_data; deepmd::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; convert_nlist(inlist, nlist_data); - std::vector value; + std::vector value; dp.compute(value, coord_cpy, atype_cpy, box, nall-nloc, inlist); EXPECT_EQ(value.size(), expected_d.size()); for(int ii = 0; ii < expected_d.size(); ++ii){ - EXPECT_LT(fabs(value[ii] - expected_d[ii]), 1e-10); + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); } } diff --git a/source/api_cc/tests/test_deeppolar.cc b/source/api_cc/tests/test_deeppolar.cc index ad4ccdca5b..e678ae4631 100644 --- a/source/api_cc/tests/test_deeppolar.cc +++ b/source/api_cc/tests/test_deeppolar.cc @@ -11,10 +11,11 @@ #include #include +template class TestInferDeepPolar : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -25,10 +26,10 @@ class TestInferDeepPolar : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = { + std::vector box = { 13., 0., 0., 0., 13., 0., 0., 0., 13. }; - std::vector expected_d = { + std::vector expected_d = { 1.061407927405987051e-01,-3.569013342133873778e-01,-2.862108976089940138e-02,-3.569013342133875444e-01,1.304367268874677244e+00,1.037647501453442256e-01,-2.862108976089940138e-02,1.037647501453441284e-01,8.100521520762453409e-03,1.236797829492216616e+00,-3.717307430531632262e-01,7.371515676976750919e-01,-3.717307430531630041e-01,1.127222682121889058e-01,-2.239181552775717510e-01,7.371515676976746478e-01,-2.239181552775717787e-01,4.448255365635306879e-01 }; int natoms; @@ -49,9 +50,18 @@ class TestInferDeepPolar : public ::testing::Test }; }; +TYPED_TEST_SUITE(TestInferDeepPolar, ValueTypes); -TEST_F(TestInferDeepPolar, cpu_build_nlist) +TYPED_TEST(TestInferDeepPolar, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::DeepTensor& dp = this -> dp; + EXPECT_EQ(dp.cutoff(), 6.); EXPECT_EQ(dp.numb_types(), 2); EXPECT_EQ(dp.output_dim(), 9); @@ -59,46 +69,53 @@ TEST_F(TestInferDeepPolar, cpu_build_nlist) EXPECT_EQ(sel_types.size(), 1); EXPECT_EQ(sel_types[0], 0); - std::vector value; + std::vector value; dp.compute(value, coord, atype, box); EXPECT_EQ(value.size(), expected_d.size()); for(int ii = 0; ii < expected_d.size(); ++ii){ - EXPECT_LT(fabs(value[ii] - expected_d[ii]), 1e-10); + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); } } -TEST_F(TestInferDeepPolar, cpu_lmp_nlist) +TYPED_TEST(TestInferDeepPolar, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& atype = this -> atype; + std::vector& box = this -> box; + std::vector& expected_d = this -> expected_d; + int& natoms = this -> natoms; + deepmd::DeepTensor& dp = this -> dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector ilist(nloc), numneigh(nloc); std::vector firstneigh(nloc); std::vector > nlist_data; deepmd::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; convert_nlist(inlist, nlist_data); - std::vector value; + std::vector value; dp.compute(value, coord_cpy, atype_cpy, box, nall-nloc, inlist); EXPECT_EQ(value.size(), expected_d.size()); for(int ii = 0; ii < expected_d.size(); ++ii){ - EXPECT_LT(fabs(value[ii] - expected_d[ii]), 1e-10); + EXPECT_LT(fabs(value[ii] - expected_d[ii]), EPSILON); } } - +template class TestInferDeepPolarNew : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -109,20 +126,20 @@ class TestInferDeepPolarNew : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = { + std::vector box = { 13., 0., 0., 0., 13., 0., 0., 0., 13. }; - std::vector expected_t = { + std::vector expected_t = { 1.936327241487292961e+00, 5.198696351735779264e-02, 3.888336625074450149e-03, 5.198696351735781346e-02, 1.764967784387830196e+00, -1.354658545697527347e-02, 3.888336625074451016e-03, -1.354658545697527000e-02, 1.939288409902199639e+00, 1.786740420980893029e+00, 4.868765294055640847e-02, -9.812132615180739481e-02, 4.868765294055640847e-02, 1.925999147066305373e+00, 2.895028407651457567e-02, -9.812132615180743644e-02, 2.895028407651457220e-02, 1.883109989034779996e+00 }; - std::vector expected_f = { + std::vector expected_f = { 5.305178446980116092e-02, -1.127314829623577049e-02, 1.136493514861047216e-01, 5.598130220328862322e-05, -4.352126938892845326e-02, -7.700608888887500170e-02, -1.050015668789053697e-01, 5.882396336737016895e-02, -3.723875897544067642e-02, -7.850322286760008650e-02, 7.279117637753844405e-02, -6.178451060078461732e-02, 3.404361490778949895e-01, 5.447934529195214842e-02, -8.698375128815737101e-02, -2.100391251033939810e-01, -1.313000673516965255e-01, 1.493637582671529240e-01, -9.589318874236771317e-02, 6.285887854370801608e-02, -1.824395427630142175e-01, -3.264267092869802683e-02, 3.637498661083633789e-02, 1.524859582123189172e-01, 1.442484990808054202e-01, -8.957992476622803069e-02, 3.076469140583825215e-02, 4.909822745881124717e-02, -2.559151672032903835e-01, -1.522830913546814324e-01, -2.885480042033320910e-02, 7.730841025065784966e-02, 1.553301391955271560e-01, -3.595606644821771475e-02, 1.689528165643162105e-01, -3.858154695988691516e-03, 5.018843026262573281e-02, 1.756005154318779349e-02, 3.489323893614350303e-02, -4.020411124876955428e-02, 2.218648284685413238e-02, -8.086177159691650476e-03, -2.222392408702593067e-02, -3.825892777133557687e-02, -1.689393838770965675e-02, -5.465804822761769627e-02, -1.398775875506316768e-01, -1.165702490994514756e-01, 5.449067849718619572e-02, 1.588580450812354106e-01, -8.209560373418453572e-02, 1.240697480360127003e-02, -2.046806414931008622e-02, 1.887527294448937965e-01, -9.589318874236771317e-02, 6.285887854370801608e-02, -1.824395427630142175e-01, -3.264267092869802683e-02, 3.637498661083633789e-02, 1.524859582123189172e-01, 1.442484990808054202e-01, -8.957992476622803069e-02, 3.076469140583825215e-02, 4.909822745881124717e-02, -2.559151672032903835e-01, -1.522830913546814324e-01, -2.885480042033320910e-02, 7.730841025065784966e-02, 1.553301391955271560e-01, -3.595606644821771475e-02, 1.689528165643162105e-01, -3.858154695988691516e-03, 4.038746042068122599e-02, -2.549213597407858356e-01, -1.131801705114504619e-01, 1.489732376295762606e-01, 2.734584831542113958e-01, -1.125511889088352951e-01, -1.908551011160136424e-01, -2.400995606986339528e-02, 2.255650484976146619e-01, -2.185213968874370055e-02, 1.475333123369945709e-01, 9.584417756169674729e-02, -1.576380405016522893e-02, -5.153693137796186430e-02, -8.489897831367294867e-02, 3.911034680466508873e-02, -9.052354830259493057e-02, -1.077888832535272776e-02, -1.970229486427777510e-01, -6.538978166042377915e-02, -1.570533119125729904e-01, 1.417940206277617798e-01, -4.684714285705613573e-02, 6.070882964241105378e-02, 5.715183445260185735e-02, 1.138024049318459713e-01, 9.374622673558237473e-02, 3.096927839536914306e-02, -9.232883741117139942e-02, -6.499836527010099951e-02, 2.839980861544661936e-02, 8.097497759757724123e-03, 1.006700103228213017e-01, -6.129199344840163821e-02, 8.266585923704758421e-02, -3.307338951814068478e-02, 5.018843026262574669e-02, 1.756005154318778308e-02, 3.489323893614350997e-02, -4.020411124876957509e-02, 2.218648284685414279e-02, -8.086177159691652211e-03, -2.222392408702593067e-02, -3.825892777133557687e-02, -1.689393838770965675e-02, -5.465804822761770321e-02, -1.398775875506316491e-01, -1.165702490994514756e-01, 5.449067849718619572e-02, 1.588580450812354106e-01, -8.209560373418453572e-02, 1.240697480360125615e-02, -2.046806414931009316e-02, 1.887527294448937965e-01, -1.970229486427777510e-01, -6.538978166042375140e-02, -1.570533119125729626e-01, 1.417940206277618076e-01, -4.684714285705613573e-02, 6.070882964241105378e-02, 5.715183445260184347e-02, 1.138024049318459713e-01, 9.374622673558236086e-02, 3.096927839536912919e-02, -9.232883741117139942e-02, -6.499836527010102727e-02, 2.839980861544661589e-02, 8.097497759757731062e-03, 1.006700103228213017e-01, -6.129199344840162433e-02, 8.266585923704758421e-02, -3.307338951814066397e-02, -3.078161564779093723e-02, -8.748776750553553111e-03, -2.162930108693108394e-02, 2.135313622214399243e-02, -8.845621737097757523e-03, 9.365293934359546560e-03, 8.562579091543631032e-03, 1.772751551871581607e-02, 1.573655414890783033e-02, -3.649820158632081230e-02, -1.904914900326310223e-01, -1.076542087674599024e-01, -5.186655049718805199e-02, 1.686765146765009937e-01, -6.620206332305828001e-02, 8.923065241761217459e-02, 2.168185832506550753e-02, 1.703837250941818704e-01 }; - std::vector expected_v = { + std::vector expected_v = { -2.123013313652813774e-03, -2.646248889538913257e-04, 2.225254748021367093e-04, 9.843593195853941446e-04, 1.226963457840150472e-04, -1.031764725911038809e-04, -8.467513732241481721e-04, -1.055440805151912256e-04, 8.875297679686559459e-05, 1.829118379697145316e-02, 2.302438731350108913e-03, -1.890198823577125386e-03, 3.300229266409118040e-02, -1.339230641165423293e-02, -2.445540228188634868e-02, 5.127826101331301595e-02, -2.458314752619149279e-02, -4.252530480245884925e-02, 9.733043787604266084e-02, -6.217238566516904152e-02, 3.767656091618994812e-02, 6.674680725588777973e-03, 4.245867422406505304e-02, -2.752200660186601699e-02, -8.318636634138946995e-03, -2.738884420387305285e-02, 1.785195524121836741e-02, -3.151218435289559073e-03, -3.927864338604547816e-04, 3.302976830190196104e-04, 1.387198082848713948e-06, 1.729085429046553641e-07, -1.454003656243721975e-07, -4.056191292896940703e-05, -5.055875832506090064e-06, 4.251531950061960394e-06, 7.087482338961141604e-02, -1.643445525800983908e-01, 2.668682182870234509e-01, 7.752581706917366366e-03, -2.674714571946596939e-02, 4.308263417785011123e-02, -9.385640612496094423e-03, 4.307848167667025635e-02, -6.910099104451945806e-02, -1.822493611414978121e-01, -4.510097387143227610e-02, 5.157836206906134952e-02, -1.170389534066011428e-01, -2.858136680923874240e-02, 3.256883555835647648e-02, 1.336331160725280354e-01, 3.257484898923947853e-02, -3.710113093740719653e-02, 3.343993600586595179e-03, 4.168150663620683060e-04, -3.505035785317401481e-04, -4.312491363797464269e-03, -5.375343342977005178e-04, 4.520175083867039156e-04, -5.045304632809267465e-04, -6.288764981405317546e-05, 5.288279643454484632e-05, 2.176577726533836937e-02, -1.041710664445027849e-02, -1.802940684978692962e-02, -3.097121964369356495e-02, 1.077096511204005125e-02, 2.079488766754130843e-02, -1.120464690158002596e-01, 4.736950869652114399e-02, 8.530900293808066359e-02, 3.029112757823893692e-02, 1.058529311156591879e-01, -6.894903720238335088e-02, -5.089618157121258979e-02, -6.973511953466600410e-02, 4.618114280030299196e-02, 1.143309394598741001e-02, 2.319568285212985151e-02, -1.522637168466081138e-02, -1.535733649675188493e-03, -1.914228911776438445e-04, 1.609692493993826663e-04, -2.603290366421702733e-03, -3.244894507721100851e-04, 2.728661290583660171e-04, 6.938458118266074663e-04, 8.648503036932213837e-05, -7.272604826511198082e-05, -2.609239945314979423e-02, 1.142603664459106681e-02, -2.051406106454568487e-02, 5.779549344910496142e-03, -3.860615030463052100e-02, 6.168332781226748551e-02, 2.068839156841529789e-02, -7.643723474881176927e-02, 1.229844977392647865e-01, -3.554667688747349674e-02, -8.262665730398828859e-03, 9.285295046969522723e-03, 1.497274901467501862e-01, 3.666859638982037511e-02, -4.181688913175674732e-02, -3.257377626487627069e-03, -8.171909213273372040e-04, 9.379633299917983094e-04, 5.408910405506226968e-04, 6.741984641424190365e-05, -5.669396175743082354e-05, 4.696290607396237790e-04, 5.853733334998140626e-05, -4.922457577157541143e-05, -5.350269144276139158e-03, -6.668890718077903363e-04, 5.607930831110977251e-04, 3.013271000130106694e-02, -1.241570117891089425e-02, -2.255430712666738058e-02, -1.643158253499693577e-02, 6.876116339617440766e-03, 1.242585434168311936e-02, 2.120265775977717496e-03, -2.988284987993197143e-03, -4.123302560925387432e-03, 3.528008965720315360e-02, -1.132921329184741026e-02, 6.435692645130823564e-03, -2.115291124444698342e-02, -2.971050496327276927e-02, 1.966236467455729359e-02, -2.194244461519655187e-02, -1.469000955331024871e-02, 1.000316933044766328e-02, -2.208576023807404254e-03, -2.752899293131040766e-04, 2.314938041951108548e-04, -5.840262773118632192e-04, -7.279647649213021596e-05, 6.121521886838239123e-05, -1.263538670848133802e-03, -1.574949051482092536e-04, 1.324388975109944740e-04, 8.955566031735841259e-03, -2.660296383100100095e-02, 4.296567375352825652e-02, 2.380373596470350059e-02, -7.784355459714024927e-02, 1.255004729498893912e-01, -1.824501349606120690e-02, 3.948761180940744964e-02, -6.423389834199008663e-02, 1.038606825469970407e-02, 2.616819816765628484e-03, -3.006960935423359793e-03, -1.864007491704058883e-02, -4.504736174636920880e-03, 5.118497771104377897e-03, 1.680266347982039554e-01, 4.105963063126880086e-02, -4.679634408112137711e-02, 3.343993600586595179e-03, 4.168150663620683060e-04, -3.505035785317401481e-04, -4.312491363797464269e-03, -5.375343342977005178e-04, 4.520175083867039156e-04, -5.045304632809267465e-04, -6.288764981405317546e-05, 5.288279643454484632e-05, 2.176577726533836937e-02, -1.041710664445027849e-02, -1.802940684978692962e-02, -3.097121964369356495e-02, 1.077096511204005125e-02, 2.079488766754130843e-02, -1.120464690158002596e-01, 4.736950869652114399e-02, 8.530900293808066359e-02, 3.029112757823893692e-02, 1.058529311156591879e-01, -6.894903720238335088e-02, -5.089618157121258979e-02, -6.973511953466600410e-02, 4.618114280030299196e-02, 1.143309394598741001e-02, 2.319568285212985151e-02, -1.522637168466081138e-02, -1.535733649675188493e-03, -1.914228911776438445e-04, 1.609692493993826663e-04, -2.603290366421702733e-03, -3.244894507721100851e-04, 2.728661290583660171e-04, 6.938458118266074663e-04, 8.648503036932213837e-05, -7.272604826511198082e-05, -2.609239945314979423e-02, 1.142603664459106681e-02, -2.051406106454568487e-02, 5.779549344910496142e-03, -3.860615030463052100e-02, 6.168332781226748551e-02, 2.068839156841529789e-02, -7.643723474881176927e-02, 1.229844977392647865e-01, -3.554667688747349674e-02, -8.262665730398828859e-03, 9.285295046969522723e-03, 1.497274901467501862e-01, 3.666859638982037511e-02, -4.181688913175674732e-02, -3.257377626487627069e-03, -8.171909213273372040e-04, 9.379633299917983094e-04, 1.097257666720985849e-03, 1.367686610077148478e-04, -1.150100103928514269e-04, -3.252401295559594844e-03, -4.053984617694676175e-04, 3.409032519425078027e-04, -1.217154259382106555e-04, -1.517132787898375553e-05, 1.275770753460001047e-05, -1.104423096905816498e-01, 4.615651100464009809e-02, 8.344619780982527601e-02, -1.998235369855275168e-01, 8.508819942125579738e-02, 1.528709647298205909e-01, 8.333302476347614896e-02, -3.488524142655123617e-02, -6.303339769808283255e-02, -7.468341447282240975e-02, -1.443673498458480642e-01, 9.485360739696327426e-02, -2.685004652445167612e-04, -1.702408228533323561e-02, 1.097613894113106531e-02, 9.496752299747332482e-02, 1.714581306702349373e-01, -1.128066531362114239e-01, -2.109671824413435984e-03, -2.629619271223545066e-04, 2.211270750801623281e-04, 1.011694656468142307e-02, 1.261035832424879221e-03, -1.060416495448196581e-03, 2.326027531269699879e-04, 2.899297772687444119e-05, -2.438045854305356789e-05, -9.775618976121780001e-04, 7.897148922927013995e-03, -1.259878571596698138e-02, -5.534571406250721713e-03, 2.552681480358522451e-02, -4.094434810336724379e-02, -1.258721457759937913e-02, 4.161890111720080443e-02, -6.708566706120022705e-02, 3.521744971093632853e-02, 8.557787631933998912e-03, -9.738493960065902622e-03, -8.446926488038911107e-02, -2.017604402799078392e-02, 2.285024948138817888e-02, -9.755577915095828626e-03, -2.364722966186930900e-03, 2.689144780896026744e-03, 8.392348196279006065e-05, 1.046071729847805219e-05, -8.796512273720217211e-06, -2.967282659264359589e-03, -3.698595949224694123e-04, 3.110182957302592738e-04, -1.688223115474902841e-03, -2.104300767164184042e-04, 1.769525645115341121e-04, -1.040849854787611189e-01, 4.406117175034113265e-02, 7.931633477513304331e-02, 3.539829580561168476e-02, -1.443144702217136026e-02, -2.631106338063535569e-02, -4.383990895980735547e-02, 1.895493123709470276e-02, 3.388325869579450478e-02, 1.809448338386955915e-02, 4.269882582195522885e-02, -2.795653019460052346e-02, 4.363124777259473619e-02, 8.597058258914810902e-02, -5.646456449126337207e-02, 4.431189331687027805e-02, 7.186269332716928304e-02, -4.739074421553418626e-02, 7.807665162715203382e-05, 9.731933913865978996e-06, -8.183671700296416994e-06, 2.525821455836478949e-03, 3.148332692827336839e-04, -2.647461582604813284e-04, 5.088778918832323993e-03, 6.342953893162101269e-04, -5.333847591977234877e-04, 1.765533347871811772e-03, -1.422682766506909793e-02, 2.269730547460076936e-02, 2.888222424864686153e-04, -4.083171371247279469e-03, 6.494062010930001794e-03, 1.594130471018519873e-02, -4.922350239779287734e-02, 7.944117864515577720e-02, -5.516443865142822006e-02, -1.340804559261108905e-02, 1.525892700429632917e-02, 7.450140187529649682e-02, 1.809617933997387934e-02, -2.059052256811338619e-02, -3.118940445306414219e-02, -7.412336287839308216e-03, 8.382871287998559101e-03, 5.408910405506207452e-04, 6.741984641424155129e-05, -5.669396175743063380e-05, 4.696290607396231285e-04, 5.853733334998132494e-05, -4.922457577157534367e-05, -5.350269144276134821e-03, -6.668890718077897942e-04, 5.607930831110975083e-04, 3.013271000130106694e-02, -1.241570117891090119e-02, -2.255430712666738752e-02, -1.643158253499694271e-02, 6.876116339617444236e-03, 1.242585434168312457e-02, 2.120265775977718363e-03, -2.988284987993198010e-03, -4.123302560925387432e-03, 3.528008965720314666e-02, -1.132921329184741026e-02, 6.435692645130823564e-03, -2.115291124444698342e-02, -2.971050496327276927e-02, 1.966236467455729012e-02, -2.194244461519655881e-02, -1.469000955331024871e-02, 1.000316933044766501e-02, -2.208576023807403820e-03, -2.752899293131040766e-04, 2.314938041951108548e-04, -5.840262773118632192e-04, -7.279647649213021596e-05, 6.121521886838239123e-05, -1.263538670848133802e-03, -1.574949051482092536e-04, 1.324388975109944740e-04, 8.955566031735841259e-03, -2.660296383100100095e-02, 4.296567375352825652e-02, 2.380373596470350059e-02, -7.784355459714024927e-02, 1.255004729498893912e-01, -1.824501349606121037e-02, 3.948761180940744964e-02, -6.423389834199008663e-02, 1.038606825469969019e-02, 2.616819816765625015e-03, -3.006960935423356324e-03, -1.864007491704059577e-02, -4.504736174636922615e-03, 5.118497771104379632e-03, 1.680266347982039554e-01, 4.105963063126880086e-02, -4.679634408112137711e-02, 8.392348196278930170e-05, 1.046071729847797087e-05, -8.796512273720142672e-06, -2.967282659264356987e-03, -3.698595949224691413e-04, 3.110182957302590027e-04, -1.688223115474903708e-03, -2.104300767164184855e-04, 1.769525645115341934e-04, -1.040849854787611189e-01, 4.406117175034113265e-02, 7.931633477513304331e-02, 3.539829580561167782e-02, -1.443144702217136026e-02, -2.631106338063535569e-02, -4.383990895980735547e-02, 1.895493123709470276e-02, 3.388325869579450478e-02, 1.809448338386955221e-02, 4.269882582195521498e-02, -2.795653019460051653e-02, 4.363124777259472925e-02, 8.597058258914809514e-02, -5.646456449126335819e-02, 4.431189331687027111e-02, 7.186269332716926916e-02, -4.739074421553417932e-02, 7.807665162715246750e-05, 9.731933913866019654e-06, -8.183671700296457651e-06, 2.525821455836478515e-03, 3.148332692827336297e-04, -2.647461582604812742e-04, 5.088778918832324860e-03, 6.342953893162102353e-04, -5.333847591977235961e-04, 1.765533347871809603e-03, -1.422682766506909793e-02, 2.269730547460076589e-02, 2.888222424864694826e-04, -4.083171371247282938e-03, 6.494062010930008733e-03, 1.594130471018519873e-02, -4.922350239779287040e-02, 7.944117864515577720e-02, -5.516443865142821312e-02, -1.340804559261108558e-02, 1.525892700429632570e-02, 7.450140187529649682e-02, 1.809617933997387934e-02, -2.059052256811338966e-02, -3.118940445306412831e-02, -7.412336287839304746e-03, 8.382871287998553897e-03, -9.575909105642434974e-04, -1.193597735547498307e-04, 1.003707186710399045e-04, -9.520061199010912585e-05, -1.186636523389461756e-05, 9.978534401229592523e-06, -5.876800709203859434e-03, -7.325190685693192200e-04, 6.159819440242017292e-04, -1.659431774532551043e-02, 6.520628417529478540e-03, 1.204087494393247214e-02, 6.518824051016284399e-03, -2.745500204548994606e-03, -4.950724849051978994e-03, -5.340810191179472081e-03, 3.101366677982481286e-03, 5.077959020099345744e-03, 7.727976016970144156e-03, 7.022558645366243878e-03, -4.714356496325102820e-03, 7.018017321145150929e-03, 1.341962078953426278e-02, -8.818944869050635710e-03, -2.755773236988961865e-03, 1.079245666846929096e-02, -6.886663303228377636e-03, 9.801230913130992879e-04, 1.221683173308112048e-04, -1.027324486645460452e-04, 1.233918620327190629e-04, 1.538028875195364422e-05, -1.293342463232469071e-05, 4.892751025155074075e-03, 6.098613175830685205e-04, -5.128379261493998297e-04, -7.792305682365031905e-03, 2.541307371885552502e-02, -4.097328323558844382e-02, 2.530143617608526449e-02, -8.265149730513186854e-02, 1.332544508945474881e-01, -1.184335640259520997e-02, 3.220055758982264676e-02, -5.209911236104310117e-02, 8.090761694886683397e-02, 1.959431243541279177e-02, -2.227702786419644143e-02, 1.968691296265078980e-02, 4.764576998712748319e-03, -5.415896903683155988e-03, 1.534638141861073557e-01, 3.728680895816388619e-02, -4.242975875503233324e-02 }; - std::vector expected_gt; - std::vector expected_gv; + std::vector expected_gt; + std::vector expected_gv; int natoms = 6; int nsel = 2; int odim; @@ -156,9 +173,23 @@ class TestInferDeepPolarNew : public ::testing::Test }; }; +TYPED_TEST_SUITE(TestInferDeepPolarNew, ValueTypes); -TEST_F(TestInferDeepPolarNew, cpu_build_nlist) +TYPED_TEST(TestInferDeepPolarNew, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_t = this->expected_t; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + std::vector& expected_gt = this->expected_gt; + std::vector& expected_gv = this->expected_gv; + int& natoms = this->natoms; + int& nsel = this->nsel; + int& odim = this->odim; + deepmd::DeepTensor& dp = this->dp; EXPECT_EQ(dp.cutoff(), 6.); EXPECT_EQ(dp.numb_types(), 2); EXPECT_EQ(dp.output_dim(), 9); @@ -166,74 +197,87 @@ TEST_F(TestInferDeepPolarNew, cpu_build_nlist) EXPECT_EQ(sel_types.size(), 1); EXPECT_EQ(sel_types[0], 0); - std::vector gt, ff, vv, at, av; + std::vector gt, ff, vv, at, av; dp.compute(at, coord, atype, box); EXPECT_EQ(at.size(), expected_t.size()); for(int ii = 0; ii < expected_t.size(); ++ii){ - EXPECT_LT(fabs(at[ii] - expected_t[ii]), 1e-10); + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); } dp.compute(gt, ff, vv, coord, atype, box); EXPECT_EQ(gt.size(), expected_gt.size()); for(int ii = 0; ii < expected_gt.size(); ++ii){ - EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), 1e-10); + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); } EXPECT_EQ(ff.size(), expected_f.size()); for(int ii = 0; ii < expected_f.size(); ++ii){ - EXPECT_LT(fabs(ff[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(ff[ii] - expected_f[ii]), EPSILON); } EXPECT_EQ(vv.size(), expected_gv.size()); for(int ii = 0; ii < expected_gv.size(); ++ii){ - EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), 1e-10); + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); } dp.compute(gt, ff, vv, at, av, coord, atype, box); EXPECT_EQ(gt.size(), expected_gt.size()); for(int ii = 0; ii < expected_gt.size(); ++ii){ - EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), 1e-10); + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); } EXPECT_EQ(ff.size(), expected_f.size()); for(int ii = 0; ii < expected_f.size(); ++ii){ - EXPECT_LT(fabs(ff[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(ff[ii] - expected_f[ii]), EPSILON); } EXPECT_EQ(vv.size(), expected_gv.size()); for(int ii = 0; ii < expected_gv.size(); ++ii){ - EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), 1e-10); + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); } EXPECT_EQ(at.size(), expected_t.size()); for(int ii = 0; ii < expected_t.size(); ++ii){ - EXPECT_LT(fabs(at[ii] - expected_t[ii]), 1e-10); + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); } EXPECT_EQ(av.size(), expected_v.size()); for(int ii = 0; ii < expected_v.size(); ++ii){ - EXPECT_LT(fabs(av[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(av[ii] - expected_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPolarNew, cpu_lmp_nlist) +TYPED_TEST(TestInferDeepPolarNew, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_t = this->expected_t; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + std::vector& expected_gt = this->expected_gt; + std::vector& expected_gv = this->expected_gv; + int& natoms = this->natoms; + int& nsel = this->nsel; + int& odim = this->odim; + deepmd::DeepTensor& dp = this->dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector ilist(nloc), numneigh(nloc); std::vector firstneigh(nloc); std::vector > nlist_data; deepmd::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; convert_nlist(inlist, nlist_data); - std::vector gt, ff, vv, at, av; + std::vector gt, ff, vv, at, av; dp.compute(at, coord_cpy, atype_cpy, box, nall-nloc, inlist); EXPECT_EQ(at.size(), expected_t.size()); for(int ii = 0; ii < expected_t.size(); ++ii){ - EXPECT_LT(fabs(at[ii] - expected_t[ii]), 1e-10); + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); } @@ -241,21 +285,21 @@ TEST_F(TestInferDeepPolarNew, cpu_lmp_nlist) EXPECT_EQ(gt.size(), expected_gt.size()); for(int ii = 0; ii < expected_gt.size(); ++ii){ - EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), 1e-10); + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); } // remove ghost atoms - std::vector rff (odim * nloc * 3); + std::vector rff (odim * nloc * 3); for(int kk = 0; kk < odim; ++kk){ - _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); + _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); } EXPECT_EQ(rff.size(), expected_f.size()); for(int ii = 0; ii < expected_f.size(); ++ii){ - EXPECT_LT(fabs(rff[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(rff[ii] - expected_f[ii]), EPSILON); } // virial EXPECT_EQ(vv.size(), expected_gv.size()); for(int ii = 0; ii < expected_gv.size(); ++ii){ - EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), 1e-10); + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); } @@ -263,34 +307,34 @@ TEST_F(TestInferDeepPolarNew, cpu_lmp_nlist) EXPECT_EQ(gt.size(), expected_gt.size()); for(int ii = 0; ii < expected_gt.size(); ++ii){ - EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), 1e-10); + EXPECT_LT(fabs(gt[ii] - expected_gt[ii]), EPSILON); } // remove ghost atoms for(int kk = 0; kk < odim; ++kk){ - _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); + _fold_back(rff.begin() + kk * nloc * 3, ff.begin() + kk * nall * 3, mapping, nloc, nall, 3); } EXPECT_EQ(rff.size(), expected_f.size()); for(int ii = 0; ii < expected_f.size(); ++ii){ - EXPECT_LT(fabs(rff[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(rff[ii] - expected_f[ii]), EPSILON); } // virial EXPECT_EQ(vv.size(), expected_gv.size()); for(int ii = 0; ii < expected_gv.size(); ++ii){ - EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), 1e-10); + EXPECT_LT(fabs(vv[ii] - expected_gv[ii]), EPSILON); } // atom tensor EXPECT_EQ(at.size(), expected_t.size()); for(int ii = 0; ii < expected_t.size(); ++ii){ - EXPECT_LT(fabs(at[ii] - expected_t[ii]), 1e-10); + EXPECT_LT(fabs(at[ii] - expected_t[ii]), EPSILON); } // atom virial - std::vector rav (odim * nloc * 9); + std::vector rav (odim * nloc * 9); for(int kk = 0; kk < odim; ++kk){ - _fold_back(rav.begin() + kk * nloc * 9, av.begin() + kk * nall * 9, mapping, nloc, nall, 9); + _fold_back(rav.begin() + kk * nloc * 9, av.begin() + kk * nall * 9, mapping, nloc, nall, 9); } EXPECT_EQ(rav.size(), expected_v.size()); for(int ii = 0; ii < expected_v.size(); ++ii){ - EXPECT_LT(fabs(rav[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(rav[ii] - expected_v[ii]), EPSILON); } } diff --git a/source/api_cc/tests/test_deeppot_a.cc b/source/api_cc/tests/test_deeppot_a.cc index d8082972f8..abf6a384b9 100644 --- a/source/api_cc/tests/test_deeppot_a.cc +++ b/source/api_cc/tests/test_deeppot_a.cc @@ -11,10 +11,11 @@ #include #include +template class TestInferDeepPotA : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -25,21 +26,21 @@ class TestInferDeepPotA : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = { + std::vector box = { 13., 0., 0., 0., 13., 0., 0., 0., 13. }; - std::vector expected_e = { + std::vector expected_e = { -9.275780747115504710e+01,-1.863501786584258468e+02,-1.863392472863538103e+02,-9.279281325486221021e+01,-1.863671545232153903e+02,-1.863619822847602165e+02 }; - std::vector expected_f = { + std::vector expected_f = { -3.034045420701179663e-01,8.405844663871177014e-01,7.696947487118485642e-02,7.662001266663505117e-01,-1.880601391333554251e-01,-6.183333871091722944e-01,-5.036172391059643427e-01,-6.529525836149027151e-01,5.432962643022043459e-01,6.382357912332115024e-01,-1.748518296794561167e-01,3.457363524891907125e-01,1.286482986991941552e-03,3.757251165286925043e-01,-5.972588700887541124e-01,-5.987006197104716154e-01,-2.004450304880958100e-01,2.495901655353461868e-01 }; - std::vector expected_v = { + std::vector expected_v = { -2.912234126853306959e-01,-3.800610846612756388e-02,2.776624987489437202e-01,-5.053761003913598976e-02,-3.152373041953385746e-01,1.060894290092162379e-01,2.826389131596073745e-01,1.039129970665329250e-01,-2.584378792325942586e-01,-3.121722367954994914e-01,8.483275876786681990e-02,2.524662342344257682e-01,4.142176771106586414e-02,-3.820285230785245428e-02,-2.727311173065460545e-02,2.668859789777112135e-01,-6.448243569420382404e-02,-2.121731470426218846e-01,-8.624335220278558922e-02,-1.809695356746038597e-01,1.529875294531883312e-01,-1.283658185172031341e-01,-1.992682279795223999e-01,1.409924999632362341e-01,1.398322735274434292e-01,1.804318474574856390e-01,-1.470309318999652726e-01,-2.593983661598450730e-01,-4.236536279233147489e-02,3.386387920184946720e-02,-4.174017537818433543e-02,-1.003500282164128260e-01,1.525690815194478966e-01,3.398976109910181037e-02,1.522253908435125536e-01,-2.349125581341701963e-01,9.515545977581392825e-04,-1.643218849228543846e-02,1.993234765412972564e-02,6.027265332209678569e-04,-9.563256398907417355e-02,1.510815124001868293e-01,-7.738094816888557714e-03,1.502832772532304295e-01,-2.380965783745832010e-01,-2.309456719810296654e-01,-6.666961081213038098e-02,7.955566551234216632e-02,-8.099093777937517447e-02,-3.386641099800401927e-02,4.447884755740908608e-02,1.008593228579038742e-01,4.556718179228393811e-02,-6.078081273849572641e-02 }; int natoms; double expected_tot_e; - std::vectorexpected_tot_v; + std::vectorexpected_tot_v; deepmd::DeepPot dp; @@ -70,27 +71,51 @@ class TestInferDeepPotA : public ::testing::Test }; }; -TEST_F(TestInferDeepPotA, cpu_build_nlist) +TYPED_TEST_SUITE(TestInferDeepPotA, ValueTypes); + +TYPED_TEST(TestInferDeepPotA, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; double ener; - std::vector force, virial; + std::vector force, virial; dp.compute(ener, force, virial, coord, atype, box); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotA, cpu_build_nlist_numfv) +TYPED_TEST(TestInferDeepPotA, cpu_build_nlist_numfv) { - class MyModel : public EnergyModelTest + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; + class MyModel : public EnergyModelTest { deepmd::DeepPot & mydp; const std::vector atype; @@ -101,17 +126,17 @@ TEST_F(TestInferDeepPotA, cpu_build_nlist_numfv) ) : mydp(dp_), atype(atype_) {}; virtual void compute ( double & ener, - std::vector & force, - std::vector & virial, - const std::vector & coord, - const std::vector & box) { + std::vector & force, + std::vector & virial, + const std::vector & coord, + const std::vector & box) { mydp.compute(ener, force, virial, coord, atype, box); } }; MyModel model(dp, atype); model.test_f(coord, box); model.test_v(coord, box); - std::vector box_(box); + std::vector box_(box); box_[1] -= 0.4; model.test_f(coord, box_); model.test_v(coord, box_); @@ -133,10 +158,21 @@ TEST_F(TestInferDeepPotA, cpu_build_nlist_numfv) } -TEST_F(TestInferDeepPotA, cpu_build_nlist_atomic) +TYPED_TEST(TestInferDeepPotA, cpu_build_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; double ener; - std::vector force, virial, atom_ener, atom_vir; + std::vector force, virial, atom_ener, atom_vir; dp.compute(ener, force, virial, atom_ener, atom_vir, coord, atype, box); EXPECT_EQ(force.size(), natoms*3); @@ -144,30 +180,41 @@ TEST_F(TestInferDeepPotA, cpu_build_nlist_atomic) EXPECT_EQ(atom_ener.size(), natoms); EXPECT_EQ(atom_vir.size(), natoms*9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } for(int ii = 0; ii < natoms; ++ii){ - EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), 1e-10); + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); } for(int ii = 0; ii < natoms*9; ++ii){ - EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotA, cpu_lmp_nlist) +TYPED_TEST(TestInferDeepPotA, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -176,49 +223,60 @@ TEST_F(TestInferDeepPotA, cpu_lmp_nlist) convert_nlist(inlist, nlist_data); double ener; - std::vector force_, virial; + std::vector force_, virial; dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); - std::vector force; - _fold_back(force, force_, mapping, nloc, nall, 3); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } ener = 0.; std::fill(force_.begin(), force_.end(), 0.0); std::fill(virial.begin(), virial.end(), 0.0); dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 1); - _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotA, cpu_lmp_nlist_atomic) +TYPED_TEST(TestInferDeepPotA, cpu_lmp_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -227,30 +285,30 @@ TEST_F(TestInferDeepPotA, cpu_lmp_nlist_atomic) convert_nlist(inlist, nlist_data); double ener; - std::vector force_, atom_ener_, atom_vir_, virial; - std::vector force, atom_ener, atom_vir; + std::vector force_, atom_ener_, atom_vir_, virial; + std::vector force, atom_ener, atom_vir; dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); - _fold_back(force, force_, mapping, nloc, nall, 3); - _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); - _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); + _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); EXPECT_EQ(atom_ener.size(), natoms); EXPECT_EQ(atom_vir.size(), natoms*9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } for(int ii = 0; ii < natoms; ++ii){ - EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), 1e-10); + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); } for(int ii = 0; ii < natoms*9; ++ii){ - EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); } ener = 0.; @@ -259,39 +317,50 @@ TEST_F(TestInferDeepPotA, cpu_lmp_nlist_atomic) std::fill(atom_ener_.begin(), atom_ener_.end(), 0.0); std::fill(atom_vir_.begin(), atom_vir_.end(), 0.0); dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 1); - _fold_back(force, force_, mapping, nloc, nall, 3); - _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); - _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); + _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); EXPECT_EQ(atom_ener.size(), natoms); EXPECT_EQ(atom_vir.size(), natoms*9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } for(int ii = 0; ii < natoms; ++ii){ - EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), 1e-10); + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); } for(int ii = 0; ii < natoms*9; ++ii){ - EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotA, cpu_lmp_nlist_2rc) +TYPED_TEST(TestInferDeepPotA, cpu_lmp_nlist_2rc) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc*2); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -300,48 +369,59 @@ TEST_F(TestInferDeepPotA, cpu_lmp_nlist_2rc) convert_nlist(inlist, nlist_data); double ener; - std::vector force_(nall*3, 0.0), virial(9, 0.0); + std::vector force_(nall*3, 0.0), virial(9, 0.0); dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); - std::vector force; - _fold_back(force, force_, mapping, nloc, nall, 3); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } ener = 0.; std::fill(force_.begin(), force_.end(), 0.0); std::fill(virial.begin(), virial.end(), 0.0); dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 1); - _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotA, cpu_lmp_nlist_type_sel) +TYPED_TEST(TestInferDeepPotA, cpu_lmp_nlist_type_sel) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; float rc = dp.cutoff(); // add vir atoms int nvir = 2; - std::vector coord_vir(nvir*3); + std::vector coord_vir(nvir*3); std::vector atype_vir(nvir, 2); for(int ii = 0; ii < nvir; ++ii){ coord_vir[ii] = coord[ii]; @@ -349,15 +429,15 @@ TEST_F(TestInferDeepPotA, cpu_lmp_nlist_type_sel) coord.insert(coord.begin(), coord_vir.begin(), coord_vir.end()); atype.insert(atype.begin(), atype_vir.begin(), atype_vir.end()); natoms += nvir; - std::vector expected_f_vir(nvir*3, 0.0); + std::vector expected_f_vir(nvir*3, 0.0); expected_f.insert(expected_f.begin(), expected_f_vir.begin(), expected_f_vir.end()); // build nlist int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -367,30 +447,92 @@ TEST_F(TestInferDeepPotA, cpu_lmp_nlist_type_sel) // dp compute double ener; - std::vector force_(nall*3, 0.0), virial(9, 0.0); + std::vector force_(nall*3, 0.0), virial(9, 0.0); dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); // fold back - std::vector force; - _fold_back(force, force_, mapping, nloc, nall, 3); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } +TYPED_TEST(TestInferDeepPotA, cpu_lmp_nlist_type_sel_atomic) +{ + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; + float rc = dp.cutoff(); + + // add vir atoms + int nvir = 2; + std::vector coord_vir(nvir*3); + std::vector atype_vir(nvir, 2); + for(int ii = 0; ii < nvir; ++ii){ + coord_vir[ii] = coord[ii]; + } + coord.insert(coord.begin(), coord_vir.begin(), coord_vir.end()); + atype.insert(atype.begin(), atype_vir.begin(), atype_vir.end()); + natoms += nvir; + std::vector expected_f_vir(nvir*3, 0.0); + expected_f.insert(expected_f.begin(), expected_f_vir.begin(), expected_f_vir.end()); + + // build nlist + int nloc = coord.size() / 3; + std::vector coord_cpy; + std::vector atype_cpy, mapping; + std::vector > nlist_data; + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + coord, atype, box, rc); + int nall = coord_cpy.size() / 3; + std::vector ilist(nloc), numneigh(nloc); + std::vector firstneigh(nloc); + deepmd::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); + convert_nlist(inlist, nlist_data); + + // dp compute + double ener; + std::vector force_(nall*3, 0.0), virial(9, 0.0), atomic_energy, atomic_virial; + dp.compute(ener, force_, virial, atomic_energy, atomic_virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); + // fold back + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); + + EXPECT_EQ(force.size(), natoms*3); + EXPECT_EQ(virial.size(), 9); + + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); + for(int ii = 0; ii < natoms*3; ++ii){ + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); + } + for(int ii = 0; ii < 3*3; ++ii){ + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); + } +} + +template class TestInferDeepPotANoPbc : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -401,19 +543,19 @@ class TestInferDeepPotANoPbc : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = {}; - std::vector expected_e = { + std::vector box = {}; + std::vector expected_e = { -9.255934839310273787e+01,-1.863253376736990106e+02,-1.857237299341402945e+02,-9.279308539717486326e+01,-1.863708105823244239e+02,-1.863635196514972563e+02 }; - std::vector expected_f = { + std::vector expected_f = { -2.161037360255332107e+00,9.052994347015581589e-01,1.635379623977007979e+00,2.161037360255332107e+00,-9.052994347015581589e-01,-1.635379623977007979e+00,-1.167128117249453811e-02,1.371975700096064992e-03,-1.575265180249604477e-03,6.226508593971802341e-01,-1.816734122009256991e-01,3.561766019664774907e-01,-1.406075393906316626e-02,3.789140061530929526e-01,-6.018777878642909140e-01,-5.969188242856223736e-01,-1.986125696522633155e-01,2.472764510780630642e-01 }; - std::vector expected_v = { + std::vector expected_v = { -7.042445481792056761e-01,2.950213647777754078e-01,5.329418202437231633e-01,2.950213647777752968e-01,-1.235900311906896754e-01,-2.232594111831812944e-01,5.329418202437232743e-01,-2.232594111831813499e-01,-4.033073234276823849e-01,-8.949230984097404917e-01,3.749002169013777030e-01,6.772391014992630298e-01,3.749002169013777586e-01,-1.570527935667933583e-01,-2.837082722496912512e-01,6.772391014992631408e-01,-2.837082722496912512e-01,-5.125052659994422388e-01,4.858210330291591605e-02,-6.902596153269104431e-03,6.682612642430500391e-03,-5.612247004554610057e-03,9.767795567660207592e-04,-9.773758942738038254e-04,5.638322117219018645e-03,-9.483806049779926932e-04,8.493873281881353637e-04,-2.941738570564985666e-01,-4.482529909499673171e-02,4.091569840186781021e-02,-4.509020615859140463e-02,-1.013919988807244071e-01,1.551440772665269030e-01,4.181857726606644232e-02,1.547200233064863484e-01,-2.398213304685777592e-01,-3.218625798524068354e-02,-1.012438450438508421e-02,1.271639330380921855e-02,3.072814938490859779e-03,-9.556241797915024372e-02,1.512251983492413077e-01,-8.277872384009607454e-03,1.505412040827929787e-01,-2.386150620881526407e-01,-2.312295470054945568e-01,-6.631490213524345034e-02,7.932427266386249398e-02,-8.053754366323923053e-02,-3.294595881137418747e-02,4.342495071150231922e-02,1.004599500126941436e-01,4.450400364869536163e-02,-5.951077548033092968e-02 }; int natoms; double expected_tot_e; - std::vectorexpected_tot_v; + std::vectorexpected_tot_v; deepmd::DeepPot dp; @@ -444,20 +586,33 @@ class TestInferDeepPotANoPbc : public ::testing::Test }; }; -TEST_F(TestInferDeepPotANoPbc, cpu_build_nlist) +TYPED_TEST_SUITE(TestInferDeepPotANoPbc, ValueTypes); + +TYPED_TEST(TestInferDeepPotANoPbc, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; double ener; - std::vector force, virial; + std::vector force, virial; dp.compute(ener, force, virial, coord, atype, box); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } diff --git a/source/api_cc/tests/test_deeppot_model_devi.cc b/source/api_cc/tests/test_deeppot_model_devi.cc index 2b532f098e..ed33f8ae05 100644 --- a/source/api_cc/tests/test_deeppot_model_devi.cc +++ b/source/api_cc/tests/test_deeppot_model_devi.cc @@ -11,10 +11,11 @@ #include #include +template class TestInferDeepPotModeDevi : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -25,7 +26,7 @@ class TestInferDeepPotModeDevi : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = { + std::vector box = { 13., 0., 0., 0., 13., 0., 0., 0., 13. }; int natoms; @@ -54,11 +55,13 @@ class TestInferDeepPotModeDevi : public ::testing::Test }; }; +TYPED_TEST_SUITE(TestInferDeepPotModeDevi, ValueTypes); +template class TestInferDeepPotModeDeviPython : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 4.170220047025740423e-02,7.203244934421580703e-02,1.000114374817344942e-01, 4.053881673400336005e+00,4.191945144032948461e-02,6.852195003967595510e-02, 1.130233257263184132e+00,1.467558908171130543e-02,1.092338594768797883e-01, @@ -69,14 +72,14 @@ class TestInferDeepPotModeDeviPython : public ::testing::Test std::vector atype = { 0, 0, 1, 1, 1, 1 }; - std::vector box = { + std::vector box = { 20., 0., 0., 0., 20., 0., 0., 0., 20. }; int natoms; - std::vector expected_md_f = { + std::vector expected_md_f = { 0.509504727653, 0.458424067748, 0.481978258466 }; // max min avg - std::vector expected_md_v = { + std::vector expected_md_v = { 0.167004837423,0.00041822790564,0.0804864867641 }; // max min avg @@ -104,9 +107,19 @@ class TestInferDeepPotModeDeviPython : public ::testing::Test }; }; +TYPED_TEST_SUITE(TestInferDeepPotModeDeviPython, ValueTypes); -TEST_F(TestInferDeepPotModeDevi, attrs) + +TYPED_TEST(TestInferDeepPotModeDevi, attrs) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + int& natoms = this->natoms; + deepmd::DeepPot& dp0 = this->dp0; + deepmd::DeepPot& dp1 = this->dp1; + deepmd::DeepPotModelDevi& dp_md = this->dp_md; EXPECT_EQ(dp0.cutoff(), dp_md.cutoff()); EXPECT_EQ(dp0.numb_types(), dp_md.numb_types()); EXPECT_EQ(dp0.dim_fparam(), dp_md.dim_fparam()); @@ -117,14 +130,22 @@ TEST_F(TestInferDeepPotModeDevi, attrs) EXPECT_EQ(dp1.dim_aparam(), dp_md.dim_aparam()); } -TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list) +TYPED_TEST(TestInferDeepPotModeDevi, cpu_lmp_list) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + int& natoms = this->natoms; + deepmd::DeepPot& dp0 = this->dp0; + deepmd::DeepPot& dp1 = this->dp1; + deepmd::DeepPotModelDevi& dp_md = this->dp_md; float rc = dp_md.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -134,13 +155,13 @@ TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list) int nmodel = 2; std::vector edir(nmodel), emd; - std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd; + std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd; dp0.compute(edir[0], fdir_[0], vdir[0], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); dp1.compute(edir[1], fdir_[1], vdir[1], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); dp_md.compute(emd, fmd_, vmd, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); for(int kk = 0; kk < nmodel; ++kk){ - _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); - _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); + _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); + _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); } EXPECT_EQ(edir.size(), emd.size()); @@ -151,25 +172,33 @@ TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list) EXPECT_EQ(vdir[kk].size(), vmd[kk].size()); } for(int kk = 0; kk < nmodel; ++kk){ - EXPECT_LT(fabs(edir[kk] - emd[kk]), 1e-10); + EXPECT_LT(fabs(edir[kk] - emd[kk]), EPSILON); for(int ii = 0; ii < fdir[0].size(); ++ii){ - EXPECT_LT(fabs(fdir[kk][ii] - fmd[kk][ii]), 1e-10); + EXPECT_LT(fabs(fdir[kk][ii] - fmd[kk][ii]), EPSILON); } for(int ii = 0; ii < vdir[0].size(); ++ii){ - EXPECT_LT(fabs(vdir[kk][ii] - vmd[kk][ii]), 1e-10); + EXPECT_LT(fabs(vdir[kk][ii] - vmd[kk][ii]), EPSILON); } } } -TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list_atomic) +TYPED_TEST(TestInferDeepPotModeDevi, cpu_lmp_list_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + int& natoms = this->natoms; + deepmd::DeepPot& dp0 = this->dp0; + deepmd::DeepPot& dp1 = this->dp1; + deepmd::DeepPotModelDevi& dp_md = this->dp_md; float rc = dp_md.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -179,15 +208,15 @@ TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list_atomic) int nmodel = 2; std::vector edir(nmodel), emd; - std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd, aedir(nmodel), aemd, avdir(nmodel), avdir_(nmodel), avmd(nmodel), avmd_; + std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd, aedir(nmodel), aemd, avdir(nmodel), avdir_(nmodel), avmd(nmodel), avmd_; dp0.compute(edir[0], fdir_[0], vdir[0], aedir[0], avdir_[0], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); dp1.compute(edir[1], fdir_[1], vdir[1], aedir[1], avdir_[1], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); dp_md.compute(emd, fmd_, vmd, aemd, avmd_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); for(int kk = 0; kk < nmodel; ++kk){ - _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); - _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); - _fold_back(avdir[kk], avdir_[kk], mapping, nloc, nall, 9); - _fold_back(avmd[kk], avmd_[kk], mapping, nloc, nall, 9); + _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); + _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); + _fold_back(avdir[kk], avdir_[kk], mapping, nloc, nall, 9); + _fold_back(avmd[kk], avmd_[kk], mapping, nloc, nall, 9); } EXPECT_EQ(edir.size(), emd.size()); @@ -202,31 +231,39 @@ TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list_atomic) EXPECT_EQ(avdir[kk].size(), avmd[kk].size()); } for(int kk = 0; kk < nmodel; ++kk){ - EXPECT_LT(fabs(edir[kk] - emd[kk]), 1e-10); + EXPECT_LT(fabs(edir[kk] - emd[kk]), EPSILON); for(int ii = 0; ii < fdir[0].size(); ++ii){ - EXPECT_LT(fabs(fdir[kk][ii] - fmd[kk][ii]), 1e-10); + EXPECT_LT(fabs(fdir[kk][ii] - fmd[kk][ii]), EPSILON); } for(int ii = 0; ii < vdir[0].size(); ++ii){ - EXPECT_LT(fabs(vdir[kk][ii] - vmd[kk][ii]), 1e-10); + EXPECT_LT(fabs(vdir[kk][ii] - vmd[kk][ii]), EPSILON); } for(int ii = 0; ii < aedir[0].size(); ++ii){ - EXPECT_LT(fabs(aedir[kk][ii] - aemd[kk][ii]), 1e-10); + EXPECT_LT(fabs(aedir[kk][ii] - aemd[kk][ii]), EPSILON); } for(int ii = 0; ii < avdir[0].size(); ++ii){ - EXPECT_LT(fabs(avdir[kk][ii] - avmd[kk][ii]), 1e-10); + EXPECT_LT(fabs(avdir[kk][ii] - avmd[kk][ii]), EPSILON); } } } -TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list_std) +TYPED_TEST(TestInferDeepPotModeDevi, cpu_lmp_list_std) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + int& natoms = this->natoms; + deepmd::DeepPot& dp0 = this->dp0; + deepmd::DeepPot& dp1 = this->dp1; + deepmd::DeepPotModelDevi& dp_md = this->dp_md; float rc = dp_md.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -236,15 +273,15 @@ TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list_std) int nmodel = 2; std::vector edir(nmodel), emd; - std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd; - std::vector > aemd(nmodel), aemd_, avmd(nmodel), avmd_; + std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd; + std::vector > aemd(nmodel), aemd_, avmd(nmodel), avmd_; dp0.compute(edir[0], fdir_[0], vdir[0], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); dp1.compute(edir[1], fdir_[1], vdir[1], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); dp_md.compute(emd, fmd_, vmd, aemd_, avmd_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); for(int kk = 0; kk < nmodel; ++kk){ - _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); - _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); - _fold_back(avmd[kk], avmd_[kk], mapping, nloc, nall, 9); + _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); + _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); + _fold_back(avmd[kk], avmd_[kk], mapping, nloc, nall, 9); aemd[kk].resize(nloc); for(int ii = 0; ii < nloc; ++ii){ aemd[kk][ii] = aemd_[kk][ii]; @@ -252,7 +289,7 @@ TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list_std) } // dp compute std e - std::vector avg_e, std_e; + std::vector avg_e, std_e; dp_md.compute_avg(avg_e, aemd); dp_md.compute_std_e(std_e, avg_e, aemd); @@ -275,36 +312,36 @@ TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list_std) } EXPECT_EQ(manual_std_e.size(), std_e.size()); for(int ii = 0; ii < std_e.size(); ++ii){ - EXPECT_LT(fabs(manual_avg_e[ii] - avg_e[ii]), 1e-10); - EXPECT_LT(fabs(manual_std_e[ii] - std_e[ii]), 1e-10); + EXPECT_LT(fabs(manual_avg_e[ii] - avg_e[ii]), EPSILON); + EXPECT_LT(fabs(manual_std_e[ii] - std_e[ii]), EPSILON); } // dp compute std f - std::vector avg_f, std_f; + std::vector avg_f, std_f; dp_md.compute_avg(avg_f, fmd); dp_md.compute_std_f(std_f, avg_f, fmd); // manual compute std f - std::vector manual_std_f(nloc); - std::vector manual_rel_std_f(nloc); - double eps = 0.2; + std::vector manual_std_f(nloc); + std::vector manual_rel_std_f(nloc); + VALUETYPE eps = 0.2; EXPECT_EQ(fmd[0].size(), nloc * 3); for(int ii = 0; ii < nloc; ++ii){ - std::vector avg_f(3, 0.0); + std::vector avg_f(3, 0.0); for(int dd = 0; dd < 3; ++dd){ for(int kk = 0; kk < nmodel; ++kk){ avg_f[dd] += fmd[kk][ii*3+dd]; } avg_f[dd] /= (nmodel) * 1.0; } - double std = 0.; + VALUETYPE std = 0.; for(int kk = 0; kk < nmodel; ++kk){ for(int dd = 0; dd < 3; ++dd){ - double tmp = fmd[kk][ii*3+dd] - avg_f[dd]; + VALUETYPE tmp = fmd[kk][ii*3+dd] - avg_f[dd]; std += tmp * tmp; } } - double f_norm = 0; + VALUETYPE f_norm = 0; for (int dd = 0; dd < 3; ++dd){ f_norm += avg_f[dd] * avg_f[dd]; } @@ -316,18 +353,19 @@ TEST_F(TestInferDeepPotModeDevi, cpu_lmp_list_std) EXPECT_EQ(manual_std_f.size(), std_f.size()); for(int ii = 0; ii < std_f.size(); ++ii){ - EXPECT_LT(fabs(manual_std_f[ii] - std_f[ii]), 1e-10); + EXPECT_LT(fabs(manual_std_f[ii] - std_f[ii]), EPSILON); } dp_md.compute_relative_std_f(std_f, avg_f, eps); EXPECT_EQ(manual_std_f.size(), std_f.size()); for(int ii = 0; ii < std_f.size(); ++ii){ - EXPECT_LT(fabs(manual_rel_std_f[ii] - std_f[ii]), 1e-10); + EXPECT_LT(fabs(manual_rel_std_f[ii] - std_f[ii]), EPSILON); } } -inline double mymax(const std::vector & xx) +template +inline VALUETYPE mymax(const std::vector & xx) { - double ret = 0; + VALUETYPE ret = 0; for (int ii = 0; ii < xx.size(); ++ii){ if (xx[ii] > ret) { ret = xx[ii]; @@ -335,9 +373,10 @@ inline double mymax(const std::vector & xx) } return ret; }; -inline double mymin(const std::vector & xx) +template +inline VALUETYPE mymin(const std::vector & xx) { - double ret = 1e10; + VALUETYPE ret = 1e10; for (int ii = 0; ii < xx.size(); ++ii){ if (xx[ii] < ret) { ret = xx[ii]; @@ -345,31 +384,43 @@ inline double mymin(const std::vector & xx) } return ret; }; -inline double myavg(const std::vector & xx) +template +inline VALUETYPE myavg(const std::vector & xx) { - double ret = 0; + VALUETYPE ret = 0; for (int ii = 0; ii < xx.size(); ++ii){ ret += xx[ii]; } return (ret / xx.size()); }; -inline double mystd(const std::vector & xx) +template +inline VALUETYPE mystd(const std::vector & xx) { - double ret = 0; + VALUETYPE ret = 0; for (int ii = 0; ii < xx.size(); ++ii){ ret += xx[ii] * xx[ii]; } return sqrt(ret / xx.size()); }; -TEST_F(TestInferDeepPotModeDeviPython, cpu_lmp_list_std) +TYPED_TEST(TestInferDeepPotModeDeviPython, cpu_lmp_list_std) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + int& natoms = this->natoms; + deepmd::DeepPot& dp0 = this->dp0; + deepmd::DeepPot& dp1 = this->dp1; + deepmd::DeepPotModelDevi& dp_md = this->dp_md; + std::vector& expected_md_f = this->expected_md_f; + std::vector& expected_md_v = this->expected_md_v; float rc = dp_md.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -379,15 +430,15 @@ TEST_F(TestInferDeepPotModeDeviPython, cpu_lmp_list_std) int nmodel = 2; std::vector edir(nmodel), emd; - std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd; - std::vector > aemd(nmodel), aemd_, avmd(nmodel), avmd_; + std::vector > fdir_(nmodel), fdir(nmodel), vdir(nmodel), fmd_, fmd(nmodel), vmd; + std::vector > aemd(nmodel), aemd_, avmd(nmodel), avmd_; dp0.compute(edir[0], fdir_[0], vdir[0], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); dp1.compute(edir[1], fdir_[1], vdir[1], coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); dp_md.compute(emd, fmd_, vmd, aemd_, avmd_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); for(int kk = 0; kk < nmodel; ++kk){ - _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); - _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); - _fold_back(avmd[kk], avmd_[kk], mapping, nloc, nall, 9); + _fold_back(fdir[kk], fdir_[kk], mapping, nloc, nall, 3); + _fold_back(fmd[kk], fmd_[kk], mapping, nloc, nall, 3); + _fold_back(avmd[kk], avmd_[kk], mapping, nloc, nall, 9); aemd[kk].resize(nloc); for(int ii = 0; ii < nloc; ++ii){ aemd[kk][ii] = aemd_[kk][ii]; @@ -395,29 +446,29 @@ TEST_F(TestInferDeepPotModeDeviPython, cpu_lmp_list_std) } // dp compute std e - std::vector avg_e, std_e; + std::vector avg_e, std_e; dp_md.compute_avg(avg_e, aemd); dp_md.compute_std_e(std_e, avg_e, aemd); // dp compute std f - std::vector avg_f, std_f; + std::vector avg_f, std_f; dp_md.compute_avg(avg_f, fmd); dp_md.compute_std_f(std_f, avg_f, fmd); - EXPECT_LT(fabs(mymax(std_f) - expected_md_f[0]), 1e-10); - EXPECT_LT(fabs(mymin(std_f) - expected_md_f[1]), 1e-10); - EXPECT_LT(fabs(myavg(std_f) - expected_md_f[2]), 1e-10); + EXPECT_LT(fabs(mymax(std_f) - expected_md_f[0]), EPSILON); + EXPECT_LT(fabs(mymin(std_f) - expected_md_f[1]), EPSILON); + EXPECT_LT(fabs(myavg(std_f) - expected_md_f[2]), EPSILON); // dp compute std v // we normalize v by number of atoms for (int ii = 0; ii < vmd.size(); ++ii){ for(int jj = 0; jj < vmd[ii].size(); ++jj){ - vmd[ii][jj] /= double(atype.size()); + vmd[ii][jj] /= VALUETYPE(atype.size()); } } - std::vector avg_v, std_v; + std::vector avg_v, std_v; dp_md.compute_avg(avg_v, vmd); dp_md.compute_std(std_v, avg_v, vmd, 1); - EXPECT_LT(fabs(mymax(std_v) - expected_md_v[0]), 1e-10); - EXPECT_LT(fabs(mymin(std_v) - expected_md_v[1]), 1e-10); - EXPECT_LT(fabs(mystd(std_v) - expected_md_v[2]), 1e-10); + EXPECT_LT(fabs(mymax(std_v) - expected_md_v[0]), EPSILON); + EXPECT_LT(fabs(mymin(std_v) - expected_md_v[1]), EPSILON); + EXPECT_LT(fabs(mystd(std_v) - expected_md_v[2]), EPSILON); } diff --git a/source/api_cc/tests/test_deeppot_r.cc b/source/api_cc/tests/test_deeppot_r.cc index 3bd34f398c..55189f4701 100644 --- a/source/api_cc/tests/test_deeppot_r.cc +++ b/source/api_cc/tests/test_deeppot_r.cc @@ -11,10 +11,11 @@ #include #include +template class TestInferDeepPotR : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -25,21 +26,21 @@ class TestInferDeepPotR : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = { + std::vector box = { 13., 0., 0., 0., 13., 0., 0., 0., 13. }; - std::vector expected_e = { + std::vector expected_e = { -9.320909762801588272e+01,-1.868020345400987878e+02,-1.868011172371355997e+02,-9.320868430396934912e+01,-1.868010398844378415e+02,-1.868016706555875999e+02 }; - std::vector expected_f = { + std::vector expected_f = { 6.385312846474267391e-04,-6.460452911141417731e-03,-5.652405655332678417e-04,-7.516468794343579736e-03,1.128804614240160216e-03,5.531937784564192051e-03,1.914138124904981664e-03,5.601819906021693503e-03,-5.131359585752605541e-03,-4.847104424804288617e-03,1.992071550328819614e-03,-4.028159855157302516e-03,1.236340684486603517e-03,-5.373955841338794344e-03,8.312829460571366513e-03,8.574563125108854156e-03,3.111712681889538742e-03,-4.120007238692381148e-03 }; - std::vector expected_v = { + std::vector expected_v = { 5.844056241889131371e-03,4.663973497239899614e-04,-2.268382127762904633e-03,4.663973497239897988e-04,2.349338784202595950e-03,-6.908546513234039253e-04,-2.268382127762904633e-03,-6.908546513234039253e-04,2.040499248150800561e-03,4.238130266437327605e-03,-1.539867187443782223e-04,-2.393101333240631613e-03,-1.539867187443782223e-04,4.410341945447907377e-04,9.544239698119633068e-06,-2.393101333240631613e-03,9.544239698119578858e-06,1.877785959095269654e-03,5.798992562057291543e-03,6.943392552230453693e-04,-1.180376879311998773e-03,6.943392552230453693e-04,1.686725132156275536e-03,-1.461632060145726542e-03,-1.180376879311998556e-03,-1.461632060145726325e-03,1.749543733794208444e-03,7.173915604192910439e-03,3.903218041111061569e-04,-5.747400467123527524e-04,3.903218041111061569e-04,1.208289706621179949e-03,-1.826828914132010932e-03,-5.747400467123527524e-04,-1.826828914132011148e-03,2.856960586657185906e-03,4.067553030177322240e-03,-3.267469855253819430e-05,-6.980667859103454904e-05,-3.267469855253830272e-05,1.387653029234650918e-03,-2.096820720698671855e-03,-6.980667859103444062e-05,-2.096820720698671855e-03,3.218305506720191278e-03,4.753992590355240674e-03,1.224911338353675992e-03,-1.683421934571502484e-03,1.224911338353676209e-03,7.332113564901583539e-04,-1.025577052190138451e-03,-1.683421934571502484e-03,-1.025577052190138234e-03,1.456681925652047018e-03 }; int natoms; double expected_tot_e; - std::vectorexpected_tot_v; + std::vectorexpected_tot_v; deepmd::DeepPot dp; @@ -70,28 +71,51 @@ class TestInferDeepPotR : public ::testing::Test }; }; +TYPED_TEST_SUITE(TestInferDeepPotR, ValueTypes); -TEST_F(TestInferDeepPotR, cpu_build_nlist) +TYPED_TEST(TestInferDeepPotR, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; double ener; - std::vector force, virial; + std::vector force, virial; dp.compute(ener, force, virial, coord, atype, box); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotR, cpu_build_nlist_numfv) +TYPED_TEST(TestInferDeepPotR, cpu_build_nlist_numfv) { - class MyModel : public EnergyModelTest + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; + class MyModel : public EnergyModelTest { deepmd::DeepPot & mydp; const std::vector & atype; @@ -102,17 +126,17 @@ TEST_F(TestInferDeepPotR, cpu_build_nlist_numfv) ) : mydp(dp_), atype(atype_) {}; virtual void compute ( double & ener, - std::vector & force, - std::vector & virial, - const std::vector & coord, - const std::vector & box) { + std::vector & force, + std::vector & virial, + const std::vector & coord, + const std::vector & box) { mydp.compute(ener, force, virial, coord, atype, box); } }; MyModel model(dp, atype); model.test_f(coord, box); model.test_v(coord, box); - std::vector box_(box); + std::vector box_(box); box_[1] -= 0.4; model.test_f(coord, box_); model.test_v(coord, box_); @@ -133,10 +157,21 @@ TEST_F(TestInferDeepPotR, cpu_build_nlist_numfv) model.test_v(coord, box_); } -TEST_F(TestInferDeepPotR, cpu_build_nlist_atomic) +TYPED_TEST(TestInferDeepPotR, cpu_build_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; double ener; - std::vector force, virial, atom_ener, atom_vir; + std::vector force, virial, atom_ener, atom_vir; dp.compute(ener, force, virial, atom_ener, atom_vir, coord, atype, box); EXPECT_EQ(force.size(), natoms*3); @@ -144,30 +179,41 @@ TEST_F(TestInferDeepPotR, cpu_build_nlist_atomic) EXPECT_EQ(atom_ener.size(), natoms); EXPECT_EQ(atom_vir.size(), natoms*9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } for(int ii = 0; ii < natoms; ++ii){ - EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), 1e-10); + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); } for(int ii = 0; ii < natoms*9; ++ii){ - EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotR, cpu_lmp_nlist) +TYPED_TEST(TestInferDeepPotR, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -176,49 +222,60 @@ TEST_F(TestInferDeepPotR, cpu_lmp_nlist) convert_nlist(inlist, nlist_data); double ener; - std::vector force_, virial; + std::vector force_, virial; dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); - std::vector force; - _fold_back(force, force_, mapping, nloc, nall, 3); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } ener = 0.; std::fill(force_.begin(), force_.end(), 0.0); std::fill(virial.begin(), virial.end(), 0.0); dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 1); - _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotR, cpu_lmp_nlist_atomic) +TYPED_TEST(TestInferDeepPotR, cpu_lmp_nlist_atomic) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -227,30 +284,30 @@ TEST_F(TestInferDeepPotR, cpu_lmp_nlist_atomic) convert_nlist(inlist, nlist_data); double ener; - std::vector force_, atom_ener_, atom_vir_, virial; - std::vector force, atom_ener, atom_vir; + std::vector force_, atom_ener_, atom_vir_, virial; + std::vector force, atom_ener, atom_vir; dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); - _fold_back(force, force_, mapping, nloc, nall, 3); - _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); - _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); + _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); EXPECT_EQ(atom_ener.size(), natoms); EXPECT_EQ(atom_vir.size(), natoms*9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } for(int ii = 0; ii < natoms; ++ii){ - EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), 1e-10); + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); } for(int ii = 0; ii < natoms*9; ++ii){ - EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); } ener = 0.; @@ -259,39 +316,50 @@ TEST_F(TestInferDeepPotR, cpu_lmp_nlist_atomic) std::fill(atom_ener_.begin(), atom_ener_.end(), 0.0); std::fill(atom_vir_.begin(), atom_vir_.end(), 0.0); dp.compute(ener, force_, virial, atom_ener_, atom_vir_, coord_cpy, atype_cpy, box, nall-nloc, inlist, 1); - _fold_back(force, force_, mapping, nloc, nall, 3); - _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); - _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); + _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(atom_ener, atom_ener_, mapping, nloc, nall, 1); + _fold_back(atom_vir, atom_vir_, mapping, nloc, nall, 9); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); EXPECT_EQ(atom_ener.size(), natoms); EXPECT_EQ(atom_vir.size(), natoms*9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } for(int ii = 0; ii < natoms; ++ii){ - EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), 1e-10); + EXPECT_LT(fabs(atom_ener[ii] - expected_e[ii]), EPSILON); } for(int ii = 0; ii < natoms*9; ++ii){ - EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), 1e-10); + EXPECT_LT(fabs(atom_vir[ii] - expected_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotR, cpu_lmp_nlist_2rc) +TYPED_TEST(TestInferDeepPotR, cpu_lmp_nlist_2rc) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; float rc = dp.cutoff(); int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc*2); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -300,48 +368,59 @@ TEST_F(TestInferDeepPotR, cpu_lmp_nlist_2rc) convert_nlist(inlist, nlist_data); double ener; - std::vector force_(nall*3, 0.0), virial(9, 0.0); + std::vector force_(nall*3, 0.0), virial(9, 0.0); dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); - std::vector force; - _fold_back(force, force_, mapping, nloc, nall, 3); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } ener = 0.; std::fill(force_.begin(), force_.end(), 0.0); std::fill(virial.begin(), virial.end(), 0.0); dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 1); - _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } -TEST_F(TestInferDeepPotR, cpu_lmp_nlist_type_sel) +TYPED_TEST(TestInferDeepPotR, cpu_lmp_nlist_type_sel) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; float rc = dp.cutoff(); // add vir atoms int nvir = 2; - std::vector coord_vir(nvir*3); + std::vector coord_vir(nvir*3); std::vector atype_vir(nvir, 2); for(int ii = 0; ii < nvir; ++ii){ coord_vir[ii] = coord[ii]; @@ -349,15 +428,15 @@ TEST_F(TestInferDeepPotR, cpu_lmp_nlist_type_sel) coord.insert(coord.begin(), coord_vir.begin(), coord_vir.end()); atype.insert(atype.begin(), atype_vir.begin(), atype_vir.end()); natoms += nvir; - std::vector expected_f_vir(nvir*3, 0.0); + std::vector expected_f_vir(nvir*3, 0.0); expected_f.insert(expected_f.begin(), expected_f_vir.begin(), expected_f_vir.end()); // build nlist int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; std::vector ilist(nloc), numneigh(nloc); @@ -367,30 +446,30 @@ TEST_F(TestInferDeepPotR, cpu_lmp_nlist_type_sel) // dp compute double ener; - std::vector force_(nall*3, 0.0), virial(9, 0.0); + std::vector force_(nall*3, 0.0), virial(9, 0.0); dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall-nloc, inlist, 0); // fold back - std::vector force; - _fold_back(force, force_, mapping, nloc, nall, 3); + std::vector force; + _fold_back(force, force_, mapping, nloc, nall, 3); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } - +template class TestInferDeepPotRNoPbc : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -401,19 +480,19 @@ class TestInferDeepPotRNoPbc : public ::testing::Test std::vector atype = { 0, 1, 1, 0, 1, 1 }; - std::vector box = {}; - std::vector expected_e = { + std::vector box = {}; + std::vector expected_e = { -9.321213823508108476e+01,-1.868044102481340758e+02,-1.868067983858651075e+02,-9.320899631301440991e+01,-1.868014559732615112e+02,-1.868017660713088617e+02 }; - std::vector expected_f = { + std::vector expected_f = { 4.578151103701261042e-03,-1.917874111009987628e-03,-3.464546781179331930e-03,-4.578151103701261042e-03,1.917874111009987628e-03,3.464546781179331930e-03,-2.624402581721222913e-03,3.566275128489623933e-04,-2.859315986763691776e-04,-5.767787273464367384e-03,1.907053583551196647e-03,-3.889064429673861831e-03,1.786820066350549132e-04,-5.327197473636275694e-03,8.236236182834734409e-03,8.213507848550535492e-03,3.063516377236116545e-03,-4.061240154484504865e-03 }; - std::vector expected_v = { + std::vector expected_v = { 1.984979026299632174e-03,-8.315452677741701822e-04,-1.502146290172694243e-03,-8.315452677741700738e-04,3.483500446080982317e-04,6.292774999372096039e-04,-1.502146290172694243e-03,6.292774999372097123e-04,1.136759354725281907e-03,1.402852790439301908e-03,-5.876815743732210226e-04,-1.061618327900012114e-03,-5.876815743732211311e-04,2.461909298049979960e-04,4.447320022283834766e-04,-1.061618327900012331e-03,4.447320022283834766e-04,8.033868427351443728e-04,4.143606961846296385e-03,-5.511382161123719835e-04,4.465413399437045397e-04,-5.511382161123719835e-04,1.082271054025323839e-04,-1.097918001262628728e-04,4.465413399437046481e-04,-1.097918001262628728e-04,1.220966982358671871e-04,5.263952004497593831e-03,2.395243710938091842e-04,-2.830378939414603329e-04,2.395243710938094010e-04,1.189969706598244898e-03,-1.805627331015851201e-03,-2.830378939414602245e-04,-1.805627331015851635e-03,2.801996513751836820e-03,2.208413501170402270e-03,5.331756287635716889e-05,-1.664423506603235218e-04,5.331756287635695205e-05,1.379626072862918072e-03,-2.094132943741625064e-03,-1.664423506603234133e-04,-2.094132943741625064e-03,3.199787996743366607e-03,4.047014004814953811e-03,1.137904999421357000e-03,-1.568106936614101698e-03,1.137904999421357217e-03,7.205982843216952307e-04,-1.011174600268313238e-03,-1.568106936614101698e-03,-1.011174600268313238e-03,1.435226522157425754e-03 }; int natoms; double expected_tot_e; - std::vectorexpected_tot_v; + std::vectorexpected_tot_v; deepmd::DeepPot dp; @@ -444,20 +523,33 @@ class TestInferDeepPotRNoPbc : public ::testing::Test }; }; -TEST_F(TestInferDeepPotRNoPbc, cpu_build_nlist) +TYPED_TEST_SUITE(TestInferDeepPotRNoPbc, ValueTypes); + +TYPED_TEST(TestInferDeepPotRNoPbc, cpu_build_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + int& natoms = this->natoms; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepPot& dp = this->dp; double ener; - std::vector force, virial; + std::vector force, virial; dp.compute(ener, force, virial, coord, atype, box); EXPECT_EQ(force.size(), natoms*3); EXPECT_EQ(virial.size(), 9); - EXPECT_LT(fabs(ener - expected_tot_e), 1e-10); + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); for(int ii = 0; ii < natoms*3; ++ii){ - EXPECT_LT(fabs(force[ii] - expected_f[ii]), 1e-10); + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); } for(int ii = 0; ii < 3*3; ++ii){ - EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), 1e-10); + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); } } diff --git a/source/api_cc/tests/test_dipolecharge.cc b/source/api_cc/tests/test_dipolecharge.cc index b75677f8f6..65c7b2ec52 100644 --- a/source/api_cc/tests/test_dipolecharge.cc +++ b/source/api_cc/tests/test_dipolecharge.cc @@ -14,10 +14,11 @@ #include #include +template class TestDipoleCharge : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 4.6067455554, 8.8719311819, 6.3886531197, 4.0044515745, 4.2449530507, 7.7902855220, 2.6453069446, 0.8772647726, 1.2804446790, @@ -30,26 +31,26 @@ class TestDipoleCharge : public ::testing::Test std::vector atype = { 0,3,2,1,3,4,1,4 }; - std::vector box = { + std::vector box = { 10., 0., 0., 0., 10., 0., 0., 0., 10. }; std::vector expected_e = { 3.671081837126222158e+00 }; - std::vector expected_f = { + std::vector expected_f = { 8.786854427753210128e-01,-1.590752486903602159e-01,-2.709225006303785932e-01,-4.449513960033193438e-01,-1.564291540964127813e-01,2.139031741772115178e-02,1.219699614140521193e+00,-5.580358618499958734e-02,-3.878662478349682585e-01,-1.286685244990778854e+00,1.886475802950296488e-01,3.904450515493615437e-01,1.605017382138404849e-02,2.138016869742287995e-01,-2.617514921203008965e-02,2.877081057057793712e-01,-3.846449683844421763e-01,3.048855616906603894e-02,-9.075632811311897807e-01,-6.509653472431625731e-03,2.302010972126376787e-01,2.370565856822822726e-01,3.600133435593881881e-01,1.243887532859055609e-02 }; - std::vector expected_v = { + std::vector expected_v = { 3.714071471995848417e-01,6.957130186032146613e-01,-1.158289779017217302e+00,6.957130186032139951e-01,-1.400130091653774933e+01,-3.631620234653316626e-01,-1.158289779017217302e+00,-3.631620234653316626e-01,3.805077486043773050e+00 }; - std::vector charge_map = { + std::vector charge_map = { 1., 1., 1., 1., 1., -1., -3. }; int natoms; int ntypes; std::vector type_asso; double expected_tot_e; - std::vectorexpected_tot_v; + std::vectorexpected_tot_v; deepmd::DeepTensor dp; deepmd::DipoleChargeModifier dm; @@ -87,16 +88,33 @@ _in_vec(const int & value, return false; } -TEST_F(TestDipoleCharge, cpu_lmp_nlist) +TYPED_TEST_SUITE(TestDipoleCharge, ValueTypes); + +TYPED_TEST(TestDipoleCharge, cpu_lmp_nlist) { + using VALUETYPE = TypeParam; + std::vector& coord = this->coord; + std::vector& atype = this->atype; + std::vector& box = this->box; + std::vector& expected_e = this->expected_e; + std::vector& expected_f = this->expected_f; + std::vector& expected_v = this->expected_v; + std::vector& charge_map = this->charge_map; + int& natoms = this->natoms; + int& ntypes = this->ntypes; + std::vector& type_asso = this->type_asso; + double& expected_tot_e = this->expected_tot_e; + std::vector&expected_tot_v = this->expected_tot_v; + deepmd::DeepTensor& dp = this->dp; + deepmd::DipoleChargeModifier& dm = this->dm; // build nlist // float rc = dp.cutoff(); float rc = 4.0; int nloc = coord.size() / 3; - std::vector coord_cpy; + std::vector coord_cpy; std::vector atype_cpy, mapping; std::vector > nlist_data; - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); int nall = coord_cpy.size() / 3; int nghost = nall - nloc; @@ -106,7 +124,7 @@ TEST_F(TestDipoleCharge, cpu_lmp_nlist) convert_nlist(inlist, nlist_data); // evaluate dipole - std::vector dipole, dipole_recd(nloc*3, 0.0); + std::vector dipole, dipole_recd(nloc*3, 0.0); dp.compute(dipole, coord_cpy, atype_cpy, box, nall-nloc, inlist); // add virtual atoms to the system @@ -124,7 +142,7 @@ TEST_F(TestDipoleCharge, cpu_lmp_nlist) // const std::vector & sort_fwd_map(nnp_map.get_fwd_map()); // // add coords - std::vector add_coord; + std::vector add_coord; std::vector add_atype; std::vector> pairs; for(int ii = 0; ii < nloc; ++ii){ @@ -132,7 +150,7 @@ TEST_F(TestDipoleCharge, cpu_lmp_nlist) // Yixiao: the sort map is no longer needed // int res_idx = sort_fwd_map[sel_fwd[ii]]; int res_idx = sel_fwd[ii]; - std::vector tmp_coord(3); + std::vector tmp_coord(3); for(int dd = 0; dd < 3; ++dd){ tmp_coord[dd] = coord[ii*3+dd] + dipole[res_idx*3+dd]; dipole_recd[ii*3+dd] = dipole[res_idx*3+dd]; @@ -155,17 +173,17 @@ TEST_F(TestDipoleCharge, cpu_lmp_nlist) EXPECT_EQ(atype.size()*3, coord.size()); // get charge value - std::vector charge(nloc); + std::vector charge(nloc); for(int ii = 0; ii < nloc; ++ii){ charge[ii] = charge_map[atype[ii]]; } // compute the recp part of the ele interaction - double eener; - std::vector eforce, evirial; - deepmd::Region region; + VALUETYPE eener; + std::vector eforce, evirial; + deepmd::Region region; init_region_cpu(region, &box[0]); - deepmd::EwaldParameters eparam; + deepmd::EwaldParameters eparam; eparam.beta = 0.2; eparam.spacing = 4; ewald_recp(eener, eforce, evirial, coord, charge, region, eparam); @@ -175,7 +193,7 @@ TEST_F(TestDipoleCharge, cpu_lmp_nlist) EXPECT_EQ(evirial.size(), 9); // extend the system with virtual atoms, and build nlist - _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, + _build_nlist(nlist_data, coord_cpy, atype_cpy, mapping, coord, atype, box, rc); nall = coord_cpy.size() / 3; nghost = nall - nloc; @@ -189,13 +207,13 @@ TEST_F(TestDipoleCharge, cpu_lmp_nlist) convert_nlist(inlist, nlist_data); // compute force and virial - std::vector force_, force, virial; + std::vector force_, force, virial; dm.compute(force_, virial, coord_cpy, atype_cpy, box, pairs, eforce, nghost, inlist); // for(int ii = 0; ii < force_.size(); ++ii){ // std::cout << force_[ii] << " " ; // } // std::cout << std::endl; - _fold_back(force, force_, mapping, nloc, nall, 3); + _fold_back(force, force_, mapping, nloc, nall, 3); // compare force EXPECT_EQ(force.size(), nloc*3); diff --git a/source/api_cc/tests/test_ewald.cc b/source/api_cc/tests/test_ewald.cc index e27b1087e3..83b190586a 100644 --- a/source/api_cc/tests/test_ewald.cc +++ b/source/api_cc/tests/test_ewald.cc @@ -7,10 +7,11 @@ #include "test_utils.h" #include "ewald.h" +template class TestInferEwald : public ::testing::Test { protected: - std::vector coord = { + std::vector coord = { 12.83, 2.56, 2.18, 12.09, 2.87, 2.74, 00.25, 3.32, 1.68, @@ -18,10 +19,10 @@ class TestInferEwald : public ::testing::Test 3.51, 2.51, 2.60, 4.27, 3.22, 1.56 }; - std::vector charge = { + std::vector charge = { -2, 1, 1, -2, 1, 1 }; - std::vector box = { + std::vector box = { 13., 0., 0., 0., 13., 0., 0., 0., 13. }; void SetUp() override { @@ -30,33 +31,41 @@ class TestInferEwald : public ::testing::Test }; }; -TEST_F(TestInferEwald, cpu_numfv) +TYPED_TEST_SUITE(TestInferEwald, ValueTypes); + +TYPED_TEST(TestInferEwald, cpu_numfv) { - class MyModel : public EnergyModelTest + using VALUETYPE = TypeParam; + std::vector& coord = this -> coord; + std::vector& charge = this -> charge; + std::vector& box = this -> box; + class MyModel : public EnergyModelTest { - const std::vector & charge; - deepmd::EwaldParameters eparam; + const std::vector & charge; + deepmd::EwaldParameters eparam; public: MyModel( - const std::vector & charge_ + const std::vector & charge_ ) : charge(charge_) { eparam.beta = 0.4; }; virtual void compute ( double & ener, - std::vector & force, - std::vector & virial, - const std::vector & coord, - const std::vector & box) { - deepmd::Region region; + std::vector & force, + std::vector & virial, + const std::vector & coord, + const std::vector & box) { + deepmd::Region region; init_region_cpu(region, &box[0]); - ewald_recp(ener, force, virial, coord, charge, region, eparam); + VALUETYPE ener_; + ewald_recp(ener_, force, virial, coord, charge, region, eparam); + ener = ener_; } }; MyModel model(charge); model.test_f(coord, box); model.test_v(coord, box); - std::vector box_(box); + std::vector box_(box); box_[1] -= 0.2; model.test_f(coord, box_); model.test_v(coord, box_); diff --git a/source/api_cc/tests/test_utils.h b/source/api_cc/tests/test_utils.h index d2d9d6c261..b6759514e5 100644 --- a/source/api_cc/tests/test_utils.h +++ b/source/api_cc/tests/test_utils.h @@ -1,10 +1,19 @@ #pragma once #include +#include "gtest/gtest.h" +#include "SimulationRegion.h" +#include "region.h" +#include "neighbor_list.h" +#define EPSILON (std::is_same::value ? 1e-10 : 1e-4) + +typedef testing::Types ValueTypes; + +template inline void _fold_back( - typename std::vector::iterator out, - const typename std::vector::const_iterator in, + typename std::vector::iterator out, + const typename std::vector::const_iterator in, const std::vector &mapping, const int nloc, const int nall, @@ -21,34 +30,41 @@ _fold_back( } } +template inline void _fold_back( - std::vector &out, - const std::vector &in, + std::vector &out, + const std::vector &in, const std::vector &mapping, const int nloc, const int nall, const int ndim) { out.resize(nloc*ndim); - _fold_back(out.begin(), in.begin(), mapping, nloc, nall, ndim); + _fold_back(out.begin(), in.begin(), mapping, nloc, nall, ndim); } +template inline void _build_nlist( std::vector> &nlist_data, - std::vector & coord_cpy, + std::vector & coord_cpy, std::vector & atype_cpy, std::vector & mapping, - const std::vector & coord, + const std::vector & coord, const std::vector & atype, - const std::vector & box, + const std::vector & box, const float & rc) { + // convert VALUETYPE to double, it looks like copy_coord only accepts double + std::vector coord_cpy_; + std::vector coord_(coord.begin(), coord.end()); + std::vector box_(box.begin(), box.end()); + SimulationRegion region; - region.reinitBox(&box[0]); + region.reinitBox(&box_[0]); std::vector ncell, ngcell; - copy_coord(coord_cpy, atype_cpy, mapping, ncell, ngcell, coord, atype, rc, region); + copy_coord(coord_cpy_, atype_cpy, mapping, ncell, ngcell, coord_, atype, rc, region); std::vector nat_stt, ext_stt, ext_end; nat_stt.resize(3); ext_stt.resize(3); @@ -57,20 +73,23 @@ _build_nlist( ext_stt[dd] = -ngcell[dd]; ext_end[dd] = ncell[dd] + ngcell[dd]; } - int nloc = coord.size() / 3; - int nall = coord_cpy.size() / 3; + int nloc = coord_.size() / 3; + int nall = coord_cpy_.size() / 3; std::vector> nlist_r_cpy; - build_nlist(nlist_data, nlist_r_cpy, coord_cpy, nloc, rc, rc, nat_stt, ncell, ext_stt, ext_end, region, ncell); + build_nlist(nlist_data, nlist_r_cpy, coord_cpy_, nloc, rc, rc, nat_stt, ncell, ext_stt, ext_end, region, ncell); + + // convert double to VALUETYPE + coord_cpy.assign(coord_cpy_.begin(), coord_cpy_.end()); } template class EnergyModelTest { - double hh = 1e-5; - double level = 1e-6; + double hh = std::is_same::value ? 1e-5 : 1e-2; + double level = std::is_same::value ? 1e-6 : 1e-2; // expected? public: virtual void compute ( - VALUETYPE & ener, + double & ener, std::vector & force, std::vector & virial, const std::vector & coord, @@ -80,12 +99,12 @@ class EnergyModelTest const std::vector & coord, const std::vector & box) { int ndof = coord.size(); - VALUETYPE ener; + double ener; std::vector force, virial; compute(ener, force, virial, coord, box); for(int ii = 0; ii < ndof; ++ii){ std::vector coord0(coord), coord1(coord); - VALUETYPE ener0, ener1; + double ener0, ener1; std::vector forcet, virialt; coord0[ii] += hh; coord1[ii] -= hh; @@ -100,7 +119,7 @@ class EnergyModelTest const std::vector & coord, const std::vector & box) { std::vector num_diff(9); - VALUETYPE ener; + double ener; std::vector force, virial; compute(ener, force, virial, coord, box); deepmd::Region region; @@ -124,7 +143,7 @@ class EnergyModelTest convert_to_inter_cpu(pi, region, &coord[ii*3]); convert_to_phys_cpu(&coord1[ii*3], region1, pi); } - VALUETYPE ener0, ener1; + double ener0, ener1; std::vector forcet, virialt; compute(ener0, forcet, virialt, coord0, box0); compute(ener1, forcet, virialt, coord1, box1); diff --git a/source/cmake/Config.cmake.in b/source/cmake/Config.cmake.in new file mode 100644 index 0000000000..08a8cbfa78 --- /dev/null +++ b/source/cmake/Config.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ +include(CMakeFindDependencyMacro) + +include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") +check_required_components("@project_name@") diff --git a/source/cmake/FindROCM.cmake b/source/cmake/FindROCM.cmake index cab69e4999..fa8ee2c20f 100644 --- a/source/cmake/FindROCM.cmake +++ b/source/cmake/FindROCM.cmake @@ -7,13 +7,10 @@ # ROCM_LIBRARIES # define the search path -list(APPEND ROCM_search_PATHS ${ROCM_ROOT}) -list(APPEND ROCM_search_PATHS "/opt/rocm/") - -# define the libs to find -if (NOT ROCM_FIND_COMPONENTS) - set(ROCM_FIND_COMPONENTS hip_hcc hiprtc) -endif () +cmake_minimum_required(VERSION 3.21) +include(CMakeDetermineHIPCompiler) +set(ROCM_PATH ${CMAKE_HIP_COMPILER_ROCM_ROOT}) +set(ROCM_search_PATHS ${CMAKE_HIP_COMPILER_ROCM_ROOT}) # includes find_path (ROCM_INCLUDE_DIRS @@ -31,21 +28,6 @@ if (NOT ROCM_INCLUDE_DIRS AND ROCM_FIND_REQUIRED) "You can manually set the ROCM install path by -DROCM_ROOT ") endif () -# libs -foreach (module ${ROCM_FIND_COMPONENTS}) - find_library(ROCM_LIBRARIES_${module} - NAMES ${module} - PATHS ${ROCM_search_PATHS} PATH_SUFFIXES "lib" NO_DEFAULT_PATH - ) - if (ROCM_LIBRARIES_${module}) - list(APPEND ROCM_LIBRARIES ${ROCM_LIBRARIES_${module}}) - elseif (ROCM_FIND_REQUIRED) - message(FATAL_ERROR - "Not found lib/'${module}' in '${ROCM_search_PATHS}' " - "You can manually set the ROCM install path by -DROCM_ROOT ") - endif () -endforeach () - # FindHIP.cmake find_path (HIP_CMAKE NAMES @@ -64,6 +46,30 @@ endif () list (APPEND CMAKE_MODULE_PATH ${HIP_CMAKE}) find_package(HIP) +# define the libs to find +if (NOT ROCM_FIND_COMPONENTS) + if (HIP_VERSION VERSION_GREATER_EQUAL 3.5.1) + set(ROCM_FIND_COMPONENTS amd_comgr amdhip64) + else() + set(ROCM_FIND_COMPONENTS hip-hcc hiprtc) + endif() +endif () + +# libs +foreach (module ${ROCM_FIND_COMPONENTS}) + find_library(ROCM_LIBRARIES_${module} + NAMES ${module} + PATHS ${ROCM_search_PATHS} PATH_SUFFIXES "lib" NO_DEFAULT_PATH + ) + if (ROCM_LIBRARIES_${module}) + list(APPEND ROCM_LIBRARIES ${ROCM_LIBRARIES_${module}}) + elseif (ROCM_FIND_REQUIRED) + message(FATAL_ERROR + "Not found lib/'${module}' in '${ROCM_search_PATHS}' " + "You can manually set the ROCM install path by -DROCM_ROOT ") + endif () +endforeach () + # define the output variable if (ROCM_INCLUDE_DIRS AND ROCM_LIBRARIES AND HIP_CMAKE) set(ROCM_FOUND TRUE) diff --git a/source/cmake/Findtensorflow.cmake b/source/cmake/Findtensorflow.cmake index 97d21b8444..35137db664 100644 --- a/source/cmake/Findtensorflow.cmake +++ b/source/cmake/Findtensorflow.cmake @@ -9,7 +9,10 @@ # TensorFlow_LIBRARY_PATH # TensorFlowFramework_LIBRARY # TensorFlowFramework_LIBRARY_PATH - +# +# Target: +# TensorFlow::tensorflow_framework +# TensorFlow::tensorflow_cc if (BUILD_CPP_IF AND INSTALL_TENSORFLOW) # Here we try to install libtensorflow_cc using conda install. @@ -25,20 +28,23 @@ if (BUILD_CPP_IF AND INSTALL_TENSORFLOW) endif () # execute conda install execute_process( - COMMAND conda install libtensorflow_cc=*=${VARIANT}* -c deepmodeling -y -p ${TENSORFLOW_ROOT} + COMMAND conda create libtensorflow_cc=*=${VARIANT}* -c deepmodeling -y -p ${TENSORFLOW_ROOT} ) endif () -if (BUILD_CPP_IF AND USE_TF_PYTHON_LIBS) +if (BUILD_CPP_IF AND USE_TF_PYTHON_LIBS AND NOT SKBUILD) # Here we try to install libtensorflow_cc.so as well as libtensorflow_framework.so using libs within the python site-package tensorflow folder. - - if (NOT DEFINED TENSORFLOW_ROOT) - set (TENSORFLOW_ROOT ${CMAKE_INSTALL_PREFIX}) - endif () - # execute install script execute_process( - COMMAND sh ${DEEPMD_SOURCE_DIR}/source/install/install_tf.sh ${Python_SITELIB} ${TENSORFLOW_ROOT} - ) + COMMAND ${Python_EXECUTABLE} -c "import tensorflow; print(tensorflow.sysconfig.get_lib())" + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE TENSORFLOW_ROOT + RESULT_VARIABLE TENSORFLOW_ROOT_RESULT_VAR + ERROR_VARIABLE TENSORFLOW_ROOT_ERROR_VAR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (NOT ${TENSORFLOW_ROOT_RESULT_VAR} EQUAL 0) + message(FATAL_ERROR "Cannot determine tensorflow root, error code: ${TENSORFLOW_ROOT_RESULT_VAR}, error message: ${TENSORFLOW_ROOT_ERROR_VAR}") + endif() endif () if(DEFINED TENSORFLOW_ROOT) @@ -47,16 +53,15 @@ endif(DEFINED TENSORFLOW_ROOT) # define the search path list(APPEND TensorFlow_search_PATHS ${TENSORFLOW_ROOT}) -if(BUILD_CPP_IF) +if(BUILD_CPP_IF AND NOT USE_TF_PYTHON_LIBS) list(APPEND TensorFlow_search_PATHS ${TENSORFLOW_ROOT_NO64}) list(APPEND TensorFlow_search_PATHS "/usr/") list(APPEND TensorFlow_search_PATHS "/usr/local/") endif() -if(BUILD_PY_IF) +if(BUILD_PY_IF OR USE_TF_PYTHON_LIBS) # here TENSORFLOW_ROOT is path to site-packages/tensorflow # for conda libraries, append extra paths list(APPEND TensorFlow_search_PATHS "${TENSORFLOW_ROOT}/../tensorflow_core") - list(APPEND TensorFlow_search_PATHS "${TENSORFLOW_ROOT}/../../../..") endif() # includes @@ -71,14 +76,6 @@ find_path(TensorFlow_INCLUDE_DIRS PATH_SUFFIXES "/include" NO_DEFAULT_PATH ) -find_path(TensorFlow_INCLUDE_DIRS_GOOGLE - NAMES - google/protobuf/type.pb.h - PATHS ${TensorFlow_search_PATHS} - PATH_SUFFIXES "/include" - NO_DEFAULT_PATH - ) -list(APPEND TensorFlow_INCLUDE_DIRS ${TensorFlow_INCLUDE_DIRS_GOOGLE}) if (NOT TensorFlow_INCLUDE_DIRS AND tensorflow_FIND_REQUIRED) message(FATAL_ERROR @@ -86,7 +83,7 @@ if (NOT TensorFlow_INCLUDE_DIRS AND tensorflow_FIND_REQUIRED) "You can manually set the tensorflow install path by -DTENSORFLOW_ROOT ") endif () -if (BUILD_CPP_IF) +if (BUILD_CPP_IF AND NOT USE_TF_PYTHON_LIBS) message (STATUS "Enabled cpp interface build, looking for tensorflow_cc and tensorflow_framework") # tensorflow_cc and tensorflow_framework if (NOT TensorFlow_FIND_COMPONENTS) @@ -111,9 +108,9 @@ if (BUILD_CPP_IF) "You can manually set the tensorflow install path by -DTENSORFLOW_ROOT ") endif () endforeach () -else (BUILD_CPP_IF) +else (BUILD_CPP_IF AND NOT USE_TF_PYTHON_LIBS) message (STATUS "Disabled cpp interface build, looking for tensorflow_framework") -endif (BUILD_CPP_IF) +endif (BUILD_CPP_IF AND NOT USE_TF_PYTHON_LIBS) # tensorflow_framework @@ -145,11 +142,79 @@ foreach (module ${TensorFlowFramework_FIND_COMPONENTS}) list(APPEND TensorFlowFramework_LIBRARY_PATH ${TensorFlowFramework_LIBRARY_PATH_${module}}) elseif (tensorflow_FIND_REQUIRED) message(FATAL_ERROR - "Not found lib/'${module}' in '${TensorFlow_search_PATHS}' " + "Not found ${TF_SUFFIX}/${module} in '${TensorFlow_search_PATHS}' " "You can manually set the tensorflow install path by -DTENSORFLOW_ROOT ") endif () endforeach () +# find _pywrap_tensorflow_internal and set it as tensorflow_cc +if (BUILD_CPP_IF AND USE_TF_PYTHON_LIBS) + set(TF_SUFFIX python) + if(WIN32) + set(TensorFlow_FIND_COMPONENTS _pywrap_tensorflow_internal.lib) + else () + set(TensorFlow_FIND_COMPONENTS _pywrap_tensorflow_internal${CMAKE_SHARED_MODULE_SUFFIX}) + endif() + foreach (module ${TensorFlow_FIND_COMPONENTS}) + find_library(TensorFlow_LIBRARY_${module} + NAMES ${module} + PATHS ${TensorFlow_search_PATHS} PATH_SUFFIXES ${TF_SUFFIX} NO_DEFAULT_PATH + ) + if (TensorFlow_LIBRARY_${module}) + list(APPEND TensorFlow_LIBRARY ${TensorFlow_LIBRARY_${module}}) + get_filename_component(TensorFlow_LIBRARY_PATH_${module} ${TensorFlow_LIBRARY_${module}} PATH) + list(APPEND TensorFlow_LIBRARY_PATH ${TensorFlow_LIBRARY_PATH_${module}}) + set (TensorFlow_LIBRARY_tensorflow_cc ${TensorFlow_LIBRARY_${module}}) + elseif (tensorflow_FIND_REQUIRED) + message(FATAL_ERROR + "Not found ${TF_SUFFIX}/${module} in '${TensorFlow_search_PATHS}' ") + endif () + endforeach () +endif() + + +# find protobuf header +find_path(TensorFlow_INCLUDE_DIRS_GOOGLE + NAMES + google/protobuf/type.pb.h + PATHS ${TensorFlow_search_PATHS} + PATH_SUFFIXES "/include" + NO_DEFAULT_PATH + ) + # try to find from ldd list of TF library + # a warning is threw here, just ignore it + # https://stackoverflow.com/a/49738486/9567349 + if ($ENV{LD_LIBRARY_PATH}) + string(REPLACE ":" ";" _LD_LIBRARY_DIRS $ENV{LD_LIBRARY_PATH}) + endif() + file(GET_RUNTIME_DEPENDENCIES + RESOLVED_DEPENDENCIES_VAR TensorFlow_LINKED_LIBRARIES + UNRESOLVED_DEPENDENCIES_VAR TensorFlow_LINKED_LIBRARIES_UNRESOLVED + LIBRARIES ${TensorFlowFramework_LIBRARY} + POST_INCLUDE_REGEXES "^.+protobuf\..+$" + DIRECTORIES "${_LD_LIBRARY_DIRS}" + ) + # search protobuf from linked libraries + foreach(_lib ${TensorFlow_LINKED_LIBRARIES}) + string(REGEX MATCH "^.+protobuf\..+$" _protobuf_lib ${_lib}) + if (_protobuf_lib) + set(Protobuf_LIBRARY ${_protobuf_lib}) + break() + endif() + endforeach() +if (NOT TensorFlow_INCLUDE_DIRS_GOOGLE) + message(STATUS "Protobuf headers are not found in the directory of TensorFlow, assuming external protobuf was used to build TensorFlow") + if (NOT Protobuf_LIBRARY) + message(FATAL_ERROR "TensorFlow is not linked to protobuf") + endif() + get_filename_component(Protobuf_LIBRARY_DIRECTORY ${Protobuf_LIBRARY} DIRECTORY) + # assume the include directory is ../include + set(Protobuf_INCLUDE_DIR ${Protobuf_LIBRARY_DIRECTORY}/../include) + find_package(Protobuf REQUIRED) + set(TensorFlow_INCLUDE_DIRS_GOOGLE ${Protobuf_INCLUDE_DIRS}) +endif() +list(APPEND TensorFlow_INCLUDE_DIRS ${TensorFlow_INCLUDE_DIRS_GOOGLE}) + if (BUILD_CPP_IF) # define the output variable if (TensorFlow_INCLUDE_DIRS AND TensorFlow_LIBRARY AND TensorFlowFramework_LIBRARY) @@ -188,3 +253,136 @@ if (NOT TensorFlow_FIND_QUIETLY) endif () unset(TensorFlow_search_PATHS) + +if (TENSORFLOW_VERSION VERSION_GREATER_EQUAL 2.10) + set (CMAKE_CXX_STANDARD 17) +elseif (TENSORFLOW_VERSION VERSION_GREATER_EQUAL 2.7) + set (CMAKE_CXX_STANDARD 14) +else() + set (CMAKE_CXX_STANDARD 11) +endif() + +if (MSVC) + # see TF .bazelrc + add_compile_options(/W0 /Zc:__cplusplus /D_USE_MATH_DEFINES /d2ReducedOptimizeHugeFunctions) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) +endif() +if (TENSORFLOW_VERSION VERSION_GREATER_EQUAL 2.4 AND MSVC) + # see TF 2.4 release notes + add_compile_options(/Zc:preprocessor) +endif() + +# auto op_cxx_abi +if(MSVC OR APPLE) + # skip on windows or osx + set(OP_CXX_ABI 0) +elseif (NOT DEFINED OP_CXX_ABI) + if (TENSORFLOW_VERSION VERSION_GREATER_EQUAL 2.9) + # TF 2.9 removes the tf_cxx11_abi_flag function, which is really bad... + # try compiling with both 0 and 1, and see which one works + try_compile( + CPP_CXX_ABI_COMPILE_RESULT_VAR0 + ${CMAKE_CURRENT_BINARY_DIR}/tf_cxx_abi0 + "${CMAKE_CURRENT_LIST_DIR}/test_cxx_abi.cpp" + LINK_LIBRARIES ${TensorFlowFramework_LIBRARY} + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${TensorFlow_INCLUDE_DIRS}" + COMPILE_DEFINITIONS -D_GLIBCXX_USE_CXX11_ABI=0 + ) + try_compile( + CPP_CXX_ABI_COMPILE_RESULT_VAR1 + ${CMAKE_CURRENT_BINARY_DIR}/tf_cxx_abi1 + "${CMAKE_CURRENT_LIST_DIR}/test_cxx_abi.cpp" + LINK_LIBRARIES ${TensorFlowFramework_LIBRARY} + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${TensorFlow_INCLUDE_DIRS}" + COMPILE_DEFINITIONS -D_GLIBCXX_USE_CXX11_ABI=1 + ) + if (NOT ${CPP_CXX_ABI_COMPILE_RESULT_VAR0} AND ${CPP_CXX_ABI_COMPILE_RESULT_VAR1}) + set(OP_CXX_ABI 1) + elseif(${CPP_CXX_ABI_COMPILE_RESULT_VAR0} AND NOT ${CPP_CXX_ABI_COMPILE_RESULT_VAR1}) + set(OP_CXX_ABI 0) + else() + message(FATAL_ERROR "Failed to detect OP_CXX_ABI, please set it manually") + endif() + else() + try_run( + CPP_CXX_ABI_RUN_RESULT_VAR CPP_CXX_ABI_COMPILE_RESULT_VAR + ${CMAKE_CURRENT_BINARY_DIR}/tf_cxx_abi + "${CMAKE_CURRENT_LIST_DIR}/tf_cxx_abi.cpp" + LINK_LIBRARIES ${TensorFlowFramework_LIBRARY} + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${TensorFlow_INCLUDE_DIRS}" + RUN_OUTPUT_VARIABLE CPP_CXX_ABI + COMPILE_OUTPUT_VARIABLE CPP_CXX_ABI_COMPILE_OUTPUT_VAR + ) + if (NOT ${CPP_CXX_ABI_COMPILE_RESULT_VAR}) + message(FATAL_ERROR "Failed to compile: \n ${CPP_CXX_ABI_COMPILE_OUTPUT_VAR}" ) + endif() + if (NOT ${CPP_CXX_ABI_RUN_RESULT_VAR} EQUAL "0") + message(FATAL_ERROR "Failed to run, return code: ${CPP_CXX_ABI}" ) + endif() + set(OP_CXX_ABI ${CPP_CXX_ABI}) + endif() + message (STATUS "Automatically determined OP_CXX_ABI=${OP_CXX_ABI} ") +else() + message (STATUS "User set OP_CXX_ABI=${OP_CXX_ABI} ") +endif() +# message the cxx_abi used during compiling +if (${OP_CXX_ABI} EQUAL 0) + message (STATUS "Set GLIBCXX_USE_CXX_ABI=0") +else () + set (OP_CXX_ABI 1) + message (STATUS "Set GLIBCXX_USE_CXX_ABI=1") +endif () + +# set _GLIBCXX_USE_CXX11_ABI flag globally +add_definitions(-D_GLIBCXX_USE_CXX11_ABI=${OP_CXX_ABI}) + +# set import libraries +# https://cmake.org/cmake/help/latest/guide/importing-exporting/ +# TensorFlow::tensorflow_framework + +add_library(TensorFlow::tensorflow_framework SHARED IMPORTED GLOBAL) +if(WIN32) + if(USE_TF_PYTHON_LIBS) + string(REGEX REPLACE "[.]lib" ".pyd" _DLL_FILE ${TensorFlowFramework_LIBRARY}) + else() + string(REGEX REPLACE "[.]lib" ".dll" _DLL_FILE ${TensorFlowFramework_LIBRARY}) + endif() + set_target_properties(TensorFlow::tensorflow_framework PROPERTIES + IMPORTED_IMPLIB ${TensorFlowFramework_LIBRARY} + IMPORTED_LOCATION ${_DLL_FILE}) +else() +set_property(TARGET TensorFlow::tensorflow_framework PROPERTY + IMPORTED_LOCATION ${TensorFlowFramework_LIBRARY}) +endif() +set_property(TARGET TensorFlow::tensorflow_framework PROPERTY + CXX_STANDARD ${CMAKE_CXX_STANDARD}) +target_include_directories(TensorFlow::tensorflow_framework INTERFACE ${TensorFlow_INCLUDE_DIRS}) +target_compile_definitions(TensorFlow::tensorflow_framework INTERFACE + -D_GLIBCXX_USE_CXX11_ABI=${OP_CXX_ABI}) + +# TensorFlow::tensorflow_cc +if(BUILD_CPP_IF) + add_library(TensorFlow::tensorflow_cc SHARED IMPORTED GLOBAL) + if(WIN32) + if(USE_TF_PYTHON_LIBS) + string(REGEX REPLACE "[.]lib" ".pyd" _DLL_FILE ${TensorFlow_LIBRARY_tensorflow_cc}) + else() + string(REGEX REPLACE "[.]lib" ".dll" _DLL_FILE ${TensorFlow_LIBRARY_tensorflow_cc}) + endif() + set_target_properties(TensorFlow::tensorflow_cc PROPERTIES + IMPORTED_IMPLIB ${TensorFlow_LIBRARY_tensorflow_cc} + IMPORTED_LOCATION ${_DLL_FILE}) + else() + set_property(TARGET TensorFlow::tensorflow_cc PROPERTY + IMPORTED_LOCATION ${TensorFlow_LIBRARY_tensorflow_cc}) + endif() + set_property(TARGET TensorFlow::tensorflow_cc PROPERTY + CXX_STANDARD ${CMAKE_CXX_STANDARD}) + target_include_directories(TensorFlow::tensorflow_cc INTERFACE ${TensorFlow_INCLUDE_DIRS}) + target_compile_definitions(TensorFlow::tensorflow_cc INTERFACE + -D_GLIBCXX_USE_CXX11_ABI=${OP_CXX_ABI}) + if (USE_TF_PYTHON_LIBS) + # link: libpython3.x.so + target_link_libraries (TensorFlow::tensorflow_cc INTERFACE ${Python_LIBRARIES}) + endif() +endif() diff --git a/source/cmake/coverage_config/CMakeLists.txt b/source/cmake/coverage_config/CMakeLists.txt new file mode 100644 index 0000000000..90fc13522d --- /dev/null +++ b/source/cmake/coverage_config/CMakeLists.txt @@ -0,0 +1,12 @@ +# include this directory before other modules +add_library(coverage_config INTERFACE) +target_compile_options(coverage_config INTERFACE + -O0 # no optimization + -g # generate debug info + --coverage # sets all required flags +) +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13) + target_link_options(coverage_config INTERFACE --coverage) +else() + target_link_libraries(coverage_config INTERFACE --coverage) +endif() \ No newline at end of file diff --git a/source/cmake/googletest.cmake.in b/source/cmake/googletest.cmake.in index 577bd17dc1..5d167cf774 100644 --- a/source/cmake/googletest.cmake.in +++ b/source/cmake/googletest.cmake.in @@ -11,9 +11,10 @@ endif() include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY ${GTEST_REPO_ADDRESS} - GIT_TAG main - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" + GIT_TAG release-1.12.1 + GIT_SHALLOW TRUE + SOURCE_DIR "@CMAKE_CURRENT_BINARY_DIR@/googletest-src" + BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/googletest-build" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/source/cmake/test_cxx_abi.cpp b/source/cmake/test_cxx_abi.cpp new file mode 100644 index 0000000000..0e70533aa0 --- /dev/null +++ b/source/cmake/test_cxx_abi.cpp @@ -0,0 +1,6 @@ +#include +#include "tensorflow/core/framework/shape_inference.h" +int main() { + auto ignore = tensorflow::strings::StrCat("a", "b"); + return 0; +} diff --git a/source/cmake/tf_cxx_abi.cpp b/source/cmake/tf_cxx_abi.cpp index ed3fd848e0..c25565c568 100644 --- a/source/cmake/tf_cxx_abi.cpp +++ b/source/cmake/tf_cxx_abi.cpp @@ -3,11 +3,7 @@ int main(int argc, char * argv[]) { #if (TF_MAJOR_VERSION == 2 && TF_MINOR_VERSION>=9) || TF_MAJOR_VERSION > 2 -#ifdef _GLIBCXX_USE_CXX11_ABI - std::cout << _GLIBCXX_USE_CXX11_ABI; -#else - std::cout << 0; -#endif +#error "TF>=2.9 should not execute this file..." #else std::cout << tf_cxx11_abi_flag(); #endif diff --git a/source/config/CMakeLists.txt b/source/config/CMakeLists.txt index faab6e3e36..52834ebb1e 100644 --- a/source/config/CMakeLists.txt +++ b/source/config/CMakeLists.txt @@ -4,5 +4,5 @@ configure_file("run_config.ini" "${CMAKE_CURRENT_BINARY_DIR}/run_config.ini" @ON install( FILES ${CMAKE_CURRENT_BINARY_DIR}/run_config.ini - DESTINATION deepmd/pkg_config + DESTINATION deepmd ) diff --git a/source/gmx/.gitignore b/source/gmx/.gitignore new file mode 100644 index 0000000000..ed2f43cf54 --- /dev/null +++ b/source/gmx/.gitignore @@ -0,0 +1 @@ +CMakeLists.txt.patch \ No newline at end of file diff --git a/source/gmx/CMakeLists.txt b/source/gmx/CMakeLists.txt index baa2e13140..e176b2b209 100644 --- a/source/gmx/CMakeLists.txt +++ b/source/gmx/CMakeLists.txt @@ -14,7 +14,7 @@ file(GLOB LIB_SRC src/*.cpp) file(GLOB INC_SRC include/*.h) add_library(${libgmxname} SHARED ${LIB_SRC}) -target_link_libraries(${libgmxname} ${LIB_DEEPMD_CC} ${LIB_DEEPMD} ${TensorFlow_LIBRARY} ${TensorFlowFramework_LIBRARY}) +target_link_libraries(${libgmxname} PUBLIC ${LIB_DEEPMD_CC}) target_include_directories(${libgmxname} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(${libgmxname} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/) diff --git a/source/gmx/patches/2020.2/CMakeLists.txt.patch.in b/source/gmx/patches/2020.2/CMakeLists.txt.patch.in index fa027f156e..93f11bbffe 100644 --- a/source/gmx/patches/2020.2/CMakeLists.txt.patch.in +++ b/source/gmx/patches/2020.2/CMakeLists.txt.patch.in @@ -18,8 +18,8 @@ +include_directories(${GMX_TENSORFLOW_ROOT}/include) +link_directories(${GMX_DEEPMD_ROOT}/lib) +link_directories(${GMX_TENSORFLOW_ROOT}/lib) -+# define high precision, only support high precision now -+add_definitions("-D HIGH_PREC") ++ ++ +# add link libraries +list (APPEND GMX_PUBLIC_LIBRARIES deepmd_gromacs) +# DeepMD diff --git a/source/install/build_cc.sh b/source/install/build_cc.sh index f557ab7a0b..2804c33161 100755 --- a/source/install/build_cc.sh +++ b/source/install/build_cc.sh @@ -1,8 +1,11 @@ set -e -if [ "$DP_VARIANT" == "cuda" ] +if [ "$DP_VARIANT" = "cuda" ] then CUDA_ARGS="-DUSE_CUDA_TOOLKIT=TRUE" +elif [ "$DP_VARIANT" = "rocm" ] +then + CUDA_ARGS="-DUSE_ROCM_TOOLKIT=TRUE" fi #------------------ @@ -11,6 +14,10 @@ if [ -z "$INSTALL_PREFIX" ] then INSTALL_PREFIX=$(realpath -s ${SCRIPT_PATH}/../../dp) fi +if [ -z "$DOWNLOAD_TENSORFLOW" ] +then + DOWNLOAD_TENSORFLOW=TRUE +fi mkdir -p ${INSTALL_PREFIX} echo "Installing DeePMD-kit to ${INSTALL_PREFIX}" NPROC=$(nproc --all) @@ -20,7 +27,7 @@ NPROC=$(nproc --all) BUILD_TMP_DIR=${SCRIPT_PATH}/../build mkdir -p ${BUILD_TMP_DIR} cd ${BUILD_TMP_DIR} -cmake -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -DINSTALL_TENSORFLOW=TRUE ${CUDA_ARGS} -DLAMMPS_VERSION=stable_23Jun2022_update1 -DUSE_TTM=TRUE .. +cmake -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -DINSTALL_TENSORFLOW=${DOWNLOAD_TENSORFLOW} ${CUDA_ARGS} -DLAMMPS_VERSION=stable_23Jun2022_update2 .. make -j${NPROC} make install diff --git a/source/install/build_lammps.sh b/source/install/build_lammps.sh index 9f95776de6..96963bea08 100755 --- a/source/install/build_lammps.sh +++ b/source/install/build_lammps.sh @@ -15,7 +15,7 @@ BUILD_TMP_DIR=${SCRIPT_PATH}/../build_lammps mkdir -p ${BUILD_TMP_DIR} cd ${BUILD_TMP_DIR} # download LAMMMPS -LAMMPS_VERSION=stable_23Jun2022_update1 +LAMMPS_VERSION=stable_23Jun2022_update2 if [ ! -d "lammps-${LAMMPS_VERSION}" ] then curl -L -o lammps.tar.gz https://github.com/lammps/lammps/archive/refs/tags/${LAMMPS_VERSION}.tar.gz @@ -25,10 +25,11 @@ fi cd ${BUILD_TMP_DIR}/lammps-${LAMMPS_VERSION} mkdir -p ${BUILD_TMP_DIR}/lammps-${LAMMPS_VERSION}/build cd ${BUILD_TMP_DIR}/lammps-${LAMMPS_VERSION}/build -cmake -C ../cmake/presets/all_off.cmake -D PKG_PLUGIN=ON -D PKG_KSPACE=ON -D BUILD_SHARED_LIBS=yes -D LAMMPS_INSTALL_RPATH=ON -D CMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -D CMAKE_INSTALL_LIBDIR=lib -D CMAKE_INSTALL_FULL_LIBDIR=${INSTALL_PREFIX}/lib ../cmake +cmake -C ../cmake/presets/all_off.cmake -D PKG_PLUGIN=ON -D PKG_KSPACE=ON -DLAMMPS_EXCEPTIONS=yes -D BUILD_SHARED_LIBS=yes -D LAMMPS_INSTALL_RPATH=ON -D CMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -D CMAKE_INSTALL_LIBDIR=lib -D CMAKE_INSTALL_FULL_LIBDIR=${INSTALL_PREFIX}/lib ../cmake make -j${NPROC} make install +make install-python #------------------ echo "Congratulations! LAMMPS has been installed at ${INSTALL_PREFIX}" diff --git a/source/install/build_tf.py b/source/install/build_tf.py index e2b65eebf6..0ede567442 100755 --- a/source/install/build_tf.py +++ b/source/install/build_tf.py @@ -47,10 +47,15 @@ CPU_COUNT = os.cpu_count() nvcc_path = shutil.which("nvcc") if nvcc_path is not None: - CUDA_PATH = Path(shutil.which("nvcc")).parent.parent + CUDA_PATH = Path(nvcc_path).parent.parent else: CUDA_PATH = None CUDNN_PATH = Path("/usr") if os.path.isfile("/usr/include/cudnn.h") else None +hipcc_path = shutil.which("hipcc") +if hipcc_path is not None: + ROCM_PATH = Path(hipcc_path).parent.parent +else: + ROCM_PATH = None GCC = shutil.which("gcc") GXX = shutil.which("g++") @@ -135,7 +140,26 @@ def post_process(self): self.path.chmod(self.path.stat().st_mode | stat.S_IEXEC) if self.gzip is not None: with tarfile.open(self.path) as tar: - tar.extractall(path=self.gzip_path) + def is_within_directory(directory, target): + + abs_directory = os.path.abspath(directory) + abs_target = os.path.abspath(target) + + prefix = os.path.commonprefix([abs_directory, abs_target]) + + return prefix == abs_directory + + def safe_extract(tar, path=".", members=None, *, numeric_owner=False): + + for member in tar.getmembers(): + member_path = os.path.join(path, member.name) + if not is_within_directory(path, member_path): + raise Exception("Attempted Path Traversal in Tar File") + + tar.extractall(path, members, numeric_owner=numeric_owner) + + + safe_extract(tar, path=self.gzip_path) def download(self): """Download the target file.""" @@ -349,6 +373,12 @@ def call(commands: List[str], env={}, **kwargs): "6eaf86ead73e23988fe192da1db68f4d3828bcdd0f3a9dc195935e339c95dbdc", gzip="tensorflow", ), + "tensorflow-2.10.0": OnlineResource( + "tensorflow-2.10.0.tar.gz", + "https://github.com/tensorflow/tensorflow/archive/refs/tags/v2.10.0.tar.gz", + "b5a1bb04c84b6fe1538377e5a1f649bb5d5f0b2e3625a3c526ff3a8af88633e8", + gzip="tensorflow", + ), } @@ -477,23 +507,46 @@ def cuda_compute_capabilities(self): raise RuntimeError("Unsupported CUDA version") +class BuildROCM(Build): + """Find ROCm.""" + @property + @lru_cache() + def resources(self) -> Dict[str, OnlineResource]: + return {} + + @property + @lru_cache() + def dependencies(self) -> Dict[str, Build]: + return {} + + def build(self): + raise RuntimeError("ROCm is not found!") + + @property + def built(self): + return ROCM_PATH is not None + + class BuildTensorFlow(Build): """Build TensorFlow C++ interface. Parameters ---------- - version : str, default=2.9.1 + version : str TensorFlow version enable_mkl : bool, default=True enable OneDNN enable_cuda : bool, default=False Enable CUDA build + enable_rocm : bool, default=False + Enable ROCm build """ - def __init__(self, version: str ="2.9.1", enable_mkl: bool=True, enable_cuda: bool=False) -> None: + def __init__(self, version: str ="2.9.1", enable_mkl: bool=True, enable_cuda: bool=False, enable_rocm: bool = False) -> None: self.version = version self.enable_mkl = enable_mkl self.enable_cuda = enable_cuda + self.enable_rocm = enable_rocm @property @lru_cache() @@ -508,6 +561,8 @@ def dependencies(self) -> Dict[str, Build]: optional_dep = {} if self.enable_cuda: optional_dep['cuda'] = BuildCUDA() + if self.enable_rocm: + optional_dep['rocm'] = BuildROCM() return { "bazelisk": BuildBazelisk(), "numpy": BuildNumpy(), @@ -520,7 +575,8 @@ def build(self): with set_directory(src): # configure -- need bazelisk in PATH call([str(src / "configure")], env={ - "PATH": list2env([PREFIX / "bin", "/usr/bin"]), + "PATH": list2env([PREFIX / "bin", "/usr/bin", "/bin"]), + "LD_LIBRARY_PATH": os.environ.get("LD_LIBRARY_PATH", ""), **self._environments, }) # bazel build @@ -531,11 +587,11 @@ def build(self): *self._build_opts, *self._build_targets, ], env={ - "PATH": list2env(["/usr/bin"]), + "PATH": list2env(["/usr/bin", "/bin"]), "HOME": os.environ.get("HOME"), "TEST_TMPDIR": str(PACKAGE_DIR / "bazelcache"), # for libstdc++ - "LD_LIBRARY_PATH": os.environ.get("LD_LIBRARY_PATH"), + "LD_LIBRARY_PATH": os.environ.get("LD_LIBRARY_PATH", ""), "CC": str(Path(GCC).resolve()), "CXX": str(Path(GXX).resolve()), }) @@ -603,6 +659,15 @@ def _environments(self) -> dict: cuda_env = { "TF_NEED_CUDA": "0", } + if self.enable_rocm: + rocm_env = { + "TF_NEED_ROCM": "1", + "ROCM_PATH": ROCM_PATH, + } + else: + rocm_env = { + "TF_NEED_ROCM": "0", + } return { "TF_ENABLE_XLA": "1", "CC_OPT_FLAGS": "-Wno-sign-compare", @@ -621,6 +686,7 @@ def _environments(self) -> dict: "TF_SET_ANDROID_WORKSPACE": "0", "TF_CONFIGURE_IOS": "0", ** cuda_env, + ** rocm_env, } @property @@ -674,6 +740,7 @@ def env() -> Dict[str, str]: "Python": sys.executable, "CUDA": CUDA_PATH, "cuDNN": CUDNN_PATH, + "ROCm": ROCM_PATH, "gcc": GCC, "g++": GXX, "Install prefix": PREFIX, @@ -715,10 +782,11 @@ def parse_args(args: Optional[List[str]] = None): default=str(PACKAGE_DIR), help="Path to download packages.", ) - parser.add_argument( + parser_variant = parser.add_mutually_exclusive_group() + parser_variant.add_argument( "--cuda", action='store_true', - help="Enable CUDA for TensorFlow and DeePMD-kit", + help="Enable CUDA for TensorFlow", ) parser.add_argument( "--cuda-path", @@ -732,6 +800,17 @@ def parse_args(args: Optional[List[str]] = None): default=CUDNN_PATH, help="path to cuDNN", ) + parser_variant.add_argument( + "--rocm", + action='store_true', + help="Enable ROCm for TensorFlow", + ) + parser.add_argument( + "--rocm-path", + type=str, + default=ROCM_PATH, + help="path to ROCm Toolkit", + ) parser.add_argument( "--gcc", type=str, @@ -774,6 +853,7 @@ def str_to_path_if_not_none(x: str) -> Path: CPU_COUNT = args.cpus CUDA_PATH = str_to_path_if_not_none(args.cuda_path) CUDNN_PATH = str_to_path_if_not_none(args.cudnn_path) + ROCM_PATH = str_to_path_if_not_none(args.rocm_path) GCC = args.gcc GXX = args.gxx assert GCC is not None @@ -786,7 +866,7 @@ def str_to_path_if_not_none(x: str) -> Path: PREFIX.mkdir(exist_ok=True) # start to build - BuildTensorFlow(enable_cuda=args.cuda)() + BuildTensorFlow(enable_cuda=args.cuda, enable_rocm=args.rocm)() dlog.info("Build TensorFlow C++ Library successfully!") # clean diff --git a/source/install/codecov.sh b/source/install/codecov.sh deleted file mode 100755 index 9a4b7ee29a..0000000000 --- a/source/install/codecov.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -set -e - -#------------------ - -SCRIPT_PATH=$(dirname $(realpath -s $0)) - -#------------------ -# upload to codecov -cd ${SCRIPT_PATH} -bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports" - diff --git a/source/install/docker_package_c.sh b/source/install/docker_package_c.sh new file mode 100755 index 0000000000..d56268700b --- /dev/null +++ b/source/install/docker_package_c.sh @@ -0,0 +1,9 @@ +set -e + +SCRIPT_PATH=$(dirname $(realpath -s $0)) + +docker run --rm -v ${SCRIPT_PATH}/../..:/root/deepmd-kit -w /root/deepmd-kit \ + ghcr.io/deepmodeling/libtensorflow_cc:2.9.2_cuda11.6_centos7_cmake \ + /bin/sh -c "source /opt/rh/devtoolset-10/enable \ + && cd /root/deepmd-kit/source/install \ + && /bin/sh package_c.sh" diff --git a/source/install/docker_test_package_c.sh b/source/install/docker_test_package_c.sh new file mode 100755 index 0000000000..1c1719545b --- /dev/null +++ b/source/install/docker_test_package_c.sh @@ -0,0 +1,15 @@ +# test libdeepmd_c.tar.gz works with gcc 4.9.0, glibc 2.19 +set -e + +SCRIPT_PATH=$(dirname $(realpath -s $0)) + +# assume libdeepmd_c.tar.gz has been created + +wget "https://drive.google.com/uc?export=download&id=1xldLhzm4uSkq6iPohSycNWAsWqKAenKX" -O ${SCRIPT_PATH}/../../examples/infer_water/"graph.pb" + +docker run --rm -v ${SCRIPT_PATH}/../..:/root/deepmd-kit -w /root/deepmd-kit \ + gcc:4.9 \ + /bin/sh -c "tar vxzf libdeepmd_c.tar.gz \ + && cd examples/infer_water \ + && gcc infer_water.c -std=c99 -L ../../libdeepmd_c/lib -I ../../libdeepmd_c/include -Wl,--no-as-needed -ldeepmd_c -Wl,-rpath=../../libdeepmd_c/lib -o infer_water \ + && ./infer_water" diff --git a/source/install/package_c.sh b/source/install/package_c.sh new file mode 100755 index 0000000000..1f0186a724 --- /dev/null +++ b/source/install/package_c.sh @@ -0,0 +1,29 @@ +# package C library into a tarball + +set -e + +SCRIPT_PATH=$(dirname $(realpath -s $0)) +if [ -z "$INSTALL_PREFIX" ] +then + INSTALL_PREFIX=$(realpath -s ${SCRIPT_PATH}/../../dp_c) +fi +mkdir -p ${INSTALL_PREFIX} +echo "Installing DeePMD-kit to ${INSTALL_PREFIX}" +NPROC=$(nproc --all) + +#------------------ + +BUILD_TMP_DIR=${SCRIPT_PATH}/../build_c +mkdir -p ${BUILD_TMP_DIR} +cd ${BUILD_TMP_DIR} +cmake -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \ + -DUSE_CUDA_TOOLKIT=TRUE \ + -DOP_CXX_ABI=0 \ + -DPACKAGE_C=TRUE \ + .. +make -j${NPROC} +make install + +#------------------ + +tar vczf ${SCRIPT_PATH}/../../libdeepmd_c.tar.gz -C ${BUILD_TMP_DIR} libdeepmd_c diff --git a/source/install/test_cc.sh b/source/install/test_cc.sh index 65582e2986..8b3c75e542 100755 --- a/source/install/test_cc.sh +++ b/source/install/test_cc.sh @@ -11,27 +11,16 @@ INSTALL_PREFIX=${SCRIPT_PATH}/../../dp_test BUILD_TMP_DIR=${SCRIPT_PATH}/../build_tests mkdir -p ${BUILD_TMP_DIR} cd ${BUILD_TMP_DIR} -cmake ../lib/tests -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} +cmake -DINSTALL_TENSORFLOW=TRUE -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -DTENSORFLOW_ROOT=${INSTALL_PREFIX} -DBUILD_TESTING:BOOL=TRUE -DLAMMPS_VERSION=stable_23Jun2022_update2 .. make -j${NPROC} make install #------------------ -${INSTALL_PREFIX}/bin/runUnitTests - - -#------------------ - -BUILD_TMP_DIR=${SCRIPT_PATH}/../build_cc_tests -INSTALL_PREFIX=${SCRIPT_PATH}/../../dp_test_cc -mkdir -p ${BUILD_TMP_DIR} -mkdir -p ${INSTALL_PREFIX} -cd ${BUILD_TMP_DIR} -cmake -DINSTALL_TENSORFLOW=TRUE -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -DTENSORFLOW_ROOT=${INSTALL_PREFIX} ../api_cc/tests -make -j${NPROC} -make install - -#------------------ -cd ${SCRIPT_PATH}/../api_cc/tests -${INSTALL_PREFIX}/bin/runUnitTests - - +# go to a subdirectory... +# TODO: detect directory of graph files +mkdir -p ${BUILD_TMP_DIR}/exec_tests +cd ${BUILD_TMP_DIR}/exec_tests + +${INSTALL_PREFIX}/bin/runUnitTests_lib +${INSTALL_PREFIX}/bin/runUnitTests_cc +${INSTALL_PREFIX}/bin/runUnitTests_c diff --git a/source/install/test_cc_local.sh b/source/install/test_cc_local.sh index e5a1070186..1d0d9381b5 100755 --- a/source/install/test_cc_local.sh +++ b/source/install/test_cc_local.sh @@ -5,30 +5,23 @@ set -e SCRIPT_PATH=$(dirname $(realpath -s $0)) NPROC=$(nproc --all) -#------------------ -INSTALL_PREFIX=${SCRIPT_PATH}/../../dp_test -BUILD_TMP_DIR=${SCRIPT_PATH}/../build_tests -mkdir -p ${BUILD_TMP_DIR} -cd ${BUILD_TMP_DIR} -cmake ../lib/tests -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -make -j${NPROC} -make install - -#------------------ -${INSTALL_PREFIX}/bin/runUnitTests - - #------------------ echo "try to find tensorflow in ${tensorflow_root}" -BUILD_TMP_DIR=${SCRIPT_PATH}/../build_cc_tests -INSTALL_PREFIX=${SCRIPT_PATH}/../../dp_test_cc +INSTALL_PREFIX=${SCRIPT_PATH}/../../dp_test +BUILD_TMP_DIR=${SCRIPT_PATH}/../build_tests mkdir -p ${BUILD_TMP_DIR} cd ${BUILD_TMP_DIR} -cmake -DINSTALL_TENSORFLOW=FALSE -DTENSORFLOW_ROOT=${tensorflow_root} ../api_cc/tests -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} +cmake -DINSTALL_TENSORFLOW=FALSE -DTENSORFLOW_ROOT=${tensorflow_root} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -DBUILD_TESTING:BOOL=TRUE -DLAMMPS_VERSION=stable_23Jun2022_update2 .. make -j${NPROC} make install #------------------ -cd ${SCRIPT_PATH}/../api_cc/tests -${INSTALL_PREFIX}/bin/runUnitTests +# go to a subdirectory... +# TODO: detect directory of graph files +mkdir -p ${BUILD_TMP_DIR}/exec_tests +cd ${BUILD_TMP_DIR}/exec_tests + +${INSTALL_PREFIX}/bin/runUnitTests_lib +${INSTALL_PREFIX}/bin/runUnitTests_cc +${INSTALL_PREFIX}/bin/runUnitTests_c diff --git a/source/ipi/CMakeLists.txt b/source/ipi/CMakeLists.txt index d71a904e36..e31e5ddce0 100644 --- a/source/ipi/CMakeLists.txt +++ b/source/ipi/CMakeLists.txt @@ -13,9 +13,17 @@ target_include_directories(${libipiname} PUBLIC ${MD_INCLUDE_PATH}) set(DRIVER_SOURCE_FILES driver.cc) add_executable(${ipiname} ${DRIVER_SOURCE_FILES}) # link: libdeepmd_cc -target_link_libraries(${ipiname} PRIVATE ${libipiname} ${LIB_DEEPMD_CC}${variant_name}) +target_link_libraries(${ipiname} PRIVATE ${libipiname} ${LIB_DEEPMD_CC}) target_include_directories(${ipiname} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/) +if (APPLE) + set_target_properties( + ${ipiname} + PROPERTIES + INSTALL_RPATH "@loader_path/../lib:${TensorFlow_LIBRARY_PATH}" + COMPILE_DEFINITIONS ${prec_def} + ) +else() set_target_properties( ${ipiname} PROPERTIES @@ -23,7 +31,9 @@ set_target_properties( INSTALL_RPATH "$ORIGIN/../lib:${TensorFlow_LIBRARY_PATH}" COMPILE_DEFINITIONS ${prec_def} ) +endif() +if(BUILD_PY_IF) install( TARGETS ${libipiname} DESTINATION lib/ @@ -32,6 +42,16 @@ install( TARGETS ${ipiname} DESTINATION bin/ ) +else(BUILD_PY_IF) + install( + TARGETS ${libipiname} + DESTINATION deepmd/op/ + ) + install( + TARGETS ${ipiname} + DESTINATION deepmd/op/ + ) +endif(BUILD_PY_IF) endfunction() _add_ipi_variant("${HIGH_PREC_VARIANT}" "${HIGH_PREC_DEF}") _add_ipi_variant("${LOW_PREC_VARIANT}" "${LOW_PREC_DEF}") \ No newline at end of file diff --git a/source/lib/CMakeLists.txt b/source/lib/CMakeLists.txt index 251f87053f..5902b78a61 100644 --- a/source/lib/CMakeLists.txt +++ b/source/lib/CMakeLists.txt @@ -5,15 +5,23 @@ file(GLOB LIB_SRC src/*.cc src/*.cpp) file(GLOB INC_SRC include/*.h ${CMAKE_CURRENT_BINARY_DIR}/version.h) add_library(${libname} SHARED ${LIB_SRC}) -target_include_directories(${libname} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_include_directories( + ${libname} PUBLIC + $ + $ +) if (USE_CUDA_TOOLKIT) add_definitions("-DGOOGLE_CUDA") add_subdirectory(src/cuda) set (EXTRA_LIBS ${EXTRA_LIBS} deepmd_op_cuda) - target_link_libraries (${libname} INTERFACE ${CUDA_LIBRARIES} ${EXTRA_LIBS}) + target_link_libraries (${libname} INTERFACE deepmd_dyn_cudart ${EXTRA_LIBS}) # gpu_cuda.h - target_include_directories(${libname} PUBLIC ${CUDA_INCLUDE_DIRS}) + target_include_directories( + ${libname} PUBLIC + $ + $ + ) endif() if (USE_ROCM_TOOLKIT) @@ -22,19 +30,33 @@ if (USE_ROCM_TOOLKIT) set (EXTRA_LIBS ${EXTRA_LIBS} deepmd_op_rocm) target_link_libraries (${libname} INTERFACE ${ROCM_LIBRARIES} ${EXTRA_LIBS}) # gpu_rocm.h - target_include_directories(${libname} PUBLIC ${ROCM_INCLUDE_DIRS}) + target_include_directories( + ${libname} PUBLIC + $ + $ + ) endif() set_target_properties(${libname} PROPERTIES INSTALL_RPATH $ORIGIN) +if (CMAKE_TESTING_ENABLED) + target_link_libraries(${libname} PRIVATE coverage_config) +endif() + if(BUILD_PY_IF) install(TARGETS ${libname} DESTINATION deepmd/op/) -endif(BUILD_PY_IF) -if(BUILD_CPP_IF) - install(TARGETS ${libname} DESTINATION lib/) +else(BUILD_PY_IF) + install( + TARGETS + ${libname} + EXPORT ${CMAKE_PROJECT_NAME}Targets + DESTINATION lib/) install( FILES ${INC_SRC} DESTINATION include/deepmd ) -endif(BUILD_CPP_IF) +endif(BUILD_PY_IF) +if (BUILD_CPP_IF AND CMAKE_TESTING_ENABLED) + add_subdirectory(tests) +endif() diff --git a/source/lib/include/SimulationRegion_Impl.h b/source/lib/include/SimulationRegion_Impl.h index 528402b7d6..341ae8f1dd 100644 --- a/source/lib/include/SimulationRegion_Impl.h +++ b/source/lib/include/SimulationRegion_Impl.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "errors.h" // using namespace std; @@ -501,10 +502,8 @@ computeVolume() boxt[0*3+0] * (boxt[1*3+1]*boxt[2*3+2] - boxt[2*3+1]*boxt[1*3+2]) - boxt[0*3+1] * (boxt[1*3+0]*boxt[2*3+2] - boxt[2*3+0]*boxt[1*3+2]) + boxt[0*3+2] * (boxt[1*3+0]*boxt[2*3+1] - boxt[2*3+0]*boxt[1*3+1]); - volumei = static_cast(1.)/volume; - if (volume < 0) { - throw deepmd::deepmd_exception("Negative volume detected. Please make sure the simulation cell obeys the right-hand rule."); - } + volume = std::abs(volume); + volumei = static_cast(1.)/volume; } template diff --git a/source/lib/include/switcher.h b/source/lib/include/switcher.h index 606b3c3196..e4d800bd14 100644 --- a/source/lib/include/switcher.h +++ b/source/lib/include/switcher.h @@ -76,18 +76,18 @@ spline5_switch ( const float & rmax) { if (xx < rmin) { - dd = 0; - vv = 1; + dd = (FPTYPE)0.; + vv = (FPTYPE)1.; } else if (xx < rmax) { FPTYPE uu = (xx - rmin) / (rmax - rmin) ; - FPTYPE du = 1. / (rmax - rmin) ; - vv = uu*uu*uu * (-6 * uu*uu + 15 * uu - 10) + 1; - dd = ( 3 * uu*uu * (-6 * uu*uu + 15 * uu - 10) + uu*uu*uu * (-12 * uu + 15) ) * du; + FPTYPE du = (FPTYPE)1. / (rmax - rmin) ; + vv = uu*uu*uu * ((FPTYPE)-6. * uu*uu + (FPTYPE)15. * uu - (FPTYPE)10.) + (FPTYPE)1.; + dd = ( (FPTYPE)3. * uu*uu * ((FPTYPE)-6. * uu*uu + (FPTYPE)15. * uu - (FPTYPE)10.) + uu*uu*uu * ((FPTYPE)-12. * uu + (FPTYPE)15.) ) * du; } else { - dd = 0; - vv = 0; + dd = (FPTYPE)0.; + vv = (FPTYPE)0.; } } diff --git a/source/lib/src/cuda/CMakeLists.txt b/source/lib/src/cuda/CMakeLists.txt index 2cf2d59a1a..8ba570a3f9 100644 --- a/source/lib/src/cuda/CMakeLists.txt +++ b/source/lib/src/cuda/CMakeLists.txt @@ -1,5 +1,5 @@ # required cmake version -cmake_minimum_required(VERSION 3.7) +cmake_minimum_required(VERSION 3.16) # project name project(deepmd_op_cuda) @@ -9,6 +9,12 @@ if (NOT CUDA_FOUND) message(STATUS "CUDA not found. Project will not be built.") endif(NOT CUDA_FOUND) +# take dynamic open cudart library replace of static one +# so it's not required when using CPUs +add_subdirectory(cudart) +# important: it must be before cuda_add_library and any link target to cudart +set(CUDA_LIBRARIES deepmd_dyn_cudart) + # set c++ version c++11 SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CUDA_STANDARD 11) @@ -28,6 +34,7 @@ if (${CUDA_VERSION_MAJOR} GREATER "11" OR (${CUDA_VERSION_MAJOR} STREQUAL "11" A # nvcc flags set(CUDA_NVCC_FLAGS -arch=all; # embeds a compiled code image for all supported architectures (sm_*), and a PTX program for the highest major virtual architecture -O3; -Xcompiler -fPIC; + ${CUDA_NVCC_FLAGS} ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "11" AND ${CUDA_VERSION_MINOR} GREATER "0") # nvcc flags @@ -40,6 +47,7 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "11" AND ${CUDA_VERSION_MINOR} GREATER "0 -gencode arch=compute_80,code=sm_80; # Anpere - A100 -gencode arch=compute_86,code=sm_86; # Anpere - RTX 3090 -O3; -Xcompiler -fPIC; + ${CUDA_NVCC_FLAGS} ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "11" AND ${CUDA_VERSION_MINOR} STREQUAL "0") # nvcc flags @@ -51,6 +59,7 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "11" AND ${CUDA_VERSION_MINOR} STREQUAL " -gencode arch=compute_75,code=sm_75; # Turing - RTX 2080, Titan RTX, Quadro R8000 -gencode arch=compute_80,code=sm_80; # Anpere - A100 -O3; -Xcompiler -fPIC; + ${CUDA_NVCC_FLAGS} ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "10") set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; # Tesla K10, Quadro K600 K420 K410, @@ -64,6 +73,7 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "10") -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) -gencode arch=compute_75,code=sm_75; # Turing - RTX 2080, Titan RTX, Quadro R8000 -O3; -Xcompiler -fPIC; + ${CUDA_NVCC_FLAGS} ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "9") set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; @@ -76,6 +86,7 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "9") -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 -gencode arch=compute_70,code=sm_70; # Volta - GV100/Tesla V100, GTX 1180 (GV104) -O3; -Xcompiler -fPIC; + ${CUDA_NVCC_FLAGS} ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "8") set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; @@ -87,6 +98,7 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "8") -gencode arch=compute_60,code=sm_60; # Pascal – GP100/Tesla P100 – DGX-1 (Generic Pascal) -gencode arch=compute_61,code=sm_61; # Pascal - GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030, Titan Xp, Tesla P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2 -O3; -Xcompiler -fPIC; + ${CUDA_NVCC_FLAGS} ) elseif (${CUDA_VERSION_MAJOR} STREQUAL "7") set(CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30; @@ -96,6 +108,7 @@ elseif (${CUDA_VERSION_MAJOR} STREQUAL "7") -gencode arch=compute_52,code=sm_52; # Tesla M40, Tesla M40, Quadro M6000... -gencode arch=compute_53,code=sm_53; -O3; -Xcompiler -fPIC; + ${CUDA_NVCC_FLAGS} ) else () message(FATAL_ERROR "unsupported CUDA_VERSION " ${CUDA_VERSION} ", please use a newer version (>=7.0) of CUDA toolkit!") @@ -116,10 +129,33 @@ endif() file (GLOB SOURCE_FILES "*.cu" ) cuda_add_library(deepmd_op_cuda SHARED ${SOURCE_FILES}) -target_include_directories(deepmd_op_cuda PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include/) +target_include_directories( + deepmd_op_cuda + PUBLIC + $ + $ +) +target_precompile_headers(deepmd_op_cuda PUBLIC [["device.h"]]) +if(APPLE) + set_target_properties( + deepmd_op_cuda + PROPERTIES + INSTALL_RPATH @loader_path + ) +else() + set_target_properties( + deepmd_op_cuda + PROPERTIES + INSTALL_RPATH "$ORIGIN" + ) +endif() if (BUILD_CPP_IF) - install(TARGETS deepmd_op_cuda DESTINATION lib/) + install( + TARGETS deepmd_op_cuda + EXPORT ${CMAKE_PROJECT_NAME}Targets + DESTINATION lib/ + ) endif (BUILD_CPP_IF) if (BUILD_PY_IF) install(TARGETS deepmd_op_cuda DESTINATION deepmd/op/) diff --git a/source/lib/src/cuda/cudart/CMakeLists.txt b/source/lib/src/cuda/cudart/CMakeLists.txt new file mode 100644 index 0000000000..07953381c9 --- /dev/null +++ b/source/lib/src/cuda/cudart/CMakeLists.txt @@ -0,0 +1,24 @@ +add_library(deepmd_dyn_cudart SHARED cudart_stub.cc) +target_include_directories( + deepmd_dyn_cudart + PUBLIC + ${CUDA_INCLUDE_DIRS} +) +get_filename_component(CUDA_LIBRARY_DIR ${CUDA_cudart_static_LIBRARY} DIRECTORY) +set_target_properties( + deepmd_dyn_cudart + PROPERTIES + INSTALL_RPATH "${CUDA_LIBRARY_DIR}" +) +if(BUILD_CPP_IF) + install( + TARGETS + deepmd_dyn_cudart + EXPORT ${CMAKE_PROJECT_NAME}Targets + DESTINATION lib/ + ) +endif (BUILD_CPP_IF) +if (BUILD_PY_IF) + install(TARGETS deepmd_dyn_cudart DESTINATION deepmd/op/) +endif (BUILD_PY_IF) + \ No newline at end of file diff --git a/source/lib/src/cuda/cudart/cuda_runtime_10_0.inc b/source/lib/src/cuda/cudart/cuda_runtime_10_0.inc new file mode 100644 index 0000000000..6810c05d67 --- /dev/null +++ b/source/lib/src/cuda/cudart/cuda_runtime_10_0.inc @@ -0,0 +1,1846 @@ +// Auto-generated, do not edit. + +extern "C" { + +extern __host__ cudaError_t CUDARTAPI cudaDeviceReset(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceReset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceSetLimit(enum cudaLimit limit, + size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaDeviceSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaDeviceGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaDeviceGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetStreamPriorityRange(int *leastPriority, int *greatestPriority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int *); + static auto func_ptr = + LoadSymbol("cudaDeviceGetStreamPriorityRange"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(leastPriority, greatestPriority); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaDeviceSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetSharedMemConfig(enum cudaSharedMemConfig *pConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig *); + static auto func_ptr = LoadSymbol("cudaDeviceGetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetSharedMemConfig(enum cudaSharedMemConfig config) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaDeviceSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(config); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetByPCIBusId(int *device, const char *pciBusId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const char *); + static auto func_ptr = LoadSymbol("cudaDeviceGetByPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, pciBusId); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceGetPCIBusId(char *pciBusId, + int len, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(char *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pciBusId, len, device); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetEventHandle(cudaIpcEventHandle_t *handle, cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcEventHandle_t *, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaIpcGetEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcOpenEventHandle(cudaEvent_t *event, cudaIpcEventHandle_t handle) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, cudaIpcEventHandle_t); + static auto func_ptr = LoadSymbol("cudaIpcOpenEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, handle); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetMemHandle(cudaIpcMemHandle_t *handle, void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcMemHandle_t *, void *); + static auto func_ptr = LoadSymbol("cudaIpcGetMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcOpenMemHandle( + void **devPtr, cudaIpcMemHandle_t handle, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaIpcMemHandle_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaIpcOpenMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, handle, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcCloseMemHandle(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaIpcCloseMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaThreadExit(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadExit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetLimit(enum cudaLimit limit, size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaThreadSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaThreadGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaThreadGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaThreadSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaGetLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaPeekAtLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaPeekAtLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorName(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorName"); + if (!func_ptr) return "cudaGetErrorName symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorString(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorString"); + if (!func_ptr) return "cudaGetErrorString symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceCount(int *count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceCount"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaDeviceProp *, int); + static auto func_ptr = LoadSymbol("cudaGetDeviceProperties"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(prop, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetAttribute(int *value, enum cudaDeviceAttr attr, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceAttr, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetP2PAttribute(int *value, enum cudaDeviceP2PAttr attr, + int srcDevice, int dstDevice) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceP2PAttr, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetP2PAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, srcDevice, dstDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaChooseDevice(int *device, const struct cudaDeviceProp *prop) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const struct cudaDeviceProp *); + static auto func_ptr = LoadSymbol("cudaChooseDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, prop); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDevice(int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaSetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDevice(int *device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetValidDevices(int *device_arr, + int len) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int); + static auto func_ptr = LoadSymbol("cudaSetValidDevices"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device_arr, len); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDeviceFlags(unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int); + static auto func_ptr = LoadSymbol("cudaSetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetDeviceFlags(unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamCreate(cudaStream_t *pStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *); + static auto func_ptr = LoadSymbol("cudaStreamCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithFlags(cudaStream_t *pStream, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithPriority(cudaStream_t *pStream, unsigned int flags, + int priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int, int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetPriority(cudaStream_t hStream, int *priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, int *); + static auto func_ptr = LoadSymbol("cudaStreamGetPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetFlags(cudaStream_t hStream, unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, unsigned int *); + static auto func_ptr = LoadSymbol("cudaStreamGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamDestroy(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaStreamWaitEvent( + cudaStream_t stream, cudaEvent_t event, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, cudaEvent_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamWaitEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, event, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamAddCallback(cudaStream_t stream, cudaStreamCallback_t callback, + void *userData, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaStreamCallback_t, + void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAddCallback"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, callback, userData, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamSynchronize(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamQuery(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamAttachMemAsync(cudaStream_t stream, void *devPtr, + size_t length __dv(0), + unsigned int flags __dv(cudaMemAttachSingle)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAttachMemAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, devPtr, length, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamBeginCapture(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamBeginCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamEndCapture(cudaStream_t stream, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaStreamEndCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamIsCapturing( + cudaStream_t stream, enum cudaStreamCaptureStatus *pCaptureStatus) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamCaptureStatus *); + static auto func_ptr = LoadSymbol("cudaStreamIsCapturing"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pCaptureStatus); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventCreate(cudaEvent_t *event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *); + static auto func_ptr = LoadSymbol("cudaEventCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventCreateWithFlags(cudaEvent_t *event, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaEventCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventRecord(cudaEvent_t event, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaEventRecord"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventQuery(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventSynchronize(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventDestroy(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventElapsedTime(float *ms, + cudaEvent_t start, + cudaEvent_t end) { + using FuncPtr = cudaError_t(CUDARTAPI *)(float *, cudaEvent_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventElapsedTime"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ms, start, end); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalMemory( + cudaExternalMemory_t *extMem_out, + const struct cudaExternalMemoryHandleDesc *memHandleDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaExternalMemory_t *, const struct cudaExternalMemoryHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem_out, memHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedBuffer( + void **devPtr, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryBufferDesc *bufferDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaExternalMemory_t, + const struct cudaExternalMemoryBufferDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedBuffer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, extMem, bufferDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmap, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryMipmappedArrayDesc *mipmapDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, cudaExternalMemory_t, + const struct cudaExternalMemoryMipmappedArrayDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmap, extMem, mipmapDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalMemory(cudaExternalMemory_t extMem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalMemory_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalSemaphore( + cudaExternalSemaphore_t *extSem_out, + const struct cudaExternalSemaphoreHandleDesc *semHandleDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem_out, semHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaSignalExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreSignalParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreSignalParams *, + unsigned int, cudaStream_t); + static auto func_ptr = + LoadSymbol("cudaSignalExternalSemaphoresAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaWaitExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreWaitParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreWaitParams *, + unsigned int, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaWaitExternalSemaphoresAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalSemaphore(cudaExternalSemaphore_t extSem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem); +} + +extern __host__ cudaError_t CUDARTAPI +cudaLaunchKernel(const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernel( + const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchCooperativeKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernelMultiDevice( + struct cudaLaunchParams *launchParamsList, unsigned int numDevices, + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaLaunchParams *, + unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaLaunchCooperativeKernelMultiDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(launchParamsList, numDevices, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetCacheConfig(const void *func, enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaFuncSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, cacheConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetSharedMemConfig(const void *func, enum cudaSharedMemConfig config) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaFuncSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, config); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncGetAttributes(struct cudaFuncAttributes *attr, const void *func) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaFuncAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaFuncGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attr, func); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncSetAttribute(const void *func, enum cudaFuncAttribute attr, int value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncAttribute, int); + static auto func_ptr = LoadSymbol("cudaFuncSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, attr, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForDevice(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForHost(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchHostFunc(cudaStream_t stream, + cudaHostFn_t fn, + void *userData) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaHostFn_t, void *); + static auto func_ptr = LoadSymbol("cudaLaunchHostFunc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, fn, userData); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessor(int *numBlocks, const void *func, + int blockSize, + size_t dynamicSMemSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t); + static auto func_ptr = + LoadSymbol("cudaOccupancyMaxActiveBlocksPerMultiprocessor"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(int *numBlocks, + const void *func, + int blockSize, + size_t dynamicSMemSize, + unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t, unsigned int); + static auto func_ptr = LoadSymbol( + "cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaConfigureCall(dim3 gridDim, dim3 blockDim, size_t sharedMem __dv(0), + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(dim3, dim3, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaConfigureCall"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(gridDim, blockDim, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetupArgument(const void *arg, + size_t size, + size_t offset) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaSetupArgument"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(arg, size, offset); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunch(const void *func) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *); + static auto func_ptr = LoadSymbol("cudaLaunch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMallocManaged( + void **devPtr, size_t size, unsigned int flags __dv(cudaMemAttachGlobal)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocManaged"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMalloc(void **devPtr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMalloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocHost(void **ptr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMallocHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocPitch(void **devPtr, + size_t *pitch, + size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t *, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMallocPitch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocArray( + cudaArray_t *array, const struct cudaChannelFormatDesc *desc, size_t width, + size_t height __dv(0), unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + size_t, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, width, height, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFree(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFree"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeHost(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFreeHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeArray(cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t); + static auto func_ptr = LoadSymbol("cudaFreeArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFreeMipmappedArray(cudaMipmappedArray_t mipmappedArray) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t); + static auto func_ptr = LoadSymbol("cudaFreeMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostAlloc(void **pHost, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostAlloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pHost, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostRegister(void *ptr, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostRegister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostUnregister(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaHostUnregister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostGetDevicePointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pDevice, pHost, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostGetFlags(unsigned int *pFlags, + void *pHost) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *, void *); + static auto func_ptr = LoadSymbol("cudaHostGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pFlags, pHost); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3D(struct cudaPitchedPtr *pitchedDevPtr, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr *, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMalloc3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, extent); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3DArray(cudaArray_t *array, const struct cudaChannelFormatDesc *desc, + struct cudaExtent extent, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int); + static auto func_ptr = LoadSymbol("cudaMalloc3DArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, extent, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, + const struct cudaChannelFormatDesc *desc, struct cudaExtent extent, + unsigned int numLevels, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, desc, extent, numLevels, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetMipmappedArrayLevel( + cudaArray_t *levelArray, cudaMipmappedArray_const_t mipmappedArray, + unsigned int level) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaMipmappedArray_const_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGetMipmappedArrayLevel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(levelArray, mipmappedArray, level); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3D(const struct cudaMemcpy3DParms *p) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3DPeer(const struct cudaMemcpy3DPeerParms *p) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy3DAsync( + const struct cudaMemcpy3DParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy3DPeerAsync( + const struct cudaMemcpy3DPeerParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemGetInfo(size_t *free, + size_t *total) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaMemGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(free, total); +} + +extern __host__ cudaError_t CUDARTAPI +cudaArrayGetInfo(struct cudaChannelFormatDesc *desc, struct cudaExtent *extent, + unsigned int *flags, cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + struct cudaExtent *, unsigned int *, + cudaArray_t); + static auto func_ptr = LoadSymbol("cudaArrayGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, extent, flags, array); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy(void *dst, const void *src, + size_t count, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyPeer(void *dst, int dstDevice, + const void *src, + int srcDevice, + size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, int, const void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, + const void *src, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t, size_t, size_t, const void *, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArray(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t count, + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, cudaArray_const_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2D(void *dst, size_t dpitch, + const void *src, + size_t spitch, size_t width, + size_t height, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArray( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArray( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, size_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t width, + size_t height, enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + cudaArray_const_t, size_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbol( + const void *symbol, const void *src, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyHostToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, + size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbol( + void *dst, const void *symbol, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToHost)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemcpyAsync(void *dst, const void *src, size_t count, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyPeerAsync(void *dst, int dstDevice, const void *src, int srcDevice, + size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, const void *, int, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t count, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromArrayAsync( + void *dst, cudaArray_const_t src, size_t wOffset, size_t hOffset, + size_t count, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy2DAsync( + void *dst, size_t dpitch, const void *src, size_t spitch, size_t width, + size_t height, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + const void *, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArrayAsync( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, + size_t, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbolAsync( + const void *symbol, const void *src, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbolAsync( + void *dst, const void *symbol, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset(void *devPtr, int value, + size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset2D(void *devPtr, size_t pitch, + int value, size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMemset2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset3D( + struct cudaPitchedPtr pitchedDevPtr, int value, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMemset3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemsetAsync( + void *devPtr, int value, size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemsetAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset2DAsync(void *devPtr, size_t pitch, int value, size_t width, + size_t height, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset3DAsync(struct cudaPitchedPtr pitchedDevPtr, int value, + struct cudaExtent extent, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, + struct cudaExtent, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolAddress(void **devPtr, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolAddress"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolSize(size_t *size, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolSize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(size, symbol); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPrefetchAsync(const void *devPtr, size_t count, int dstDevice, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, size_t, int, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemPrefetchAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, dstDevice, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemAdvise(const void *devPtr, size_t count, enum cudaMemoryAdvise advice, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, size_t, + enum cudaMemoryAdvise, int); + static auto func_ptr = LoadSymbol("cudaMemAdvise"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, advice, device); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttribute( + void *data, size_t dataSize, enum cudaMemRangeAttribute attribute, + const void *devPtr, size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + void *, size_t, enum cudaMemRangeAttribute, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSize, attribute, devPtr, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttributes( + void **data, size_t *dataSizes, enum cudaMemRangeAttribute *attributes, + size_t numAttributes, const void *devPtr, size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, enum cudaMemRangeAttribute *, + size_t, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSizes, attributes, numAttributes, devPtr, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaPointerGetAttributes( + struct cudaPointerAttributes *attributes, const void *ptr) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPointerAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaPointerGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attributes, ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceCanAccessPeer(int *canAccessPeer, int device, int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceCanAccessPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(canAccessPeer, device, peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceEnablePeerAccess(int peerDevice, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int, unsigned int); + static auto func_ptr = LoadSymbol("cudaDeviceEnablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceDisablePeerAccess(int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaDeviceDisablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsUnregisterResource(cudaGraphicsResource_t resource) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnregisterResource"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceSetMapFlags( + cudaGraphicsResource_t resource, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphicsResourceSetMapFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsMapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsMapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsUnmapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnmapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceGetMappedPointer( + void **devPtr, size_t *size, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsSubResourceGetMappedArray( + cudaArray_t *array, cudaGraphicsResource_t resource, + unsigned int arrayIndex, unsigned int mipLevel) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaGraphicsResource_t, unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaGraphicsSubResourceGetMappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, resource, arrayIndex, mipLevel); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsResourceGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetChannelDesc( + struct cudaChannelFormatDesc *desc, cudaArray_const_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + cudaArray_const_t); + static auto func_ptr = LoadSymbol("cudaGetChannelDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, array); +} + +extern __host__ struct cudaChannelFormatDesc CUDARTAPI cudaCreateChannelDesc( + int x, int y, int z, int w, enum cudaChannelFormatKind f) { + using FuncPtr = struct cudaChannelFormatDesc(CUDARTAPI *)( + int, int, int, int, enum cudaChannelFormatKind); + static auto func_ptr = LoadSymbol("cudaCreateChannelDesc"); + if (!func_ptr) { + return cudaChannelFormatDesc{cudaChannelFormatKind(-1), 0, 0, 0}; + } + return func_ptr(x, y, z, w, f); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindTexture( + size_t *offset, const struct textureReference *texref, const void *devPtr, + const struct cudaChannelFormatDesc *desc, size_t size __dv(UINT_MAX)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, size); +} + +extern __host__ cudaError_t CUDARTAPI +cudaBindTexture2D(size_t *offset, const struct textureReference *texref, + const void *devPtr, const struct cudaChannelFormatDesc *desc, + size_t width, size_t height, size_t pitch) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, width, height, pitch); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindTextureToArray( + const struct textureReference *texref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, array, desc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaBindTextureToMipmappedArray(const struct textureReference *texref, + cudaMipmappedArray_const_t mipmappedArray, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaMipmappedArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, mipmappedArray, desc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaUnbindTexture(const struct textureReference *texref) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaUnbindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureAlignmentOffset( + size_t *offset, const struct textureReference *texref) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(size_t *, const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaGetTextureAlignmentOffset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureReference( + const struct textureReference **texref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct textureReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetTextureReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindSurfaceToArray( + const struct surfaceReference *surfref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct surfaceReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindSurfaceToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, array, desc); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceReference( + const struct surfaceReference **surfref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct surfaceReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSurfaceReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateTextureObject( + cudaTextureObject_t *pTexObject, const struct cudaResourceDesc *pResDesc, + const struct cudaTextureDesc *pTexDesc, + const struct cudaResourceViewDesc *pResViewDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaTextureObject_t *, const struct cudaResourceDesc *, + const struct cudaTextureDesc *, const struct cudaResourceViewDesc *); + static auto func_ptr = LoadSymbol("cudaCreateTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexObject, pResDesc, pTexDesc, pResViewDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyTextureObject(cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaDestroyTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectTextureDesc( + struct cudaTextureDesc *pTexDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaTextureDesc *, cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaGetTextureObjectTextureDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceViewDesc( + struct cudaResourceViewDesc *pResViewDesc, cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaResourceViewDesc *, + cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceViewDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResViewDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateSurfaceObject( + cudaSurfaceObject_t *pSurfObject, const struct cudaResourceDesc *pResDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t *, + const struct cudaResourceDesc *); + static auto func_ptr = LoadSymbol("cudaCreateSurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pSurfObject, pResDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroySurfaceObject(cudaSurfaceObject_t surfObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t); + static auto func_ptr = LoadSymbol("cudaDestroySurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaSurfaceObject_t surfObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaSurfaceObject_t); + static auto func_ptr = + LoadSymbol("cudaGetSurfaceObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaDriverGetVersion(int *driverVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaDriverGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(driverVersion); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaRuntimeGetVersion(int *runtimeVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaRuntimeGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(runtimeVersion); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphCreate(cudaGraph_t *pGraph, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraph, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddKernelNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + cudaGraphNode_t *, size_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddKernelNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeGetParams( + cudaGraphNode_t node, struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeSetParams( + cudaGraphNode_t node, const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddMemcpyNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemcpy3DParms *pCopyParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + cudaGraphNode_t *, size_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemcpyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pCopyParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeGetParams( + cudaGraphNode_t node, struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeSetParams( + cudaGraphNode_t node, const struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddMemsetNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemsetParams *pMemsetParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + cudaGraphNode_t *, size_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemsetNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pMemsetParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeGetParams( + cudaGraphNode_t node, struct cudaMemsetParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeSetParams( + cudaGraphNode_t node, const struct cudaMemsetParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddHostNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + cudaGraphNode_t *, size_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddHostNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeGetParams( + cudaGraphNode_t node, struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeSetParams( + cudaGraphNode_t node, const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddChildGraphNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + cudaGraphNode_t *pDependencies, + size_t numDependencies, cudaGraph_t childGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t *, cudaGraph_t, cudaGraphNode_t *, size_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphAddChildGraphNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + childGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphChildGraphNodeGetGraph(cudaGraphNode_t node, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaGraphChildGraphNodeGetGraph"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddEmptyNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + cudaGraphNode_t *pDependencies, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddEmptyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphClone(cudaGraph_t *pGraphClone, cudaGraph_t originalGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphClone, originalGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeFindInClone(cudaGraphNode_t *pNode, cudaGraphNode_t originalNode, + cudaGraph_t clonedGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraphNode_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphNodeFindInClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pNode, originalNode, clonedGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeGetType(cudaGraphNode_t node, enum cudaGraphNodeType *pType) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, enum cudaGraphNodeType *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetType"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pType); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetNodes(cudaGraph_t graph, + cudaGraphNode_t *nodes, + size_t *numNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, nodes, numNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetRootNodes( + cudaGraph_t graph, cudaGraphNode_t *pRootNodes, size_t *pNumRootNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetRootNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, pRootNodes, pNumRootNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetEdges(cudaGraph_t graph, + cudaGraphNode_t *from, + cudaGraphNode_t *to, + size_t *numEdges) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, + cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetEdges"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numEdges); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependencies( + cudaGraphNode_t node, cudaGraphNode_t *pDependencies, + size_t *pNumDependencies) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependencies, pNumDependencies); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependentNodes( + cudaGraphNode_t node, cudaGraphNode_t *pDependentNodes, + size_t *pNumDependentNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependentNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependentNodes, pNumDependentNodes); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddDependencies(cudaGraph_t graph, cudaGraphNode_t *from, + cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, + cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphRemoveDependencies(cudaGraph_t graph, cudaGraphNode_t *from, + cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, + cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphRemoveDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphDestroyNode(cudaGraphNode_t node) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphInstantiate( + cudaGraphExec_t *pGraphExec, cudaGraph_t graph, cudaGraphNode_t *pErrorNode, + char *pLogBuffer, size_t bufferSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t *, cudaGraph_t, + cudaGraphNode_t *, char *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphInstantiate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphExec, graph, pErrorNode, pLogBuffer, bufferSize); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphLaunch(cudaGraphExec_t graphExec, + cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphLaunch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecDestroy(cudaGraphExec_t graphExec) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t); + static auto func_ptr = LoadSymbol("cudaGraphExecDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphDestroy(cudaGraph_t graph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetExportTable( + const void **ppExportTable, const cudaUUID_t *pExportTableId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void **, const cudaUUID_t *); + static auto func_ptr = LoadSymbol("cudaGetExportTable"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ppExportTable, pExportTableId); +} + +} // extern "C" diff --git a/source/lib/src/cuda/cudart/cuda_runtime_10_1.inc b/source/lib/src/cuda/cudart/cuda_runtime_10_1.inc new file mode 100644 index 0000000000..d076cc4ac3 --- /dev/null +++ b/source/lib/src/cuda/cudart/cuda_runtime_10_1.inc @@ -0,0 +1,1854 @@ +// Auto-generated, do not edit. + +extern "C" { + +extern __host__ cudaError_t CUDARTAPI cudaDeviceReset(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceReset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceSetLimit(enum cudaLimit limit, + size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaDeviceSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaDeviceGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaDeviceGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetStreamPriorityRange(int *leastPriority, int *greatestPriority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int *); + static auto func_ptr = + LoadSymbol("cudaDeviceGetStreamPriorityRange"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(leastPriority, greatestPriority); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaDeviceSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetSharedMemConfig(enum cudaSharedMemConfig *pConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig *); + static auto func_ptr = LoadSymbol("cudaDeviceGetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetSharedMemConfig(enum cudaSharedMemConfig config) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaDeviceSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(config); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetByPCIBusId(int *device, const char *pciBusId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const char *); + static auto func_ptr = LoadSymbol("cudaDeviceGetByPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, pciBusId); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceGetPCIBusId(char *pciBusId, + int len, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(char *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pciBusId, len, device); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetEventHandle(cudaIpcEventHandle_t *handle, cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcEventHandle_t *, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaIpcGetEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcOpenEventHandle(cudaEvent_t *event, cudaIpcEventHandle_t handle) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, cudaIpcEventHandle_t); + static auto func_ptr = LoadSymbol("cudaIpcOpenEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, handle); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetMemHandle(cudaIpcMemHandle_t *handle, void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcMemHandle_t *, void *); + static auto func_ptr = LoadSymbol("cudaIpcGetMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcOpenMemHandle( + void **devPtr, cudaIpcMemHandle_t handle, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaIpcMemHandle_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaIpcOpenMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, handle, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcCloseMemHandle(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaIpcCloseMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaThreadExit(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadExit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetLimit(enum cudaLimit limit, size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaThreadSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaThreadGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaThreadGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaThreadSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaGetLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaPeekAtLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaPeekAtLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorName(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorName"); + if (!func_ptr) return "cudaGetErrorName symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorString(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorString"); + if (!func_ptr) return "cudaGetErrorString symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceCount(int *count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceCount"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaDeviceProp *, int); + static auto func_ptr = LoadSymbol("cudaGetDeviceProperties"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(prop, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetAttribute(int *value, enum cudaDeviceAttr attr, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceAttr, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetP2PAttribute(int *value, enum cudaDeviceP2PAttr attr, + int srcDevice, int dstDevice) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceP2PAttr, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetP2PAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, srcDevice, dstDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaChooseDevice(int *device, const struct cudaDeviceProp *prop) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const struct cudaDeviceProp *); + static auto func_ptr = LoadSymbol("cudaChooseDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, prop); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDevice(int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaSetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDevice(int *device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetValidDevices(int *device_arr, + int len) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int); + static auto func_ptr = LoadSymbol("cudaSetValidDevices"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device_arr, len); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDeviceFlags(unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int); + static auto func_ptr = LoadSymbol("cudaSetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetDeviceFlags(unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamCreate(cudaStream_t *pStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *); + static auto func_ptr = LoadSymbol("cudaStreamCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithFlags(cudaStream_t *pStream, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithPriority(cudaStream_t *pStream, unsigned int flags, + int priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int, int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetPriority(cudaStream_t hStream, int *priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, int *); + static auto func_ptr = LoadSymbol("cudaStreamGetPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetFlags(cudaStream_t hStream, unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, unsigned int *); + static auto func_ptr = LoadSymbol("cudaStreamGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamDestroy(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaStreamWaitEvent( + cudaStream_t stream, cudaEvent_t event, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, cudaEvent_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamWaitEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, event, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamAddCallback(cudaStream_t stream, cudaStreamCallback_t callback, + void *userData, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaStreamCallback_t, + void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAddCallback"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, callback, userData, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamSynchronize(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamQuery(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamAttachMemAsync(cudaStream_t stream, void *devPtr, + size_t length __dv(0), + unsigned int flags __dv(cudaMemAttachSingle)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAttachMemAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, devPtr, length, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamBeginCapture(cudaStream_t stream, enum cudaStreamCaptureMode mode) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamCaptureMode); + static auto func_ptr = LoadSymbol("cudaStreamBeginCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, mode); +} + +extern __host__ cudaError_t CUDARTAPI +cudaThreadExchangeStreamCaptureMode(enum cudaStreamCaptureMode *mode) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaStreamCaptureMode *); + static auto func_ptr = + LoadSymbol("cudaThreadExchangeStreamCaptureMode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mode); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamEndCapture(cudaStream_t stream, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaStreamEndCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamIsCapturing( + cudaStream_t stream, enum cudaStreamCaptureStatus *pCaptureStatus) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamCaptureStatus *); + static auto func_ptr = LoadSymbol("cudaStreamIsCapturing"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pCaptureStatus); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamGetCaptureInfo( + cudaStream_t stream, enum cudaStreamCaptureStatus *pCaptureStatus, + unsigned long long *pId) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaStream_t, enum cudaStreamCaptureStatus *, unsigned long long *); + static auto func_ptr = LoadSymbol("cudaStreamGetCaptureInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pCaptureStatus, pId); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventCreate(cudaEvent_t *event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *); + static auto func_ptr = LoadSymbol("cudaEventCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventCreateWithFlags(cudaEvent_t *event, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaEventCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventRecord(cudaEvent_t event, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaEventRecord"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventQuery(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventSynchronize(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventDestroy(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventElapsedTime(float *ms, + cudaEvent_t start, + cudaEvent_t end) { + using FuncPtr = cudaError_t(CUDARTAPI *)(float *, cudaEvent_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventElapsedTime"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ms, start, end); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalMemory( + cudaExternalMemory_t *extMem_out, + const struct cudaExternalMemoryHandleDesc *memHandleDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaExternalMemory_t *, const struct cudaExternalMemoryHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem_out, memHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedBuffer( + void **devPtr, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryBufferDesc *bufferDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaExternalMemory_t, + const struct cudaExternalMemoryBufferDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedBuffer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, extMem, bufferDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmap, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryMipmappedArrayDesc *mipmapDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, cudaExternalMemory_t, + const struct cudaExternalMemoryMipmappedArrayDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmap, extMem, mipmapDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalMemory(cudaExternalMemory_t extMem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalMemory_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalSemaphore( + cudaExternalSemaphore_t *extSem_out, + const struct cudaExternalSemaphoreHandleDesc *semHandleDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem_out, semHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaSignalExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreSignalParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreSignalParams *, + unsigned int, cudaStream_t); + static auto func_ptr = + LoadSymbol("cudaSignalExternalSemaphoresAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaWaitExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreWaitParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreWaitParams *, + unsigned int, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaWaitExternalSemaphoresAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalSemaphore(cudaExternalSemaphore_t extSem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem); +} + +extern __host__ cudaError_t CUDARTAPI +cudaLaunchKernel(const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernel( + const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchCooperativeKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernelMultiDevice( + struct cudaLaunchParams *launchParamsList, unsigned int numDevices, + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaLaunchParams *, + unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaLaunchCooperativeKernelMultiDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(launchParamsList, numDevices, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetCacheConfig(const void *func, enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaFuncSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, cacheConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetSharedMemConfig(const void *func, enum cudaSharedMemConfig config) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaFuncSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, config); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncGetAttributes(struct cudaFuncAttributes *attr, const void *func) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaFuncAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaFuncGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attr, func); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncSetAttribute(const void *func, enum cudaFuncAttribute attr, int value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncAttribute, int); + static auto func_ptr = LoadSymbol("cudaFuncSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, attr, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForDevice(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForHost(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchHostFunc(cudaStream_t stream, + cudaHostFn_t fn, + void *userData) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaHostFn_t, void *); + static auto func_ptr = LoadSymbol("cudaLaunchHostFunc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, fn, userData); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessor(int *numBlocks, const void *func, + int blockSize, + size_t dynamicSMemSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t); + static auto func_ptr = + LoadSymbol("cudaOccupancyMaxActiveBlocksPerMultiprocessor"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(int *numBlocks, + const void *func, + int blockSize, + size_t dynamicSMemSize, + unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t, unsigned int); + static auto func_ptr = LoadSymbol( + "cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMallocManaged( + void **devPtr, size_t size, unsigned int flags __dv(cudaMemAttachGlobal)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocManaged"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMalloc(void **devPtr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMalloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocHost(void **ptr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMallocHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocPitch(void **devPtr, + size_t *pitch, + size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t *, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMallocPitch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocArray( + cudaArray_t *array, const struct cudaChannelFormatDesc *desc, size_t width, + size_t height __dv(0), unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + size_t, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, width, height, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFree(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFree"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeHost(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFreeHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeArray(cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t); + static auto func_ptr = LoadSymbol("cudaFreeArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFreeMipmappedArray(cudaMipmappedArray_t mipmappedArray) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t); + static auto func_ptr = LoadSymbol("cudaFreeMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostAlloc(void **pHost, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostAlloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pHost, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostRegister(void *ptr, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostRegister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostUnregister(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaHostUnregister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostGetDevicePointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pDevice, pHost, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostGetFlags(unsigned int *pFlags, + void *pHost) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *, void *); + static auto func_ptr = LoadSymbol("cudaHostGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pFlags, pHost); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3D(struct cudaPitchedPtr *pitchedDevPtr, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr *, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMalloc3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, extent); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3DArray(cudaArray_t *array, const struct cudaChannelFormatDesc *desc, + struct cudaExtent extent, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int); + static auto func_ptr = LoadSymbol("cudaMalloc3DArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, extent, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, + const struct cudaChannelFormatDesc *desc, struct cudaExtent extent, + unsigned int numLevels, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, desc, extent, numLevels, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetMipmappedArrayLevel( + cudaArray_t *levelArray, cudaMipmappedArray_const_t mipmappedArray, + unsigned int level) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaMipmappedArray_const_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGetMipmappedArrayLevel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(levelArray, mipmappedArray, level); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3D(const struct cudaMemcpy3DParms *p) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3DPeer(const struct cudaMemcpy3DPeerParms *p) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy3DAsync( + const struct cudaMemcpy3DParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy3DPeerAsync( + const struct cudaMemcpy3DPeerParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemGetInfo(size_t *free, + size_t *total) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaMemGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(free, total); +} + +extern __host__ cudaError_t CUDARTAPI +cudaArrayGetInfo(struct cudaChannelFormatDesc *desc, struct cudaExtent *extent, + unsigned int *flags, cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + struct cudaExtent *, unsigned int *, + cudaArray_t); + static auto func_ptr = LoadSymbol("cudaArrayGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, extent, flags, array); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy(void *dst, const void *src, + size_t count, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyPeer(void *dst, int dstDevice, + const void *src, + int srcDevice, + size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, int, const void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2D(void *dst, size_t dpitch, + const void *src, + size_t spitch, size_t width, + size_t height, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArray( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArray( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, size_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t width, + size_t height, enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + cudaArray_const_t, size_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbol( + const void *symbol, const void *src, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyHostToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, + size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbol( + void *dst, const void *symbol, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToHost)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemcpyAsync(void *dst, const void *src, size_t count, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyPeerAsync(void *dst, int dstDevice, const void *src, int srcDevice, + size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, const void *, int, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy2DAsync( + void *dst, size_t dpitch, const void *src, size_t spitch, size_t width, + size_t height, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + const void *, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArrayAsync( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, + size_t, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbolAsync( + const void *symbol, const void *src, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbolAsync( + void *dst, const void *symbol, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset(void *devPtr, int value, + size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset2D(void *devPtr, size_t pitch, + int value, size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMemset2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset3D( + struct cudaPitchedPtr pitchedDevPtr, int value, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMemset3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemsetAsync( + void *devPtr, int value, size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemsetAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset2DAsync(void *devPtr, size_t pitch, int value, size_t width, + size_t height, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset3DAsync(struct cudaPitchedPtr pitchedDevPtr, int value, + struct cudaExtent extent, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, + struct cudaExtent, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolAddress(void **devPtr, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolAddress"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolSize(size_t *size, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolSize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(size, symbol); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPrefetchAsync(const void *devPtr, size_t count, int dstDevice, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, size_t, int, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemPrefetchAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, dstDevice, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemAdvise(const void *devPtr, size_t count, enum cudaMemoryAdvise advice, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, size_t, + enum cudaMemoryAdvise, int); + static auto func_ptr = LoadSymbol("cudaMemAdvise"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, advice, device); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttribute( + void *data, size_t dataSize, enum cudaMemRangeAttribute attribute, + const void *devPtr, size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + void *, size_t, enum cudaMemRangeAttribute, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSize, attribute, devPtr, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttributes( + void **data, size_t *dataSizes, enum cudaMemRangeAttribute *attributes, + size_t numAttributes, const void *devPtr, size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, enum cudaMemRangeAttribute *, + size_t, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSizes, attributes, numAttributes, devPtr, count); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, + const void *src, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t, size_t, size_t, const void *, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArray(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t count, + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, cudaArray_const_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t count, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind, stream); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArrayAsync(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaPointerGetAttributes( + struct cudaPointerAttributes *attributes, const void *ptr) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPointerAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaPointerGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attributes, ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceCanAccessPeer(int *canAccessPeer, int device, int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceCanAccessPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(canAccessPeer, device, peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceEnablePeerAccess(int peerDevice, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int, unsigned int); + static auto func_ptr = LoadSymbol("cudaDeviceEnablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceDisablePeerAccess(int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaDeviceDisablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsUnregisterResource(cudaGraphicsResource_t resource) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnregisterResource"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceSetMapFlags( + cudaGraphicsResource_t resource, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphicsResourceSetMapFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsMapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsMapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsUnmapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnmapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceGetMappedPointer( + void **devPtr, size_t *size, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsSubResourceGetMappedArray( + cudaArray_t *array, cudaGraphicsResource_t resource, + unsigned int arrayIndex, unsigned int mipLevel) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaGraphicsResource_t, unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaGraphicsSubResourceGetMappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, resource, arrayIndex, mipLevel); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsResourceGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindTexture( + size_t *offset, const struct textureReference *texref, const void *devPtr, + const struct cudaChannelFormatDesc *desc, size_t size __dv(UINT_MAX)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, size); +} + +extern __host__ cudaError_t CUDARTAPI +cudaBindTexture2D(size_t *offset, const struct textureReference *texref, + const void *devPtr, const struct cudaChannelFormatDesc *desc, + size_t width, size_t height, size_t pitch) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, width, height, pitch); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindTextureToArray( + const struct textureReference *texref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, array, desc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaBindTextureToMipmappedArray(const struct textureReference *texref, + cudaMipmappedArray_const_t mipmappedArray, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaMipmappedArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, mipmappedArray, desc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaUnbindTexture(const struct textureReference *texref) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaUnbindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureAlignmentOffset( + size_t *offset, const struct textureReference *texref) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(size_t *, const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaGetTextureAlignmentOffset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureReference( + const struct textureReference **texref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct textureReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetTextureReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindSurfaceToArray( + const struct surfaceReference *surfref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct surfaceReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindSurfaceToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, array, desc); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceReference( + const struct surfaceReference **surfref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct surfaceReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSurfaceReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetChannelDesc( + struct cudaChannelFormatDesc *desc, cudaArray_const_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + cudaArray_const_t); + static auto func_ptr = LoadSymbol("cudaGetChannelDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, array); +} + +extern __host__ struct cudaChannelFormatDesc CUDARTAPI cudaCreateChannelDesc( + int x, int y, int z, int w, enum cudaChannelFormatKind f) { + using FuncPtr = struct cudaChannelFormatDesc(CUDARTAPI *)( + int, int, int, int, enum cudaChannelFormatKind); + static auto func_ptr = LoadSymbol("cudaCreateChannelDesc"); + if (!func_ptr) { + return cudaChannelFormatDesc{cudaChannelFormatKind(-1), 0, 0, 0}; + } + return func_ptr(x, y, z, w, f); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateTextureObject( + cudaTextureObject_t *pTexObject, const struct cudaResourceDesc *pResDesc, + const struct cudaTextureDesc *pTexDesc, + const struct cudaResourceViewDesc *pResViewDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaTextureObject_t *, const struct cudaResourceDesc *, + const struct cudaTextureDesc *, const struct cudaResourceViewDesc *); + static auto func_ptr = LoadSymbol("cudaCreateTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexObject, pResDesc, pTexDesc, pResViewDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyTextureObject(cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaDestroyTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectTextureDesc( + struct cudaTextureDesc *pTexDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaTextureDesc *, cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaGetTextureObjectTextureDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceViewDesc( + struct cudaResourceViewDesc *pResViewDesc, cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaResourceViewDesc *, + cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceViewDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResViewDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateSurfaceObject( + cudaSurfaceObject_t *pSurfObject, const struct cudaResourceDesc *pResDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t *, + const struct cudaResourceDesc *); + static auto func_ptr = LoadSymbol("cudaCreateSurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pSurfObject, pResDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroySurfaceObject(cudaSurfaceObject_t surfObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t); + static auto func_ptr = LoadSymbol("cudaDestroySurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaSurfaceObject_t surfObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaSurfaceObject_t); + static auto func_ptr = + LoadSymbol("cudaGetSurfaceObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaDriverGetVersion(int *driverVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaDriverGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(driverVersion); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaRuntimeGetVersion(int *runtimeVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaRuntimeGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(runtimeVersion); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphCreate(cudaGraph_t *pGraph, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraph, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddKernelNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddKernelNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeGetParams( + cudaGraphNode_t node, struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeSetParams( + cudaGraphNode_t node, const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemcpyNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemcpy3DParms *pCopyParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemcpyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pCopyParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeGetParams( + cudaGraphNode_t node, struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeSetParams( + cudaGraphNode_t node, const struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemsetNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemsetParams *pMemsetParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemsetNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pMemsetParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeGetParams( + cudaGraphNode_t node, struct cudaMemsetParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeSetParams( + cudaGraphNode_t node, const struct cudaMemsetParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddHostNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddHostNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeGetParams( + cudaGraphNode_t node, struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeSetParams( + cudaGraphNode_t node, const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddChildGraphNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, + size_t numDependencies, cudaGraph_t childGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphAddChildGraphNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + childGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphChildGraphNodeGetGraph(cudaGraphNode_t node, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaGraphChildGraphNodeGetGraph"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddEmptyNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddEmptyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphClone(cudaGraph_t *pGraphClone, cudaGraph_t originalGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphClone, originalGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeFindInClone(cudaGraphNode_t *pNode, cudaGraphNode_t originalNode, + cudaGraph_t clonedGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraphNode_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphNodeFindInClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pNode, originalNode, clonedGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeGetType(cudaGraphNode_t node, enum cudaGraphNodeType *pType) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, enum cudaGraphNodeType *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetType"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pType); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetNodes(cudaGraph_t graph, + cudaGraphNode_t *nodes, + size_t *numNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, nodes, numNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetRootNodes( + cudaGraph_t graph, cudaGraphNode_t *pRootNodes, size_t *pNumRootNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetRootNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, pRootNodes, pNumRootNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetEdges(cudaGraph_t graph, + cudaGraphNode_t *from, + cudaGraphNode_t *to, + size_t *numEdges) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, + cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetEdges"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numEdges); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependencies( + cudaGraphNode_t node, cudaGraphNode_t *pDependencies, + size_t *pNumDependencies) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependencies, pNumDependencies); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependentNodes( + cudaGraphNode_t node, cudaGraphNode_t *pDependentNodes, + size_t *pNumDependentNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependentNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependentNodes, pNumDependentNodes); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddDependencies(cudaGraph_t graph, const cudaGraphNode_t *from, + const cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, const cudaGraphNode_t *, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphRemoveDependencies(cudaGraph_t graph, const cudaGraphNode_t *from, + const cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, const cudaGraphNode_t *, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphRemoveDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphDestroyNode(cudaGraphNode_t node) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphInstantiate( + cudaGraphExec_t *pGraphExec, cudaGraph_t graph, cudaGraphNode_t *pErrorNode, + char *pLogBuffer, size_t bufferSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t *, cudaGraph_t, + cudaGraphNode_t *, char *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphInstantiate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphExec, graph, pErrorNode, pLogBuffer, bufferSize); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecKernelNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExecKernelNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphLaunch(cudaGraphExec_t graphExec, + cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphLaunch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecDestroy(cudaGraphExec_t graphExec) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t); + static auto func_ptr = LoadSymbol("cudaGraphExecDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphDestroy(cudaGraph_t graph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetExportTable( + const void **ppExportTable, const cudaUUID_t *pExportTableId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void **, const cudaUUID_t *); + static auto func_ptr = LoadSymbol("cudaGetExportTable"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ppExportTable, pExportTableId); +} + +} // extern "C" diff --git a/source/lib/src/cuda/cudart/cuda_runtime_10_2.inc b/source/lib/src/cuda/cudart/cuda_runtime_10_2.inc new file mode 100644 index 0000000000..a5a5438b0e --- /dev/null +++ b/source/lib/src/cuda/cudart/cuda_runtime_10_2.inc @@ -0,0 +1,1907 @@ +// Auto-generated, do not edit. + +extern "C" { + +extern __host__ cudaError_t CUDARTAPI cudaDeviceReset(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceReset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceSetLimit(enum cudaLimit limit, + size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaDeviceSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaDeviceGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaDeviceGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetStreamPriorityRange(int *leastPriority, int *greatestPriority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int *); + static auto func_ptr = + LoadSymbol("cudaDeviceGetStreamPriorityRange"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(leastPriority, greatestPriority); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaDeviceSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetSharedMemConfig(enum cudaSharedMemConfig *pConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig *); + static auto func_ptr = LoadSymbol("cudaDeviceGetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetSharedMemConfig(enum cudaSharedMemConfig config) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaDeviceSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(config); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetByPCIBusId(int *device, const char *pciBusId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const char *); + static auto func_ptr = LoadSymbol("cudaDeviceGetByPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, pciBusId); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceGetPCIBusId(char *pciBusId, + int len, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(char *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pciBusId, len, device); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetEventHandle(cudaIpcEventHandle_t *handle, cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcEventHandle_t *, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaIpcGetEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcOpenEventHandle(cudaEvent_t *event, cudaIpcEventHandle_t handle) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, cudaIpcEventHandle_t); + static auto func_ptr = LoadSymbol("cudaIpcOpenEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, handle); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetMemHandle(cudaIpcMemHandle_t *handle, void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcMemHandle_t *, void *); + static auto func_ptr = LoadSymbol("cudaIpcGetMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcOpenMemHandle( + void **devPtr, cudaIpcMemHandle_t handle, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaIpcMemHandle_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaIpcOpenMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, handle, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcCloseMemHandle(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaIpcCloseMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaThreadExit(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadExit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetLimit(enum cudaLimit limit, size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaThreadSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaThreadGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaThreadGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaThreadSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaGetLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaPeekAtLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaPeekAtLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorName(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorName"); + if (!func_ptr) return "cudaGetErrorName symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorString(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorString"); + if (!func_ptr) return "cudaGetErrorString symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceCount(int *count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceCount"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaDeviceProp *, int); + static auto func_ptr = LoadSymbol("cudaGetDeviceProperties"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(prop, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetAttribute(int *value, enum cudaDeviceAttr attr, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceAttr, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, device); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceGetNvSciSyncAttributes( + void *nvSciSyncAttrList, int device, int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, int); + static auto func_ptr = + LoadSymbol("cudaDeviceGetNvSciSyncAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(nvSciSyncAttrList, device, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetP2PAttribute(int *value, enum cudaDeviceP2PAttr attr, + int srcDevice, int dstDevice) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceP2PAttr, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetP2PAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, srcDevice, dstDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaChooseDevice(int *device, const struct cudaDeviceProp *prop) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const struct cudaDeviceProp *); + static auto func_ptr = LoadSymbol("cudaChooseDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, prop); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDevice(int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaSetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDevice(int *device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetValidDevices(int *device_arr, + int len) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int); + static auto func_ptr = LoadSymbol("cudaSetValidDevices"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device_arr, len); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDeviceFlags(unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int); + static auto func_ptr = LoadSymbol("cudaSetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetDeviceFlags(unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamCreate(cudaStream_t *pStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *); + static auto func_ptr = LoadSymbol("cudaStreamCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithFlags(cudaStream_t *pStream, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithPriority(cudaStream_t *pStream, unsigned int flags, + int priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int, int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetPriority(cudaStream_t hStream, int *priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, int *); + static auto func_ptr = LoadSymbol("cudaStreamGetPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetFlags(cudaStream_t hStream, unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, unsigned int *); + static auto func_ptr = LoadSymbol("cudaStreamGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamDestroy(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaStreamWaitEvent( + cudaStream_t stream, cudaEvent_t event, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, cudaEvent_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamWaitEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, event, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamAddCallback(cudaStream_t stream, cudaStreamCallback_t callback, + void *userData, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaStreamCallback_t, + void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAddCallback"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, callback, userData, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamSynchronize(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamQuery(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamAttachMemAsync(cudaStream_t stream, void *devPtr, + size_t length __dv(0), + unsigned int flags __dv(cudaMemAttachSingle)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAttachMemAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, devPtr, length, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamBeginCapture(cudaStream_t stream, enum cudaStreamCaptureMode mode) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamCaptureMode); + static auto func_ptr = LoadSymbol("cudaStreamBeginCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, mode); +} + +extern __host__ cudaError_t CUDARTAPI +cudaThreadExchangeStreamCaptureMode(enum cudaStreamCaptureMode *mode) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaStreamCaptureMode *); + static auto func_ptr = + LoadSymbol("cudaThreadExchangeStreamCaptureMode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mode); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamEndCapture(cudaStream_t stream, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaStreamEndCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamIsCapturing( + cudaStream_t stream, enum cudaStreamCaptureStatus *pCaptureStatus) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamCaptureStatus *); + static auto func_ptr = LoadSymbol("cudaStreamIsCapturing"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pCaptureStatus); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamGetCaptureInfo( + cudaStream_t stream, enum cudaStreamCaptureStatus *pCaptureStatus, + unsigned long long *pId) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaStream_t, enum cudaStreamCaptureStatus *, unsigned long long *); + static auto func_ptr = LoadSymbol("cudaStreamGetCaptureInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pCaptureStatus, pId); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventCreate(cudaEvent_t *event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *); + static auto func_ptr = LoadSymbol("cudaEventCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventCreateWithFlags(cudaEvent_t *event, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaEventCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventRecord(cudaEvent_t event, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaEventRecord"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventQuery(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventSynchronize(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventDestroy(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventElapsedTime(float *ms, + cudaEvent_t start, + cudaEvent_t end) { + using FuncPtr = cudaError_t(CUDARTAPI *)(float *, cudaEvent_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventElapsedTime"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ms, start, end); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalMemory( + cudaExternalMemory_t *extMem_out, + const struct cudaExternalMemoryHandleDesc *memHandleDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaExternalMemory_t *, const struct cudaExternalMemoryHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem_out, memHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedBuffer( + void **devPtr, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryBufferDesc *bufferDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaExternalMemory_t, + const struct cudaExternalMemoryBufferDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedBuffer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, extMem, bufferDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmap, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryMipmappedArrayDesc *mipmapDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, cudaExternalMemory_t, + const struct cudaExternalMemoryMipmappedArrayDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmap, extMem, mipmapDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalMemory(cudaExternalMemory_t extMem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalMemory_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalSemaphore( + cudaExternalSemaphore_t *extSem_out, + const struct cudaExternalSemaphoreHandleDesc *semHandleDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem_out, semHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaSignalExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreSignalParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreSignalParams *, + unsigned int, cudaStream_t); + static auto func_ptr = + LoadSymbol("cudaSignalExternalSemaphoresAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaWaitExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreWaitParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreWaitParams *, + unsigned int, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaWaitExternalSemaphoresAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalSemaphore(cudaExternalSemaphore_t extSem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem); +} + +extern __host__ cudaError_t CUDARTAPI +cudaLaunchKernel(const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernel( + const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchCooperativeKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernelMultiDevice( + struct cudaLaunchParams *launchParamsList, unsigned int numDevices, + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaLaunchParams *, + unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaLaunchCooperativeKernelMultiDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(launchParamsList, numDevices, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetCacheConfig(const void *func, enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaFuncSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, cacheConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetSharedMemConfig(const void *func, enum cudaSharedMemConfig config) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaFuncSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, config); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncGetAttributes(struct cudaFuncAttributes *attr, const void *func) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaFuncAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaFuncGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attr, func); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncSetAttribute(const void *func, enum cudaFuncAttribute attr, int value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncAttribute, int); + static auto func_ptr = LoadSymbol("cudaFuncSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, attr, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForDevice(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForHost(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchHostFunc(cudaStream_t stream, + cudaHostFn_t fn, + void *userData) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaHostFn_t, void *); + static auto func_ptr = LoadSymbol("cudaLaunchHostFunc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, fn, userData); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessor(int *numBlocks, const void *func, + int blockSize, + size_t dynamicSMemSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t); + static auto func_ptr = + LoadSymbol("cudaOccupancyMaxActiveBlocksPerMultiprocessor"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(int *numBlocks, + const void *func, + int blockSize, + size_t dynamicSMemSize, + unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t, unsigned int); + static auto func_ptr = LoadSymbol( + "cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMallocManaged( + void **devPtr, size_t size, unsigned int flags __dv(cudaMemAttachGlobal)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocManaged"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMalloc(void **devPtr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMalloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocHost(void **ptr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMallocHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocPitch(void **devPtr, + size_t *pitch, + size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t *, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMallocPitch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocArray( + cudaArray_t *array, const struct cudaChannelFormatDesc *desc, size_t width, + size_t height __dv(0), unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + size_t, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, width, height, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFree(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFree"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeHost(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFreeHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeArray(cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t); + static auto func_ptr = LoadSymbol("cudaFreeArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFreeMipmappedArray(cudaMipmappedArray_t mipmappedArray) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t); + static auto func_ptr = LoadSymbol("cudaFreeMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostAlloc(void **pHost, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostAlloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pHost, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostRegister(void *ptr, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostRegister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostUnregister(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaHostUnregister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostGetDevicePointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pDevice, pHost, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostGetFlags(unsigned int *pFlags, + void *pHost) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *, void *); + static auto func_ptr = LoadSymbol("cudaHostGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pFlags, pHost); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3D(struct cudaPitchedPtr *pitchedDevPtr, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr *, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMalloc3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, extent); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3DArray(cudaArray_t *array, const struct cudaChannelFormatDesc *desc, + struct cudaExtent extent, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int); + static auto func_ptr = LoadSymbol("cudaMalloc3DArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, extent, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, + const struct cudaChannelFormatDesc *desc, struct cudaExtent extent, + unsigned int numLevels, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, desc, extent, numLevels, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetMipmappedArrayLevel( + cudaArray_t *levelArray, cudaMipmappedArray_const_t mipmappedArray, + unsigned int level) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaMipmappedArray_const_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGetMipmappedArrayLevel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(levelArray, mipmappedArray, level); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3D(const struct cudaMemcpy3DParms *p) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3DPeer(const struct cudaMemcpy3DPeerParms *p) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy3DAsync( + const struct cudaMemcpy3DParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy3DPeerAsync( + const struct cudaMemcpy3DPeerParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemGetInfo(size_t *free, + size_t *total) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaMemGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(free, total); +} + +extern __host__ cudaError_t CUDARTAPI +cudaArrayGetInfo(struct cudaChannelFormatDesc *desc, struct cudaExtent *extent, + unsigned int *flags, cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + struct cudaExtent *, unsigned int *, + cudaArray_t); + static auto func_ptr = LoadSymbol("cudaArrayGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, extent, flags, array); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy(void *dst, const void *src, + size_t count, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyPeer(void *dst, int dstDevice, + const void *src, + int srcDevice, + size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, int, const void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2D(void *dst, size_t dpitch, + const void *src, + size_t spitch, size_t width, + size_t height, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArray( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArray( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, size_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t width, + size_t height, enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + cudaArray_const_t, size_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbol( + const void *symbol, const void *src, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyHostToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, + size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbol( + void *dst, const void *symbol, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToHost)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemcpyAsync(void *dst, const void *src, size_t count, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyPeerAsync(void *dst, int dstDevice, const void *src, int srcDevice, + size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, const void *, int, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy2DAsync( + void *dst, size_t dpitch, const void *src, size_t spitch, size_t width, + size_t height, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + const void *, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArrayAsync( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, + size_t, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbolAsync( + const void *symbol, const void *src, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbolAsync( + void *dst, const void *symbol, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset(void *devPtr, int value, + size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset2D(void *devPtr, size_t pitch, + int value, size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMemset2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset3D( + struct cudaPitchedPtr pitchedDevPtr, int value, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMemset3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemsetAsync( + void *devPtr, int value, size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemsetAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset2DAsync(void *devPtr, size_t pitch, int value, size_t width, + size_t height, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset3DAsync(struct cudaPitchedPtr pitchedDevPtr, int value, + struct cudaExtent extent, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, + struct cudaExtent, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolAddress(void **devPtr, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolAddress"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolSize(size_t *size, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolSize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(size, symbol); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPrefetchAsync(const void *devPtr, size_t count, int dstDevice, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, size_t, int, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemPrefetchAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, dstDevice, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemAdvise(const void *devPtr, size_t count, enum cudaMemoryAdvise advice, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, size_t, + enum cudaMemoryAdvise, int); + static auto func_ptr = LoadSymbol("cudaMemAdvise"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, advice, device); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttribute( + void *data, size_t dataSize, enum cudaMemRangeAttribute attribute, + const void *devPtr, size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + void *, size_t, enum cudaMemRangeAttribute, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSize, attribute, devPtr, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttributes( + void **data, size_t *dataSizes, enum cudaMemRangeAttribute *attributes, + size_t numAttributes, const void *devPtr, size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, enum cudaMemRangeAttribute *, + size_t, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSizes, attributes, numAttributes, devPtr, count); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, + const void *src, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t, size_t, size_t, const void *, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArray(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t count, + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, cudaArray_const_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t count, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind, stream); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArrayAsync(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaPointerGetAttributes( + struct cudaPointerAttributes *attributes, const void *ptr) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPointerAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaPointerGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attributes, ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceCanAccessPeer(int *canAccessPeer, int device, int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceCanAccessPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(canAccessPeer, device, peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceEnablePeerAccess(int peerDevice, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int, unsigned int); + static auto func_ptr = LoadSymbol("cudaDeviceEnablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceDisablePeerAccess(int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaDeviceDisablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsUnregisterResource(cudaGraphicsResource_t resource) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnregisterResource"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceSetMapFlags( + cudaGraphicsResource_t resource, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphicsResourceSetMapFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsMapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsMapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsUnmapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnmapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceGetMappedPointer( + void **devPtr, size_t *size, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsSubResourceGetMappedArray( + cudaArray_t *array, cudaGraphicsResource_t resource, + unsigned int arrayIndex, unsigned int mipLevel) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaGraphicsResource_t, unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaGraphicsSubResourceGetMappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, resource, arrayIndex, mipLevel); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsResourceGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindTexture( + size_t *offset, const struct textureReference *texref, const void *devPtr, + const struct cudaChannelFormatDesc *desc, size_t size __dv(UINT_MAX)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, size); +} + +extern __host__ cudaError_t CUDARTAPI +cudaBindTexture2D(size_t *offset, const struct textureReference *texref, + const void *devPtr, const struct cudaChannelFormatDesc *desc, + size_t width, size_t height, size_t pitch) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, width, height, pitch); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindTextureToArray( + const struct textureReference *texref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, array, desc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaBindTextureToMipmappedArray(const struct textureReference *texref, + cudaMipmappedArray_const_t mipmappedArray, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaMipmappedArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, mipmappedArray, desc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaUnbindTexture(const struct textureReference *texref) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaUnbindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureAlignmentOffset( + size_t *offset, const struct textureReference *texref) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(size_t *, const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaGetTextureAlignmentOffset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureReference( + const struct textureReference **texref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct textureReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetTextureReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindSurfaceToArray( + const struct surfaceReference *surfref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct surfaceReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindSurfaceToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, array, desc); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceReference( + const struct surfaceReference **surfref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct surfaceReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSurfaceReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetChannelDesc( + struct cudaChannelFormatDesc *desc, cudaArray_const_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + cudaArray_const_t); + static auto func_ptr = LoadSymbol("cudaGetChannelDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, array); +} + +extern __host__ struct cudaChannelFormatDesc CUDARTAPI cudaCreateChannelDesc( + int x, int y, int z, int w, enum cudaChannelFormatKind f) { + using FuncPtr = struct cudaChannelFormatDesc(CUDARTAPI *)( + int, int, int, int, enum cudaChannelFormatKind); + static auto func_ptr = LoadSymbol("cudaCreateChannelDesc"); + if (!func_ptr) { + return cudaChannelFormatDesc{cudaChannelFormatKind(-1), 0, 0, 0}; + } + return func_ptr(x, y, z, w, f); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateTextureObject( + cudaTextureObject_t *pTexObject, const struct cudaResourceDesc *pResDesc, + const struct cudaTextureDesc *pTexDesc, + const struct cudaResourceViewDesc *pResViewDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaTextureObject_t *, const struct cudaResourceDesc *, + const struct cudaTextureDesc *, const struct cudaResourceViewDesc *); + static auto func_ptr = LoadSymbol("cudaCreateTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexObject, pResDesc, pTexDesc, pResViewDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyTextureObject(cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaDestroyTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectTextureDesc( + struct cudaTextureDesc *pTexDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaTextureDesc *, cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaGetTextureObjectTextureDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceViewDesc( + struct cudaResourceViewDesc *pResViewDesc, cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaResourceViewDesc *, + cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceViewDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResViewDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateSurfaceObject( + cudaSurfaceObject_t *pSurfObject, const struct cudaResourceDesc *pResDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t *, + const struct cudaResourceDesc *); + static auto func_ptr = LoadSymbol("cudaCreateSurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pSurfObject, pResDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroySurfaceObject(cudaSurfaceObject_t surfObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t); + static auto func_ptr = LoadSymbol("cudaDestroySurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaSurfaceObject_t surfObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaSurfaceObject_t); + static auto func_ptr = + LoadSymbol("cudaGetSurfaceObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaDriverGetVersion(int *driverVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaDriverGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(driverVersion); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaRuntimeGetVersion(int *runtimeVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaRuntimeGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(runtimeVersion); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphCreate(cudaGraph_t *pGraph, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraph, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddKernelNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddKernelNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeGetParams( + cudaGraphNode_t node, struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeSetParams( + cudaGraphNode_t node, const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemcpyNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemcpy3DParms *pCopyParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemcpyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pCopyParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeGetParams( + cudaGraphNode_t node, struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeSetParams( + cudaGraphNode_t node, const struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemsetNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemsetParams *pMemsetParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemsetNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pMemsetParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeGetParams( + cudaGraphNode_t node, struct cudaMemsetParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeSetParams( + cudaGraphNode_t node, const struct cudaMemsetParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddHostNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddHostNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeGetParams( + cudaGraphNode_t node, struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeSetParams( + cudaGraphNode_t node, const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddChildGraphNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, + size_t numDependencies, cudaGraph_t childGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphAddChildGraphNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + childGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphChildGraphNodeGetGraph(cudaGraphNode_t node, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaGraphChildGraphNodeGetGraph"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddEmptyNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddEmptyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphClone(cudaGraph_t *pGraphClone, cudaGraph_t originalGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphClone, originalGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeFindInClone(cudaGraphNode_t *pNode, cudaGraphNode_t originalNode, + cudaGraph_t clonedGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraphNode_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphNodeFindInClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pNode, originalNode, clonedGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeGetType(cudaGraphNode_t node, enum cudaGraphNodeType *pType) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, enum cudaGraphNodeType *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetType"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pType); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetNodes(cudaGraph_t graph, + cudaGraphNode_t *nodes, + size_t *numNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, nodes, numNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetRootNodes( + cudaGraph_t graph, cudaGraphNode_t *pRootNodes, size_t *pNumRootNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetRootNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, pRootNodes, pNumRootNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetEdges(cudaGraph_t graph, + cudaGraphNode_t *from, + cudaGraphNode_t *to, + size_t *numEdges) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, + cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetEdges"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numEdges); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependencies( + cudaGraphNode_t node, cudaGraphNode_t *pDependencies, + size_t *pNumDependencies) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependencies, pNumDependencies); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependentNodes( + cudaGraphNode_t node, cudaGraphNode_t *pDependentNodes, + size_t *pNumDependentNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependentNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependentNodes, pNumDependentNodes); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddDependencies(cudaGraph_t graph, const cudaGraphNode_t *from, + const cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, const cudaGraphNode_t *, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphRemoveDependencies(cudaGraph_t graph, const cudaGraphNode_t *from, + const cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, const cudaGraphNode_t *, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphRemoveDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphDestroyNode(cudaGraphNode_t node) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphInstantiate( + cudaGraphExec_t *pGraphExec, cudaGraph_t graph, cudaGraphNode_t *pErrorNode, + char *pLogBuffer, size_t bufferSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t *, cudaGraph_t, + cudaGraphNode_t *, char *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphInstantiate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphExec, graph, pErrorNode, pLogBuffer, bufferSize); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecKernelNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExecKernelNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecMemcpyNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = + LoadSymbol("cudaGraphExecMemcpyNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecMemsetNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaMemsetParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaMemsetParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExecMemsetNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecHostNodeSetParams(cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphExecHostNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecUpdate(cudaGraphExec_t hGraphExec, cudaGraph_t hGraph, + cudaGraphNode_t *hErrorNode_out, + enum cudaGraphExecUpdateResult *updateResult_out) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraph_t, cudaGraphNode_t *, + enum cudaGraphExecUpdateResult *); + static auto func_ptr = LoadSymbol("cudaGraphExecUpdate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, hGraph, hErrorNode_out, updateResult_out); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphLaunch(cudaGraphExec_t graphExec, + cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphLaunch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecDestroy(cudaGraphExec_t graphExec) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t); + static auto func_ptr = LoadSymbol("cudaGraphExecDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphDestroy(cudaGraph_t graph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetExportTable( + const void **ppExportTable, const cudaUUID_t *pExportTableId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void **, const cudaUUID_t *); + static auto func_ptr = LoadSymbol("cudaGetExportTable"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ppExportTable, pExportTableId); +} + +} // extern "C" diff --git a/source/lib/src/cuda/cudart/cuda_runtime_11_0.inc b/source/lib/src/cuda/cudart/cuda_runtime_11_0.inc new file mode 100644 index 0000000000..c9cd0a3769 --- /dev/null +++ b/source/lib/src/cuda/cudart/cuda_runtime_11_0.inc @@ -0,0 +1,2639 @@ +// Auto-generated, do not edit. + +extern "C" { + +extern __host__ cudaError_t CUDARTAPI cudaDeviceReset(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceReset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceSetLimit(enum cudaLimit limit, + size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaDeviceSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaDeviceGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetTexture1DLinearMaxWidth( + size_t *maxWidthInElements, const struct cudaChannelFormatDesc *fmtDesc, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct cudaChannelFormatDesc *, int); + static auto func_ptr = + LoadSymbol("cudaDeviceGetTexture1DLinearMaxWidth"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(maxWidthInElements, fmtDesc, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaDeviceGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetStreamPriorityRange(int *leastPriority, int *greatestPriority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int *); + static auto func_ptr = + LoadSymbol("cudaDeviceGetStreamPriorityRange"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(leastPriority, greatestPriority); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaDeviceSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetSharedMemConfig(enum cudaSharedMemConfig *pConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig *); + static auto func_ptr = LoadSymbol("cudaDeviceGetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetSharedMemConfig(enum cudaSharedMemConfig config) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaDeviceSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(config); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetByPCIBusId(int *device, const char *pciBusId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const char *); + static auto func_ptr = LoadSymbol("cudaDeviceGetByPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, pciBusId); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceGetPCIBusId(char *pciBusId, + int len, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(char *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pciBusId, len, device); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetEventHandle(cudaIpcEventHandle_t *handle, cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcEventHandle_t *, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaIpcGetEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcOpenEventHandle(cudaEvent_t *event, cudaIpcEventHandle_t handle) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, cudaIpcEventHandle_t); + static auto func_ptr = LoadSymbol("cudaIpcOpenEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, handle); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetMemHandle(cudaIpcMemHandle_t *handle, void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcMemHandle_t *, void *); + static auto func_ptr = LoadSymbol("cudaIpcGetMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcOpenMemHandle( + void **devPtr, cudaIpcMemHandle_t handle, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaIpcMemHandle_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaIpcOpenMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, handle, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcCloseMemHandle(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaIpcCloseMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +#if CUDA_VERSION >= 11030 + +extern __host__ cudaError_t CUDARTAPI cudaDeviceFlushGPUDirectRDMAWrites( + enum cudaFlushGPUDirectRDMAWritesTarget target, + enum cudaFlushGPUDirectRDMAWritesScope scope) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(enum cudaFlushGPUDirectRDMAWritesTarget, + enum cudaFlushGPUDirectRDMAWritesScope); + static auto func_ptr = + LoadSymbol("cudaDeviceFlushGPUDirectRDMAWrites"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(target, scope); +} + +#endif // CUDA_VERSION >= 11030 + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaThreadExit(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadExit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetLimit(enum cudaLimit limit, size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaThreadSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaThreadGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaThreadGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaThreadSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaGetLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaPeekAtLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaPeekAtLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorName(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorName"); + if (!func_ptr) return "cudaGetErrorName symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorString(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorString"); + if (!func_ptr) return "cudaGetErrorString symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceCount(int *count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceCount"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaDeviceProp *, int); + static auto func_ptr = LoadSymbol("cudaGetDeviceProperties"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(prop, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetAttribute(int *value, enum cudaDeviceAttr attr, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceAttr, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, device); +} + +#if CUDA_VERSION >= 11020 + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetDefaultMemPool(cudaMemPool_t *memPool, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t *, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetDefaultMemPool"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, device); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetMemPool(int device, cudaMemPool_t memPool) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int, cudaMemPool_t); + static auto func_ptr = LoadSymbol("cudaDeviceSetMemPool"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, memPool); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetMemPool(cudaMemPool_t *memPool, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t *, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetMemPool"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, device); +} + +#endif // CUDA_VERSION >= 11020 + +extern __host__ cudaError_t CUDARTAPI cudaDeviceGetNvSciSyncAttributes( + void *nvSciSyncAttrList, int device, int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, int); + static auto func_ptr = + LoadSymbol("cudaDeviceGetNvSciSyncAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(nvSciSyncAttrList, device, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetP2PAttribute(int *value, enum cudaDeviceP2PAttr attr, + int srcDevice, int dstDevice) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceP2PAttr, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetP2PAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, srcDevice, dstDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaChooseDevice(int *device, const struct cudaDeviceProp *prop) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const struct cudaDeviceProp *); + static auto func_ptr = LoadSymbol("cudaChooseDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, prop); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDevice(int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaSetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDevice(int *device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetValidDevices(int *device_arr, + int len) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int); + static auto func_ptr = LoadSymbol("cudaSetValidDevices"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device_arr, len); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDeviceFlags(unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int); + static auto func_ptr = LoadSymbol("cudaSetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetDeviceFlags(unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamCreate(cudaStream_t *pStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *); + static auto func_ptr = LoadSymbol("cudaStreamCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithFlags(cudaStream_t *pStream, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithPriority(cudaStream_t *pStream, unsigned int flags, + int priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int, int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetPriority(cudaStream_t hStream, int *priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, int *); + static auto func_ptr = LoadSymbol("cudaStreamGetPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetFlags(cudaStream_t hStream, unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, unsigned int *); + static auto func_ptr = LoadSymbol("cudaStreamGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaCtxResetPersistingL2Cache(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaCtxResetPersistingL2Cache"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCopyAttributes(cudaStream_t dst, cudaStream_t src) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamCopyAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetAttribute(cudaStream_t hStream, enum cudaStreamAttrID attr, + union cudaStreamAttrValue *value_out) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamAttrID, + union cudaStreamAttrValue *); + static auto func_ptr = LoadSymbol("cudaStreamGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, attr, value_out); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamSetAttribute(cudaStream_t hStream, enum cudaStreamAttrID attr, + const union cudaStreamAttrValue *value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamAttrID, + const union cudaStreamAttrValue *); + static auto func_ptr = LoadSymbol("cudaStreamSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, attr, value); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamDestroy(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaStreamWaitEvent( + cudaStream_t stream, cudaEvent_t event, unsigned int flags __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, cudaEvent_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamWaitEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, event, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamAddCallback(cudaStream_t stream, cudaStreamCallback_t callback, + void *userData, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaStreamCallback_t, + void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAddCallback"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, callback, userData, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamSynchronize(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamQuery(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamAttachMemAsync(cudaStream_t stream, void *devPtr, + size_t length __dv(0), unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAttachMemAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, devPtr, length, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamBeginCapture(cudaStream_t stream, enum cudaStreamCaptureMode mode) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamCaptureMode); + static auto func_ptr = LoadSymbol("cudaStreamBeginCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, mode); +} + +extern __host__ cudaError_t CUDARTAPI +cudaThreadExchangeStreamCaptureMode(enum cudaStreamCaptureMode *mode) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaStreamCaptureMode *); + static auto func_ptr = + LoadSymbol("cudaThreadExchangeStreamCaptureMode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mode); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamEndCapture(cudaStream_t stream, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaStreamEndCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamIsCapturing( + cudaStream_t stream, enum cudaStreamCaptureStatus *pCaptureStatus) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamCaptureStatus *); + static auto func_ptr = LoadSymbol("cudaStreamIsCapturing"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pCaptureStatus); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamGetCaptureInfo( + cudaStream_t stream, enum cudaStreamCaptureStatus *pCaptureStatus, + unsigned long long *pId) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaStream_t, enum cudaStreamCaptureStatus *, unsigned long long *); + static auto func_ptr = LoadSymbol("cudaStreamGetCaptureInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pCaptureStatus, pId); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamGetCaptureInfo_v2( + cudaStream_t stream, enum cudaStreamCaptureStatus *captureStatus_out, + unsigned long long *id_out __dv(0), cudaGraph_t *graph_out __dv(0), + const cudaGraphNode_t **dependencies_out __dv(0), + size_t *numDependencies_out __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaStream_t, enum cudaStreamCaptureStatus *, unsigned long long *, + cudaGraph_t *, const cudaGraphNode_t **, size_t *); + static auto func_ptr = LoadSymbol("cudaStreamGetCaptureInfo_v2"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, captureStatus_out, id_out, graph_out, + dependencies_out, numDependencies_out); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamUpdateCaptureDependencies( + cudaStream_t stream, cudaGraphNode_t *dependencies, size_t numDependencies, + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaGraphNode_t *, + size_t, unsigned int); + static auto func_ptr = + LoadSymbol("cudaStreamUpdateCaptureDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, dependencies, numDependencies, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventCreate(cudaEvent_t *event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *); + static auto func_ptr = LoadSymbol("cudaEventCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventCreateWithFlags(cudaEvent_t *event, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaEventCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventRecord(cudaEvent_t event, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaEventRecord"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventRecordWithFlags(cudaEvent_t event, cudaStream_t stream __dv(0), + unsigned int flags __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaEvent_t, cudaStream_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaEventRecordWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, stream, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventQuery(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventSynchronize(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventDestroy(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventElapsedTime(float *ms, + cudaEvent_t start, + cudaEvent_t end) { + using FuncPtr = cudaError_t(CUDARTAPI *)(float *, cudaEvent_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventElapsedTime"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ms, start, end); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalMemory( + cudaExternalMemory_t *extMem_out, + const struct cudaExternalMemoryHandleDesc *memHandleDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaExternalMemory_t *, const struct cudaExternalMemoryHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem_out, memHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedBuffer( + void **devPtr, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryBufferDesc *bufferDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaExternalMemory_t, + const struct cudaExternalMemoryBufferDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedBuffer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, extMem, bufferDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmap, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryMipmappedArrayDesc *mipmapDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, cudaExternalMemory_t, + const struct cudaExternalMemoryMipmappedArrayDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmap, extMem, mipmapDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalMemory(cudaExternalMemory_t extMem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalMemory_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalSemaphore( + cudaExternalSemaphore_t *extSem_out, + const struct cudaExternalSemaphoreHandleDesc *semHandleDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem_out, semHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaSignalExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreSignalParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreSignalParams *, + unsigned int, cudaStream_t); + static auto func_ptr = + LoadSymbol("cudaSignalExternalSemaphoresAsync_v2"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaWaitExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreWaitParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreWaitParams *, + unsigned int, cudaStream_t); + static auto func_ptr = + LoadSymbol("cudaWaitExternalSemaphoresAsync_v2"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalSemaphore(cudaExternalSemaphore_t extSem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem); +} + +extern __host__ cudaError_t CUDARTAPI +cudaLaunchKernel(const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernel( + const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchCooperativeKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaLaunchCooperativeKernelMultiDevice( + struct cudaLaunchParams *launchParamsList, unsigned int numDevices, + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaLaunchParams *, + unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaLaunchCooperativeKernelMultiDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(launchParamsList, numDevices, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetCacheConfig(const void *func, enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaFuncSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, cacheConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetSharedMemConfig(const void *func, enum cudaSharedMemConfig config) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaFuncSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, config); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncGetAttributes(struct cudaFuncAttributes *attr, const void *func) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaFuncAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaFuncGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attr, func); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncSetAttribute(const void *func, enum cudaFuncAttribute attr, int value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncAttribute, int); + static auto func_ptr = LoadSymbol("cudaFuncSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, attr, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForDevice(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForHost(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchHostFunc(cudaStream_t stream, + cudaHostFn_t fn, + void *userData) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaHostFn_t, void *); + static auto func_ptr = LoadSymbol("cudaLaunchHostFunc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, fn, userData); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessor(int *numBlocks, const void *func, + int blockSize, + size_t dynamicSMemSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t); + static auto func_ptr = + LoadSymbol("cudaOccupancyMaxActiveBlocksPerMultiprocessor"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyAvailableDynamicSMemPerBlock(size_t *dynamicSmemSize, + const void *func, int numBlocks, + int blockSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, const void *, int, int); + static auto func_ptr = + LoadSymbol("cudaOccupancyAvailableDynamicSMemPerBlock"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dynamicSmemSize, func, numBlocks, blockSize); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(int *numBlocks, + const void *func, + int blockSize, + size_t dynamicSMemSize, + unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t, unsigned int); + static auto func_ptr = LoadSymbol( + "cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMallocManaged(void **devPtr, size_t size, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocManaged"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMalloc(void **devPtr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMalloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocHost(void **ptr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMallocHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocPitch(void **devPtr, + size_t *pitch, + size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t *, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMallocPitch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocArray( + cudaArray_t *array, const struct cudaChannelFormatDesc *desc, size_t width, + size_t height __dv(0), unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + size_t, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, width, height, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFree(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFree"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeHost(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFreeHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeArray(cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t); + static auto func_ptr = LoadSymbol("cudaFreeArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFreeMipmappedArray(cudaMipmappedArray_t mipmappedArray) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t); + static auto func_ptr = LoadSymbol("cudaFreeMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostAlloc(void **pHost, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostAlloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pHost, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostRegister(void *ptr, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostRegister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostUnregister(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaHostUnregister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostGetDevicePointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pDevice, pHost, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostGetFlags(unsigned int *pFlags, + void *pHost) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *, void *); + static auto func_ptr = LoadSymbol("cudaHostGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pFlags, pHost); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3D(struct cudaPitchedPtr *pitchedDevPtr, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr *, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMalloc3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, extent); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3DArray(cudaArray_t *array, const struct cudaChannelFormatDesc *desc, + struct cudaExtent extent, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int); + static auto func_ptr = LoadSymbol("cudaMalloc3DArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, extent, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, + const struct cudaChannelFormatDesc *desc, struct cudaExtent extent, + unsigned int numLevels, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, desc, extent, numLevels, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetMipmappedArrayLevel( + cudaArray_t *levelArray, cudaMipmappedArray_const_t mipmappedArray, + unsigned int level) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaMipmappedArray_const_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGetMipmappedArrayLevel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(levelArray, mipmappedArray, level); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3D(const struct cudaMemcpy3DParms *p) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3DPeer(const struct cudaMemcpy3DPeerParms *p) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy3DAsync( + const struct cudaMemcpy3DParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy3DPeerAsync( + const struct cudaMemcpy3DPeerParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemGetInfo(size_t *free, + size_t *total) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaMemGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(free, total); +} + +extern __host__ cudaError_t CUDARTAPI +cudaArrayGetInfo(struct cudaChannelFormatDesc *desc, struct cudaExtent *extent, + unsigned int *flags, cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + struct cudaExtent *, unsigned int *, + cudaArray_t); + static auto func_ptr = LoadSymbol("cudaArrayGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, extent, flags, array); +} + +extern __host__ cudaError_t CUDARTAPI cudaArrayGetPlane( + cudaArray_t *pPlaneArray, cudaArray_t hArray, unsigned int planeIdx) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t *, cudaArray_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaArrayGetPlane"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pPlaneArray, hArray, planeIdx); +} + +#if CUDA_VERSION >= 11010 + +extern __host__ cudaError_t CUDARTAPI cudaArrayGetSparseProperties( + struct cudaArraySparseProperties *sparseProperties, cudaArray_t array) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaArraySparseProperties *, cudaArray_t); + static auto func_ptr = LoadSymbol("cudaArrayGetSparseProperties"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(sparseProperties, array); +} + +extern __host__ cudaError_t CUDARTAPI cudaMipmappedArrayGetSparseProperties( + struct cudaArraySparseProperties *sparseProperties, + cudaMipmappedArray_t mipmap) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaArraySparseProperties *, + cudaMipmappedArray_t); + static auto func_ptr = + LoadSymbol("cudaMipmappedArrayGetSparseProperties"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(sparseProperties, mipmap); +} + +#endif // CUDA_VERSION >= 11010 + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy(void *dst, const void *src, + size_t count, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyPeer(void *dst, int dstDevice, + const void *src, + int srcDevice, + size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, int, const void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2D(void *dst, size_t dpitch, + const void *src, + size_t spitch, size_t width, + size_t height, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArray( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArray( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, size_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t width, + size_t height, enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + cudaArray_const_t, size_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbol( + const void *symbol, const void *src, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyHostToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, + size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbol( + void *dst, const void *symbol, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToHost)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemcpyAsync(void *dst, const void *src, size_t count, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyPeerAsync(void *dst, int dstDevice, const void *src, int srcDevice, + size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, const void *, int, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy2DAsync( + void *dst, size_t dpitch, const void *src, size_t spitch, size_t width, + size_t height, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + const void *, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArrayAsync( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, + size_t, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbolAsync( + const void *symbol, const void *src, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbolAsync( + void *dst, const void *symbol, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset(void *devPtr, int value, + size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset2D(void *devPtr, size_t pitch, + int value, size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMemset2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset3D( + struct cudaPitchedPtr pitchedDevPtr, int value, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMemset3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemsetAsync( + void *devPtr, int value, size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemsetAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset2DAsync(void *devPtr, size_t pitch, int value, size_t width, + size_t height, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset3DAsync(struct cudaPitchedPtr pitchedDevPtr, int value, + struct cudaExtent extent, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, + struct cudaExtent, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolAddress(void **devPtr, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolAddress"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolSize(size_t *size, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolSize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(size, symbol); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPrefetchAsync(const void *devPtr, size_t count, int dstDevice, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, size_t, int, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemPrefetchAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, dstDevice, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemAdvise(const void *devPtr, size_t count, enum cudaMemoryAdvise advice, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, size_t, + enum cudaMemoryAdvise, int); + static auto func_ptr = LoadSymbol("cudaMemAdvise"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, advice, device); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttribute( + void *data, size_t dataSize, enum cudaMemRangeAttribute attribute, + const void *devPtr, size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + void *, size_t, enum cudaMemRangeAttribute, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSize, attribute, devPtr, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttributes( + void **data, size_t *dataSizes, enum cudaMemRangeAttribute *attributes, + size_t numAttributes, const void *devPtr, size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, enum cudaMemRangeAttribute *, + size_t, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSizes, attributes, numAttributes, devPtr, count); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, + const void *src, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t, size_t, size_t, const void *, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArray(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t count, + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, cudaArray_const_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t count, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind, stream); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArrayAsync(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocAsync(void **devPtr, + size_t size, + cudaStream_t hStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMallocAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, hStream); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeAsync(void *devPtr, + cudaStream_t hStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaFreeAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, hStream); +} + +#if CUDA_VERSION >= 11020 + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolTrimTo(cudaMemPool_t memPool, + size_t minBytesToKeep) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t, size_t); + static auto func_ptr = LoadSymbol("cudaMemPoolTrimTo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, minBytesToKeep); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolSetAttribute( + cudaMemPool_t memPool, enum cudaMemPoolAttr attr, void *value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMemPool_t, enum cudaMemPoolAttr, void *); + static auto func_ptr = LoadSymbol("cudaMemPoolSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, attr, value); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolGetAttribute( + cudaMemPool_t memPool, enum cudaMemPoolAttr attr, void *value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMemPool_t, enum cudaMemPoolAttr, void *); + static auto func_ptr = LoadSymbol("cudaMemPoolGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, attr, value); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPoolSetAccess(cudaMemPool_t memPool, + const struct cudaMemAccessDesc *descList, size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMemPool_t, const struct cudaMemAccessDesc *, size_t); + static auto func_ptr = LoadSymbol("cudaMemPoolSetAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, descList, count); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPoolGetAccess(enum cudaMemAccessFlags *flags, cudaMemPool_t memPool, + struct cudaMemLocation *location) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + enum cudaMemAccessFlags *, cudaMemPool_t, struct cudaMemLocation *); + static auto func_ptr = LoadSymbol("cudaMemPoolGetAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags, memPool, location); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolCreate( + cudaMemPool_t *memPool, const struct cudaMemPoolProps *poolProps) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t *, + const struct cudaMemPoolProps *); + static auto func_ptr = LoadSymbol("cudaMemPoolCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, poolProps); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPoolDestroy(cudaMemPool_t memPool) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t); + static auto func_ptr = LoadSymbol("cudaMemPoolDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocFromPoolAsync( + void **ptr, size_t size, cudaMemPool_t memPool, cudaStream_t stream) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t, cudaMemPool_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMallocFromPoolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size, memPool, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolExportToShareableHandle( + void *shareableHandle, cudaMemPool_t memPool, + enum cudaMemAllocationHandleType handleType, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + void *, cudaMemPool_t, enum cudaMemAllocationHandleType, unsigned int); + static auto func_ptr = + LoadSymbol("cudaMemPoolExportToShareableHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(shareableHandle, memPool, handleType, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolImportFromShareableHandle( + cudaMemPool_t *memPool, void *shareableHandle, + enum cudaMemAllocationHandleType handleType, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMemPool_t *, void *, enum cudaMemAllocationHandleType, unsigned int); + static auto func_ptr = + LoadSymbol("cudaMemPoolImportFromShareableHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, shareableHandle, handleType, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolExportPointer( + struct cudaMemPoolPtrExportData *exportData, void *ptr) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaMemPoolPtrExportData *, void *); + static auto func_ptr = LoadSymbol("cudaMemPoolExportPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(exportData, ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPoolImportPointer(void **ptr, cudaMemPool_t memPool, + struct cudaMemPoolPtrExportData *exportData) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, cudaMemPool_t, + struct cudaMemPoolPtrExportData *); + static auto func_ptr = LoadSymbol("cudaMemPoolImportPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, memPool, exportData); +} + +#endif // CUDA_VERSION >= 11020 + +extern __host__ cudaError_t CUDARTAPI cudaPointerGetAttributes( + struct cudaPointerAttributes *attributes, const void *ptr) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPointerAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaPointerGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attributes, ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceCanAccessPeer(int *canAccessPeer, int device, int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceCanAccessPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(canAccessPeer, device, peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceEnablePeerAccess(int peerDevice, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int, unsigned int); + static auto func_ptr = LoadSymbol("cudaDeviceEnablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceDisablePeerAccess(int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaDeviceDisablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsUnregisterResource(cudaGraphicsResource_t resource) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnregisterResource"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceSetMapFlags( + cudaGraphicsResource_t resource, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphicsResourceSetMapFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsMapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsMapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsUnmapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnmapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceGetMappedPointer( + void **devPtr, size_t *size, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsSubResourceGetMappedArray( + cudaArray_t *array, cudaGraphicsResource_t resource, + unsigned int arrayIndex, unsigned int mipLevel) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaGraphicsResource_t, unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaGraphicsSubResourceGetMappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, resource, arrayIndex, mipLevel); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsResourceGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, resource); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaBindTexture( + size_t *offset, const struct textureReference *texref, const void *devPtr, + const struct cudaChannelFormatDesc *desc, size_t size __dv(UINT_MAX)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, size); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaBindTexture2D(size_t *offset, const struct textureReference *texref, + const void *devPtr, const struct cudaChannelFormatDesc *desc, + size_t width, size_t height, size_t pitch) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, width, height, pitch); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaBindTextureToArray( + const struct textureReference *texref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, array, desc); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaBindTextureToMipmappedArray(const struct textureReference *texref, + cudaMipmappedArray_const_t mipmappedArray, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaMipmappedArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, mipmappedArray, desc); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaUnbindTexture(const struct textureReference *texref) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaUnbindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaGetTextureAlignmentOffset(size_t *offset, + const struct textureReference *texref) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(size_t *, const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaGetTextureAlignmentOffset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaGetTextureReference( + const struct textureReference **texref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct textureReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetTextureReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, symbol); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaBindSurfaceToArray( + const struct surfaceReference *surfref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct surfaceReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindSurfaceToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, array, desc); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaGetSurfaceReference( + const struct surfaceReference **surfref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct surfaceReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSurfaceReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetChannelDesc( + struct cudaChannelFormatDesc *desc, cudaArray_const_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + cudaArray_const_t); + static auto func_ptr = LoadSymbol("cudaGetChannelDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, array); +} + +extern __host__ struct cudaChannelFormatDesc CUDARTAPI cudaCreateChannelDesc( + int x, int y, int z, int w, enum cudaChannelFormatKind f) { + using FuncPtr = struct cudaChannelFormatDesc(CUDARTAPI *)( + int, int, int, int, enum cudaChannelFormatKind); + static auto func_ptr = LoadSymbol("cudaCreateChannelDesc"); + if (!func_ptr) { + return cudaChannelFormatDesc{cudaChannelFormatKind(-1), 0, 0, 0}; + } + return func_ptr(x, y, z, w, f); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateTextureObject( + cudaTextureObject_t *pTexObject, const struct cudaResourceDesc *pResDesc, + const struct cudaTextureDesc *pTexDesc, + const struct cudaResourceViewDesc *pResViewDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaTextureObject_t *, const struct cudaResourceDesc *, + const struct cudaTextureDesc *, const struct cudaResourceViewDesc *); + static auto func_ptr = LoadSymbol("cudaCreateTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexObject, pResDesc, pTexDesc, pResViewDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyTextureObject(cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaDestroyTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectTextureDesc( + struct cudaTextureDesc *pTexDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaTextureDesc *, cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaGetTextureObjectTextureDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceViewDesc( + struct cudaResourceViewDesc *pResViewDesc, cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaResourceViewDesc *, + cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceViewDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResViewDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateSurfaceObject( + cudaSurfaceObject_t *pSurfObject, const struct cudaResourceDesc *pResDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t *, + const struct cudaResourceDesc *); + static auto func_ptr = LoadSymbol("cudaCreateSurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pSurfObject, pResDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroySurfaceObject(cudaSurfaceObject_t surfObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t); + static auto func_ptr = LoadSymbol("cudaDestroySurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaSurfaceObject_t surfObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaSurfaceObject_t); + static auto func_ptr = + LoadSymbol("cudaGetSurfaceObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaDriverGetVersion(int *driverVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaDriverGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(driverVersion); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaRuntimeGetVersion(int *runtimeVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaRuntimeGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(runtimeVersion); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphCreate(cudaGraph_t *pGraph, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraph, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddKernelNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddKernelNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeGetParams( + cudaGraphNode_t node, struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeSetParams( + cudaGraphNode_t node, const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphKernelNodeCopyAttributes(cudaGraphNode_t hSrc, cudaGraphNode_t hDst) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t); + static auto func_ptr = + LoadSymbol("cudaGraphKernelNodeCopyAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hSrc, hDst); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeGetAttribute( + cudaGraphNode_t hNode, enum cudaKernelNodeAttrID attr, + union cudaKernelNodeAttrValue *value_out) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, enum cudaKernelNodeAttrID, + union cudaKernelNodeAttrValue *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hNode, attr, value_out); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeSetAttribute( + cudaGraphNode_t hNode, enum cudaKernelNodeAttrID attr, + const union cudaKernelNodeAttrValue *value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, enum cudaKernelNodeAttrID, + const union cudaKernelNodeAttrValue *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hNode, attr, value); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemcpyNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemcpy3DParms *pCopyParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemcpyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pCopyParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemcpyNodeToSymbol( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const void *symbol, const void *src, size_t count, size_t offset, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t *, cudaGraph_t, const cudaGraphNode_t *, size_t, + const void *, const void *, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaGraphAddMemcpyNodeToSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, symbol, + src, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemcpyNodeFromSymbol( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, void *dst, + const void *symbol, size_t count, size_t offset, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t *, cudaGraph_t, const cudaGraphNode_t *, size_t, void *, + const void *, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = + LoadSymbol("cudaGraphAddMemcpyNodeFromSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, dst, + symbol, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemcpyNode1D( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, void *dst, + const void *src, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t *, cudaGraph_t, const cudaGraphNode_t *, size_t, void *, + const void *, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaGraphAddMemcpyNode1D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, dst, src, + count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeGetParams( + cudaGraphNode_t node, struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeSetParams( + cudaGraphNode_t node, const struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeSetParamsToSymbol( + cudaGraphNode_t node, const void *symbol, const void *src, size_t count, + size_t offset, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, const void *, const void *, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = + LoadSymbol("cudaGraphMemcpyNodeSetParamsToSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, symbol, src, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeSetParamsFromSymbol( + cudaGraphNode_t node, void *dst, const void *symbol, size_t count, + size_t offset, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, void *, const void *, size_t, + size_t, enum cudaMemcpyKind); + static auto func_ptr = + LoadSymbol("cudaGraphMemcpyNodeSetParamsFromSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, dst, symbol, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphMemcpyNodeSetParams1D(cudaGraphNode_t node, void *dst, const void *src, + size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t, void *, const void *, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeSetParams1D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, dst, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemsetNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemsetParams *pMemsetParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemsetNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pMemsetParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeGetParams( + cudaGraphNode_t node, struct cudaMemsetParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeSetParams( + cudaGraphNode_t node, const struct cudaMemsetParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddHostNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddHostNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeGetParams( + cudaGraphNode_t node, struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeSetParams( + cudaGraphNode_t node, const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddChildGraphNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, + size_t numDependencies, cudaGraph_t childGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphAddChildGraphNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + childGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphChildGraphNodeGetGraph(cudaGraphNode_t node, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaGraphChildGraphNodeGetGraph"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddEmptyNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddEmptyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddEventRecordNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, + size_t numDependencies, cudaEvent_t event) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaGraphAddEventRecordNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphEventRecordNodeGetEvent(cudaGraphNode_t node, cudaEvent_t *event_out) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaEvent_t *); + static auto func_ptr = + LoadSymbol("cudaGraphEventRecordNodeGetEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, event_out); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphEventRecordNodeSetEvent(cudaGraphNode_t node, cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaEvent_t); + static auto func_ptr = + LoadSymbol("cudaGraphEventRecordNodeSetEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddEventWaitNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, + size_t numDependencies, cudaEvent_t event) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaGraphAddEventWaitNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphEventWaitNodeGetEvent(cudaGraphNode_t node, cudaEvent_t *event_out) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaEvent_t *); + static auto func_ptr = LoadSymbol("cudaGraphEventWaitNodeGetEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, event_out); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphEventWaitNodeSetEvent(cudaGraphNode_t node, cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaGraphEventWaitNodeSetEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, event); +} + +#if CUDA_VERSION >= 11020 + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddExternalSemaphoresSignalNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaExternalSemaphoreSignalNodeParams *nodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t *, cudaGraph_t, const cudaGraphNode_t *, size_t, + const struct cudaExternalSemaphoreSignalNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphAddExternalSemaphoresSignalNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + nodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExternalSemaphoresSignalNodeGetParams( + cudaGraphNode_t hNode, + struct cudaExternalSemaphoreSignalNodeParams *params_out) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t, struct cudaExternalSemaphoreSignalNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExternalSemaphoresSignalNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hNode, params_out); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExternalSemaphoresSignalNodeSetParams( + cudaGraphNode_t hNode, + const struct cudaExternalSemaphoreSignalNodeParams *nodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t, const struct cudaExternalSemaphoreSignalNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExternalSemaphoresSignalNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hNode, nodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddExternalSemaphoresWaitNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaExternalSemaphoreWaitNodeParams *nodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t *, cudaGraph_t, const cudaGraphNode_t *, size_t, + const struct cudaExternalSemaphoreWaitNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphAddExternalSemaphoresWaitNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + nodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExternalSemaphoresWaitNodeGetParams( + cudaGraphNode_t hNode, + struct cudaExternalSemaphoreWaitNodeParams *params_out) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t, struct cudaExternalSemaphoreWaitNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExternalSemaphoresWaitNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hNode, params_out); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExternalSemaphoresWaitNodeSetParams( + cudaGraphNode_t hNode, + const struct cudaExternalSemaphoreWaitNodeParams *nodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphNode_t, const struct cudaExternalSemaphoreWaitNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExternalSemaphoresWaitNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hNode, nodeParams); +} + +#endif // CUDA_VERSION >= 11020 + +extern __host__ cudaError_t CUDARTAPI +cudaGraphClone(cudaGraph_t *pGraphClone, cudaGraph_t originalGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphClone, originalGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeFindInClone(cudaGraphNode_t *pNode, cudaGraphNode_t originalNode, + cudaGraph_t clonedGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraphNode_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphNodeFindInClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pNode, originalNode, clonedGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeGetType(cudaGraphNode_t node, enum cudaGraphNodeType *pType) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, enum cudaGraphNodeType *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetType"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pType); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetNodes(cudaGraph_t graph, + cudaGraphNode_t *nodes, + size_t *numNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, nodes, numNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetRootNodes( + cudaGraph_t graph, cudaGraphNode_t *pRootNodes, size_t *pNumRootNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetRootNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, pRootNodes, pNumRootNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetEdges(cudaGraph_t graph, + cudaGraphNode_t *from, + cudaGraphNode_t *to, + size_t *numEdges) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, + cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetEdges"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numEdges); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependencies( + cudaGraphNode_t node, cudaGraphNode_t *pDependencies, + size_t *pNumDependencies) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependencies, pNumDependencies); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependentNodes( + cudaGraphNode_t node, cudaGraphNode_t *pDependentNodes, + size_t *pNumDependentNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependentNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependentNodes, pNumDependentNodes); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddDependencies(cudaGraph_t graph, const cudaGraphNode_t *from, + const cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, const cudaGraphNode_t *, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphRemoveDependencies(cudaGraph_t graph, const cudaGraphNode_t *from, + const cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, const cudaGraphNode_t *, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphRemoveDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphDestroyNode(cudaGraphNode_t node) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphInstantiate( + cudaGraphExec_t *pGraphExec, cudaGraph_t graph, cudaGraphNode_t *pErrorNode, + char *pLogBuffer, size_t bufferSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t *, cudaGraph_t, + cudaGraphNode_t *, char *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphInstantiate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphExec, graph, pErrorNode, pLogBuffer, bufferSize); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecKernelNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExecKernelNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecMemcpyNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = + LoadSymbol("cudaGraphExecMemcpyNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecMemcpyNodeSetParamsToSymbol( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, const void *symbol, + const void *src, size_t count, size_t offset, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const void *, const void *, size_t, + size_t, enum cudaMemcpyKind); + static auto func_ptr = + LoadSymbol("cudaGraphExecMemcpyNodeSetParamsToSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, symbol, src, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecMemcpyNodeSetParamsFromSymbol(cudaGraphExec_t hGraphExec, + cudaGraphNode_t node, void *dst, + const void *symbol, size_t count, + size_t offset, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + void *, const void *, size_t, size_t, + enum cudaMemcpyKind); + static auto func_ptr = + LoadSymbol("cudaGraphExecMemcpyNodeSetParamsFromSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, dst, symbol, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecMemcpyNodeSetParams1D( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, void *dst, + const void *src, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, void *, + const void *, size_t, enum cudaMemcpyKind); + static auto func_ptr = + LoadSymbol("cudaGraphExecMemcpyNodeSetParams1D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, dst, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecMemsetNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaMemsetParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaMemsetParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExecMemsetNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecHostNodeSetParams(cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphExecHostNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecChildGraphNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, cudaGraph_t childGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, cudaGraph_t); + static auto func_ptr = + LoadSymbol("cudaGraphExecChildGraphNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, childGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecEventRecordNodeSetEvent( + cudaGraphExec_t hGraphExec, cudaGraphNode_t hNode, cudaEvent_t event) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, cudaEvent_t); + static auto func_ptr = + LoadSymbol("cudaGraphExecEventRecordNodeSetEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, hNode, event); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecEventWaitNodeSetEvent( + cudaGraphExec_t hGraphExec, cudaGraphNode_t hNode, cudaEvent_t event) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, cudaEvent_t); + static auto func_ptr = + LoadSymbol("cudaGraphExecEventWaitNodeSetEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, hNode, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecExternalSemaphoresSignalNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t hNode, + const struct cudaExternalSemaphoreSignalNodeParams *nodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphExec_t, cudaGraphNode_t, + const struct cudaExternalSemaphoreSignalNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExecExternalSemaphoresSignalNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, hNode, nodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecExternalSemaphoresWaitNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t hNode, + const struct cudaExternalSemaphoreWaitNodeParams *nodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaGraphExec_t, cudaGraphNode_t, + const struct cudaExternalSemaphoreWaitNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExecExternalSemaphoresWaitNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, hNode, nodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecUpdate(cudaGraphExec_t hGraphExec, cudaGraph_t hGraph, + cudaGraphNode_t *hErrorNode_out, + enum cudaGraphExecUpdateResult *updateResult_out) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraph_t, cudaGraphNode_t *, + enum cudaGraphExecUpdateResult *); + static auto func_ptr = LoadSymbol("cudaGraphExecUpdate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, hGraph, hErrorNode_out, updateResult_out); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphUpload(cudaGraphExec_t graphExec, + cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphUpload"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphLaunch(cudaGraphExec_t graphExec, + cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphLaunch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecDestroy(cudaGraphExec_t graphExec) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t); + static auto func_ptr = LoadSymbol("cudaGraphExecDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphDestroy(cudaGraph_t graph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphDebugDotPrint( + cudaGraph_t graph, const char *path, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, const char *, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphDebugDotPrint"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, path, flags); +} + +#if CUDA_VERSION >= 11030 + +extern __host__ cudaError_t CUDARTAPI cudaUserObjectCreate( + cudaUserObject_t *object_out, void *ptr, cudaHostFn_t destroy, + unsigned int initialRefcount, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaUserObject_t *, void *, cudaHostFn_t, unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaUserObjectCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(object_out, ptr, destroy, initialRefcount, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaUserObjectRetain(cudaUserObject_t object, unsigned int count __dv(1)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaUserObject_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaUserObjectRetain"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(object, count); +} + +extern __host__ cudaError_t CUDARTAPI +cudaUserObjectRelease(cudaUserObject_t object, unsigned int count __dv(1)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaUserObject_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaUserObjectRelease"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(object, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphRetainUserObject( + cudaGraph_t graph, cudaUserObject_t object, unsigned int count __dv(1), + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaUserObject_t, + unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphRetainUserObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, object, count, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphReleaseUserObject( + cudaGraph_t graph, cudaUserObject_t object, unsigned int count __dv(1)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaUserObject_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphReleaseUserObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, object, count); +} + +#endif // CUDA_VERSION >= 11030 + +extern __host__ cudaError_t CUDARTAPI cudaGetDriverEntryPoint( + const char *symbol, void **funcPtr, unsigned long long flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const char *, void **, unsigned long long); + static auto func_ptr = LoadSymbol("cudaGetDriverEntryPoint"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, funcPtr, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetExportTable( + const void **ppExportTable, const cudaUUID_t *pExportTableId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void **, const cudaUUID_t *); + static auto func_ptr = LoadSymbol("cudaGetExportTable"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ppExportTable, pExportTableId); +} + +#if CUDA_VERSION >= 11020 + +extern __host__ cudaError_t CUDARTAPI_CDECL +cudaGetFuncBySymbol(cudaFunction_t *functionPtr, const void *symbolPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaFunction_t *, const void *); + static auto func_ptr = LoadSymbol("cudaGetFuncBySymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(functionPtr, symbolPtr); +} + +#endif // CUDA_VERSION >= 11020 + +} // extern "C" diff --git a/source/lib/src/cuda/cudart/cuda_runtime_11_2.inc b/source/lib/src/cuda/cudart/cuda_runtime_11_2.inc new file mode 100644 index 0000000000..5c0ba7fe6a --- /dev/null +++ b/source/lib/src/cuda/cudart/cuda_runtime_11_2.inc @@ -0,0 +1,2259 @@ +// Auto-generated, do not edit. + +extern "C" { +extern __host__ cudaError_t CUDARTAPI cudaDeviceReset(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceReset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceSetLimit(enum cudaLimit limit, + size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaDeviceSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaDeviceGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaDeviceGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetStreamPriorityRange(int *leastPriority, int *greatestPriority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int *); + static auto func_ptr = + LoadSymbol("cudaDeviceGetStreamPriorityRange"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(leastPriority, greatestPriority); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaDeviceSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetSharedMemConfig(enum cudaSharedMemConfig *pConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig *); + static auto func_ptr = LoadSymbol("cudaDeviceGetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetSharedMemConfig(enum cudaSharedMemConfig config) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaDeviceSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(config); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetByPCIBusId(int *device, const char *pciBusId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const char *); + static auto func_ptr = LoadSymbol("cudaDeviceGetByPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, pciBusId); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceGetPCIBusId(char *pciBusId, + int len, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(char *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pciBusId, len, device); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetEventHandle(cudaIpcEventHandle_t *handle, cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcEventHandle_t *, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaIpcGetEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcOpenEventHandle(cudaEvent_t *event, cudaIpcEventHandle_t handle) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, cudaIpcEventHandle_t); + static auto func_ptr = LoadSymbol("cudaIpcOpenEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, handle); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetMemHandle(cudaIpcMemHandle_t *handle, void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcMemHandle_t *, void *); + static auto func_ptr = LoadSymbol("cudaIpcGetMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcOpenMemHandle( + void **devPtr, cudaIpcMemHandle_t handle, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaIpcMemHandle_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaIpcOpenMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, handle, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcCloseMemHandle(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaIpcCloseMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaThreadExit(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadExit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetLimit(enum cudaLimit limit, size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaThreadSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaThreadGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaThreadGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaThreadSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaThreadSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaGetLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaPeekAtLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaPeekAtLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorName(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorName"); + if (!func_ptr) return "cudaGetErrorName symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorString(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorString"); + if (!func_ptr) return "cudaGetErrorString symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceCount(int *count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceCount"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaDeviceProp *, int); + static auto func_ptr = LoadSymbol("cudaGetDeviceProperties"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(prop, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetAttribute(int *value, enum cudaDeviceAttr attr, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceAttr, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, device); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetDefaultMemPool(cudaMemPool_t *memPool, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t *, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetDefaultMemPool"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, device); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetMemPool(int device, cudaMemPool_t memPool) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int, cudaMemPool_t); + static auto func_ptr = LoadSymbol("cudaDeviceSetMemPool"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, memPool); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetMemPool(cudaMemPool_t *memPool, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t *, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetMemPool"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, device); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceGetNvSciSyncAttributes( + void *nvSciSyncAttrList, int device, int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, int); + static auto func_ptr = + LoadSymbol("cudaDeviceGetNvSciSyncAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(nvSciSyncAttrList, device, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetP2PAttribute(int *value, enum cudaDeviceP2PAttr attr, + int srcDevice, int dstDevice) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceP2PAttr, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetP2PAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, srcDevice, dstDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaChooseDevice(int *device, const struct cudaDeviceProp *prop) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const struct cudaDeviceProp *); + static auto func_ptr = LoadSymbol("cudaChooseDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, prop); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDevice(int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaSetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDevice(int *device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetValidDevices(int *device_arr, + int len) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int); + static auto func_ptr = LoadSymbol("cudaSetValidDevices"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device_arr, len); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDeviceFlags(unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int); + static auto func_ptr = LoadSymbol("cudaSetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetDeviceFlags(unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamCreate(cudaStream_t *pStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *); + static auto func_ptr = LoadSymbol("cudaStreamCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithFlags(cudaStream_t *pStream, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithPriority(cudaStream_t *pStream, unsigned int flags, + int priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int, int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetPriority(cudaStream_t hStream, int *priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, int *); + static auto func_ptr = LoadSymbol("cudaStreamGetPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetFlags(cudaStream_t hStream, unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, unsigned int *); + static auto func_ptr = LoadSymbol("cudaStreamGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaCtxResetPersistingL2Cache(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaCtxResetPersistingL2Cache"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCopyAttributes(cudaStream_t dst, cudaStream_t src) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamCopyAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetAttribute(cudaStream_t hStream, enum cudaStreamAttrID attr, + union cudaStreamAttrValue *value_out) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamAttrID, + union cudaStreamAttrValue *); + static auto func_ptr = LoadSymbol("cudaStreamGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, attr, value_out); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamSetAttribute(cudaStream_t hStream, enum cudaStreamAttrID attr, + const union cudaStreamAttrValue *value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamAttrID, + const union cudaStreamAttrValue *); + static auto func_ptr = LoadSymbol("cudaStreamSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, attr, value); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamDestroy(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaStreamWaitEvent( + cudaStream_t stream, cudaEvent_t event, unsigned int flags __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, cudaEvent_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamWaitEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, event, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamAddCallback(cudaStream_t stream, cudaStreamCallback_t callback, + void *userData, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaStreamCallback_t, + void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAddCallback"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, callback, userData, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamSynchronize(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamQuery(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamAttachMemAsync(cudaStream_t stream, void *devPtr, + size_t length __dv(0), unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAttachMemAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, devPtr, length, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamBeginCapture(cudaStream_t stream, enum cudaStreamCaptureMode mode) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamCaptureMode); + static auto func_ptr = LoadSymbol("cudaStreamBeginCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, mode); +} + +extern __host__ cudaError_t CUDARTAPI +cudaThreadExchangeStreamCaptureMode(enum cudaStreamCaptureMode *mode) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaStreamCaptureMode *); + static auto func_ptr = + LoadSymbol("cudaThreadExchangeStreamCaptureMode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mode); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamEndCapture(cudaStream_t stream, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaStreamEndCapture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamIsCapturing( + cudaStream_t stream, enum cudaStreamCaptureStatus *pCaptureStatus) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, enum cudaStreamCaptureStatus *); + static auto func_ptr = LoadSymbol("cudaStreamIsCapturing"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pCaptureStatus); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamGetCaptureInfo( + cudaStream_t stream, enum cudaStreamCaptureStatus *pCaptureStatus, + unsigned long long *pId) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaStream_t, enum cudaStreamCaptureStatus *, unsigned long long *); + static auto func_ptr = LoadSymbol("cudaStreamGetCaptureInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, pCaptureStatus, pId); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamGetCaptureInfo_v2( + cudaStream_t stream, enum cudaStreamCaptureStatus *captureStatus_out, + unsigned long long *id_out __dv(0), cudaGraph_t *graph_out __dv(0), + const cudaGraphNode_t **dependencies_out __dv(0), + size_t *numDependencies_out __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaStream_t, enum cudaStreamCaptureStatus *, unsigned long long *, + cudaGraph_t *, const cudaGraphNode_t **, size_t *); + static auto func_ptr = LoadSymbol("cudaStreamGetCaptureInfo_v2"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, captureStatus_out, id_out, graph_out, + dependencies_out, numDependencies_out); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamUpdateCaptureDependencies( + cudaStream_t stream, cudaGraphNode_t *dependencies, size_t numDependencies, + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaGraphNode_t *, + size_t, unsigned int); + static auto func_ptr = + LoadSymbol("cudaStreamUpdateCaptureDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, dependencies, numDependencies, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventCreate(cudaEvent_t *event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *); + static auto func_ptr = LoadSymbol("cudaEventCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventCreateWithFlags(cudaEvent_t *event, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaEventCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventRecord(cudaEvent_t event, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaEventRecord"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventQuery(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventSynchronize(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventDestroy(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventElapsedTime(float *ms, + cudaEvent_t start, + cudaEvent_t end) { + using FuncPtr = cudaError_t(CUDARTAPI *)(float *, cudaEvent_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventElapsedTime"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ms, start, end); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalMemory( + cudaExternalMemory_t *extMem_out, + const struct cudaExternalMemoryHandleDesc *memHandleDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaExternalMemory_t *, const struct cudaExternalMemoryHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem_out, memHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedBuffer( + void **devPtr, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryBufferDesc *bufferDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaExternalMemory_t, + const struct cudaExternalMemoryBufferDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedBuffer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, extMem, bufferDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaExternalMemoryGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmap, cudaExternalMemory_t extMem, + const struct cudaExternalMemoryMipmappedArrayDesc *mipmapDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, cudaExternalMemory_t, + const struct cudaExternalMemoryMipmappedArrayDesc *); + static auto func_ptr = + LoadSymbol("cudaExternalMemoryGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmap, extMem, mipmapDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalMemory(cudaExternalMemory_t extMem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalMemory_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalMemory"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extMem); +} + +extern __host__ cudaError_t CUDARTAPI cudaImportExternalSemaphore( + cudaExternalSemaphore_t *extSem_out, + const struct cudaExternalSemaphoreHandleDesc *semHandleDesc) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreHandleDesc *); + static auto func_ptr = LoadSymbol("cudaImportExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem_out, semHandleDesc); +} + +extern __host__ cudaError_t CUDARTAPI cudaSignalExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreSignalParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreSignalParams *, + unsigned int, cudaStream_t); + static auto func_ptr = LoadSymbol( + "__CUDART_API_PTSZ(cudaSignalExternalSemaphoresAsync_v2)"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaWaitExternalSemaphoresAsync( + const cudaExternalSemaphore_t *extSemArray, + const struct cudaExternalSemaphoreWaitParams *paramsArray, + unsigned int numExtSems, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const cudaExternalSemaphore_t *, + const struct cudaExternalSemaphoreWaitParams *, + unsigned int, cudaStream_t); + static auto func_ptr = LoadSymbol( + "__CUDART_API_PTSZ(cudaWaitExternalSemaphoresAsync_v2)"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSemArray, paramsArray, numExtSems, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyExternalSemaphore(cudaExternalSemaphore_t extSem) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaExternalSemaphore_t); + static auto func_ptr = LoadSymbol("cudaDestroyExternalSemaphore"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(extSem); +} + +extern __host__ cudaError_t CUDARTAPI +cudaLaunchKernel(const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernel( + const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchCooperativeKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernelMultiDevice( + struct cudaLaunchParams *launchParamsList, unsigned int numDevices, + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaLaunchParams *, + unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaLaunchCooperativeKernelMultiDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(launchParamsList, numDevices, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetCacheConfig(const void *func, enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaFuncSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, cacheConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetSharedMemConfig(const void *func, enum cudaSharedMemConfig config) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaFuncSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, config); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncGetAttributes(struct cudaFuncAttributes *attr, const void *func) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaFuncAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaFuncGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attr, func); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncSetAttribute(const void *func, enum cudaFuncAttribute attr, int value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncAttribute, int); + static auto func_ptr = LoadSymbol("cudaFuncSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, attr, value); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForDevice(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaSetDoubleForHost(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchHostFunc(cudaStream_t stream, + cudaHostFn_t fn, + void *userData) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaHostFn_t, void *); + static auto func_ptr = LoadSymbol("cudaLaunchHostFunc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, fn, userData); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessor(int *numBlocks, const void *func, + int blockSize, + size_t dynamicSMemSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t); + static auto func_ptr = + LoadSymbol("cudaOccupancyMaxActiveBlocksPerMultiprocessor"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyAvailableDynamicSMemPerBlock(size_t *dynamicSmemSize, + const void *func, int numBlocks, + int blockSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, const void *, int, int); + static auto func_ptr = + LoadSymbol("cudaOccupancyAvailableDynamicSMemPerBlock"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dynamicSmemSize, func, numBlocks, blockSize); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(int *numBlocks, + const void *func, + int blockSize, + size_t dynamicSMemSize, + unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t, unsigned int); + static auto func_ptr = LoadSymbol( + "cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMallocManaged(void **devPtr, size_t size, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocManaged"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMalloc(void **devPtr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMalloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocHost(void **ptr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMallocHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocPitch(void **devPtr, + size_t *pitch, + size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t *, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMallocPitch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocArray( + cudaArray_t *array, const struct cudaChannelFormatDesc *desc, size_t width, + size_t height __dv(0), unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + size_t, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, width, height, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFree(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFree"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeHost(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFreeHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeArray(cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t); + static auto func_ptr = LoadSymbol("cudaFreeArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFreeMipmappedArray(cudaMipmappedArray_t mipmappedArray) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t); + static auto func_ptr = LoadSymbol("cudaFreeMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostAlloc(void **pHost, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostAlloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pHost, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostRegister(void *ptr, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostRegister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostUnregister(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaHostUnregister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostGetDevicePointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pDevice, pHost, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostGetFlags(unsigned int *pFlags, + void *pHost) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *, void *); + static auto func_ptr = LoadSymbol("cudaHostGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pFlags, pHost); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3D(struct cudaPitchedPtr *pitchedDevPtr, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr *, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMalloc3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, extent); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3DArray(cudaArray_t *array, const struct cudaChannelFormatDesc *desc, + struct cudaExtent extent, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int); + static auto func_ptr = LoadSymbol("cudaMalloc3DArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, extent, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, + const struct cudaChannelFormatDesc *desc, struct cudaExtent extent, + unsigned int numLevels, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, desc, extent, numLevels, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetMipmappedArrayLevel( + cudaArray_t *levelArray, cudaMipmappedArray_const_t mipmappedArray, + unsigned int level) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaMipmappedArray_const_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGetMipmappedArrayLevel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(levelArray, mipmappedArray, level); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3D(const struct cudaMemcpy3DParms *p) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3DPeer(const struct cudaMemcpy3DPeerParms *p) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy3DAsync( + const struct cudaMemcpy3DParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy3DPeerAsync( + const struct cudaMemcpy3DPeerParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemGetInfo(size_t *free, + size_t *total) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaMemGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(free, total); +} + +extern __host__ cudaError_t CUDARTAPI +cudaArrayGetInfo(struct cudaChannelFormatDesc *desc, struct cudaExtent *extent, + unsigned int *flags, cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + struct cudaExtent *, unsigned int *, + cudaArray_t); + static auto func_ptr = LoadSymbol("cudaArrayGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, extent, flags, array); +} + +extern __host__ cudaError_t CUDARTAPI cudaArrayGetPlane( + cudaArray_t *pPlaneArray, cudaArray_t hArray, unsigned int planeIdx) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t *, cudaArray_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaArrayGetPlane"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pPlaneArray, hArray, planeIdx); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy(void *dst, const void *src, + size_t count, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyPeer(void *dst, int dstDevice, + const void *src, + int srcDevice, + size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, int, const void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2D(void *dst, size_t dpitch, + const void *src, + size_t spitch, size_t width, + size_t height, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArray( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArray( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, size_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t width, + size_t height, enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + cudaArray_const_t, size_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbol( + const void *symbol, const void *src, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyHostToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, + size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbol( + void *dst, const void *symbol, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToHost)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemcpyAsync(void *dst, const void *src, size_t count, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyPeerAsync(void *dst, int dstDevice, const void *src, int srcDevice, + size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, const void *, int, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy2DAsync( + void *dst, size_t dpitch, const void *src, size_t spitch, size_t width, + size_t height, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + const void *, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArrayAsync( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, + size_t, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbolAsync( + const void *symbol, const void *src, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbolAsync( + void *dst, const void *symbol, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset(void *devPtr, int value, + size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset2D(void *devPtr, size_t pitch, + int value, size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMemset2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset3D( + struct cudaPitchedPtr pitchedDevPtr, int value, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMemset3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemsetAsync( + void *devPtr, int value, size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemsetAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset2DAsync(void *devPtr, size_t pitch, int value, size_t width, + size_t height, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset3DAsync(struct cudaPitchedPtr pitchedDevPtr, int value, + struct cudaExtent extent, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, + struct cudaExtent, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolAddress(void **devPtr, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolAddress"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolSize(size_t *size, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolSize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(size, symbol); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPrefetchAsync(const void *devPtr, size_t count, int dstDevice, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, size_t, int, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemPrefetchAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, dstDevice, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemAdvise(const void *devPtr, size_t count, enum cudaMemoryAdvise advice, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, size_t, + enum cudaMemoryAdvise, int); + static auto func_ptr = LoadSymbol("cudaMemAdvise"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, advice, device); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttribute( + void *data, size_t dataSize, enum cudaMemRangeAttribute attribute, + const void *devPtr, size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + void *, size_t, enum cudaMemRangeAttribute, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSize, attribute, devPtr, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttributes( + void **data, size_t *dataSizes, enum cudaMemRangeAttribute *attributes, + size_t numAttributes, const void *devPtr, size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, enum cudaMemRangeAttribute *, + size_t, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSizes, attributes, numAttributes, devPtr, count); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, + const void *src, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t, size_t, size_t, const void *, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArray(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t count, + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, cudaArray_const_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + count, kind); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t count, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind, stream); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArrayAsync(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocAsync(void **devPtr, + size_t size, + cudaStream_t hStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMallocAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, hStream); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeAsync(void *devPtr, + cudaStream_t hStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaFreeAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, hStream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolTrimTo(cudaMemPool_t memPool, + size_t minBytesToKeep) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t, size_t); + static auto func_ptr = LoadSymbol("cudaMemPoolTrimTo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, minBytesToKeep); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolSetAttribute( + cudaMemPool_t memPool, enum cudaMemPoolAttr attr, void *value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMemPool_t, enum cudaMemPoolAttr, void *); + static auto func_ptr = LoadSymbol("cudaMemPoolSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, attr, value); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolGetAttribute( + cudaMemPool_t memPool, enum cudaMemPoolAttr attr, void *value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMemPool_t, enum cudaMemPoolAttr, void *); + static auto func_ptr = LoadSymbol("cudaMemPoolGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, attr, value); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPoolSetAccess(cudaMemPool_t memPool, + const struct cudaMemAccessDesc *descList, size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMemPool_t, const struct cudaMemAccessDesc *, size_t); + static auto func_ptr = LoadSymbol("cudaMemPoolSetAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, descList, count); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPoolGetAccess(enum cudaMemAccessFlags *flags, cudaMemPool_t memPool, + struct cudaMemLocation *location) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + enum cudaMemAccessFlags *, cudaMemPool_t, struct cudaMemLocation *); + static auto func_ptr = LoadSymbol("cudaMemPoolGetAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags, memPool, location); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolCreate( + cudaMemPool_t *memPool, const struct cudaMemPoolProps *poolProps) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t *, + const struct cudaMemPoolProps *); + static auto func_ptr = LoadSymbol("cudaMemPoolCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, poolProps); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPoolDestroy(cudaMemPool_t memPool) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMemPool_t); + static auto func_ptr = LoadSymbol("cudaMemPoolDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocFromPoolAsync( + void **ptr, size_t size, cudaMemPool_t memPool, cudaStream_t stream) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t, cudaMemPool_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMallocFromPoolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size, memPool, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolExportToShareableHandle( + void *shareableHandle, cudaMemPool_t memPool, + enum cudaMemAllocationHandleType handleType, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + void *, cudaMemPool_t, enum cudaMemAllocationHandleType, unsigned int); + static auto func_ptr = + LoadSymbol("cudaMemPoolExportToShareableHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(shareableHandle, memPool, handleType, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolImportFromShareableHandle( + cudaMemPool_t *memPool, void *shareableHandle, + enum cudaMemAllocationHandleType handleType, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMemPool_t *, void *, enum cudaMemAllocationHandleType, unsigned int); + static auto func_ptr = + LoadSymbol("cudaMemPoolImportFromShareableHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(memPool, shareableHandle, handleType, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemPoolExportPointer( + struct cudaMemPoolPtrExportData *exportData, void *ptr) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaMemPoolPtrExportData *, void *); + static auto func_ptr = LoadSymbol("cudaMemPoolExportPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(exportData, ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPoolImportPointer(void **ptr, cudaMemPool_t memPool, + struct cudaMemPoolPtrExportData *exportData) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, cudaMemPool_t, + struct cudaMemPoolPtrExportData *); + static auto func_ptr = LoadSymbol("cudaMemPoolImportPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, memPool, exportData); +} + +extern __host__ cudaError_t CUDARTAPI cudaPointerGetAttributes( + struct cudaPointerAttributes *attributes, const void *ptr) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPointerAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaPointerGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attributes, ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceCanAccessPeer(int *canAccessPeer, int device, int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceCanAccessPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(canAccessPeer, device, peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceEnablePeerAccess(int peerDevice, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int, unsigned int); + static auto func_ptr = LoadSymbol("cudaDeviceEnablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceDisablePeerAccess(int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaDeviceDisablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsUnregisterResource(cudaGraphicsResource_t resource) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnregisterResource"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceSetMapFlags( + cudaGraphicsResource_t resource, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphicsResourceSetMapFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsMapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsMapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsUnmapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnmapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceGetMappedPointer( + void **devPtr, size_t *size, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsSubResourceGetMappedArray( + cudaArray_t *array, cudaGraphicsResource_t resource, + unsigned int arrayIndex, unsigned int mipLevel) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaGraphicsResource_t, unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaGraphicsSubResourceGetMappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, resource, arrayIndex, mipLevel); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsResourceGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, resource); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaBindTexture( + size_t *offset, const struct textureReference *texref, const void *devPtr, + const struct cudaChannelFormatDesc *desc, size_t size __dv(UINT_MAX)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, size); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaBindTexture2D(size_t *offset, const struct textureReference *texref, + const void *devPtr, const struct cudaChannelFormatDesc *desc, + size_t width, size_t height, size_t pitch) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, width, height, pitch); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaBindTextureToArray( + const struct textureReference *texref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, array, desc); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaBindTextureToMipmappedArray(const struct textureReference *texref, + cudaMipmappedArray_const_t mipmappedArray, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaMipmappedArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, mipmappedArray, desc); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaUnbindTexture(const struct textureReference *texref) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaUnbindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI +cudaGetTextureAlignmentOffset(size_t *offset, + const struct textureReference *texref) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(size_t *, const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaGetTextureAlignmentOffset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaGetTextureReference( + const struct textureReference **texref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct textureReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetTextureReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, symbol); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaBindSurfaceToArray( + const struct surfaceReference *surfref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct surfaceReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindSurfaceToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, array, desc); +} + +extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaGetSurfaceReference( + const struct surfaceReference **surfref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct surfaceReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSurfaceReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetChannelDesc( + struct cudaChannelFormatDesc *desc, cudaArray_const_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + cudaArray_const_t); + static auto func_ptr = LoadSymbol("cudaGetChannelDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, array); +} + +extern __host__ struct cudaChannelFormatDesc CUDARTAPI cudaCreateChannelDesc( + int x, int y, int z, int w, enum cudaChannelFormatKind f) { + using FuncPtr = struct cudaChannelFormatDesc(CUDARTAPI *)( + int, int, int, int, enum cudaChannelFormatKind); + static auto func_ptr = LoadSymbol("cudaCreateChannelDesc"); + return func_ptr(x, y, z, w, f); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateTextureObject( + cudaTextureObject_t *pTexObject, const struct cudaResourceDesc *pResDesc, + const struct cudaTextureDesc *pTexDesc, + const struct cudaResourceViewDesc *pResViewDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaTextureObject_t *, const struct cudaResourceDesc *, + const struct cudaTextureDesc *, const struct cudaResourceViewDesc *); + static auto func_ptr = LoadSymbol("cudaCreateTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexObject, pResDesc, pTexDesc, pResViewDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyTextureObject(cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaDestroyTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectTextureDesc( + struct cudaTextureDesc *pTexDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaTextureDesc *, cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaGetTextureObjectTextureDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceViewDesc( + struct cudaResourceViewDesc *pResViewDesc, cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaResourceViewDesc *, + cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceViewDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResViewDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateSurfaceObject( + cudaSurfaceObject_t *pSurfObject, const struct cudaResourceDesc *pResDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t *, + const struct cudaResourceDesc *); + static auto func_ptr = LoadSymbol("cudaCreateSurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pSurfObject, pResDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroySurfaceObject(cudaSurfaceObject_t surfObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t); + static auto func_ptr = LoadSymbol("cudaDestroySurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaSurfaceObject_t surfObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaSurfaceObject_t); + static auto func_ptr = + LoadSymbol("cudaGetSurfaceObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaDriverGetVersion(int *driverVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaDriverGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(driverVersion); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaRuntimeGetVersion(int *runtimeVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaRuntimeGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(runtimeVersion); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphCreate(cudaGraph_t *pGraph, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraph, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddKernelNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddKernelNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeGetParams( + cudaGraphNode_t node, struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeSetParams( + cudaGraphNode_t node, const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphKernelNodeCopyAttributes(cudaGraphNode_t hSrc, cudaGraphNode_t hDst) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t); + static auto func_ptr = + LoadSymbol("cudaGraphKernelNodeCopyAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hSrc, hDst); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeGetAttribute( + cudaGraphNode_t hNode, enum cudaKernelNodeAttrID attr, + union cudaKernelNodeAttrValue *value_out) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, enum cudaKernelNodeAttrID, + union cudaKernelNodeAttrValue *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hNode, attr, value_out); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphKernelNodeSetAttribute( + cudaGraphNode_t hNode, enum cudaKernelNodeAttrID attr, + const union cudaKernelNodeAttrValue *value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, enum cudaKernelNodeAttrID, + const union cudaKernelNodeAttrValue *); + static auto func_ptr = LoadSymbol("cudaGraphKernelNodeSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hNode, attr, value); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemcpyNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemcpy3DParms *pCopyParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemcpyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pCopyParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeGetParams( + cudaGraphNode_t node, struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemcpyNodeSetParams( + cudaGraphNode_t node, const struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaGraphMemcpyNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddMemsetNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaMemsetParams *pMemsetParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddMemsetNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pMemsetParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeGetParams( + cudaGraphNode_t node, struct cudaMemsetParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphMemsetNodeSetParams( + cudaGraphNode_t node, const struct cudaMemsetParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaMemsetParams *); + static auto func_ptr = LoadSymbol("cudaGraphMemsetNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddHostNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies, + const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphAddHostNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeGetParams( + cudaGraphNode_t node, struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeGetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphHostNodeSetParams( + cudaGraphNode_t node, const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphHostNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddChildGraphNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, + size_t numDependencies, cudaGraph_t childGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphAddChildGraphNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, + childGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphChildGraphNodeGetGraph(cudaGraphNode_t node, cudaGraph_t *pGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraph_t *); + static auto func_ptr = LoadSymbol("cudaGraphChildGraphNodeGetGraph"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pGraph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphAddEmptyNode( + cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddEmptyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphClone(cudaGraph_t *pGraphClone, cudaGraph_t originalGraph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t *, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphClone, originalGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeFindInClone(cudaGraphNode_t *pNode, cudaGraphNode_t originalNode, + cudaGraph_t clonedGraph) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraphNode_t, cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphNodeFindInClone"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pNode, originalNode, clonedGraph); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphNodeGetType(cudaGraphNode_t node, enum cudaGraphNodeType *pType) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, enum cudaGraphNodeType *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetType"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pType); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetNodes(cudaGraph_t graph, + cudaGraphNode_t *nodes, + size_t *numNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, nodes, numNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetRootNodes( + cudaGraph_t graph, cudaGraphNode_t *pRootNodes, size_t *pNumRootNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetRootNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, pRootNodes, pNumRootNodes); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphGetEdges(cudaGraph_t graph, + cudaGraphNode_t *from, + cudaGraphNode_t *to, + size_t *numEdges) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaGraphNode_t *, + cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphGetEdges"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numEdges); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependencies( + cudaGraphNode_t node, cudaGraphNode_t *pDependencies, + size_t *pNumDependencies) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependencies, pNumDependencies); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphNodeGetDependentNodes( + cudaGraphNode_t node, cudaGraphNode_t *pDependentNodes, + size_t *pNumDependentNodes) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t, cudaGraphNode_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaGraphNodeGetDependentNodes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node, pDependentNodes, pNumDependentNodes); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddDependencies(cudaGraph_t graph, const cudaGraphNode_t *from, + const cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, const cudaGraphNode_t *, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphAddDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphRemoveDependencies(cudaGraph_t graph, const cudaGraphNode_t *from, + const cudaGraphNode_t *to, size_t numDependencies) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, const cudaGraphNode_t *, + const cudaGraphNode_t *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphRemoveDependencies"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, from, to, numDependencies); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphDestroyNode(cudaGraphNode_t node) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphNode_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroyNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(node); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphInstantiate( + cudaGraphExec_t *pGraphExec, cudaGraph_t graph, cudaGraphNode_t *pErrorNode, + char *pLogBuffer, size_t bufferSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t *, cudaGraph_t, + cudaGraphNode_t *, char *, size_t); + static auto func_ptr = LoadSymbol("cudaGraphInstantiate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphExec, graph, pErrorNode, pLogBuffer, bufferSize); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecKernelNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaKernelNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaKernelNodeParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExecKernelNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecMemcpyNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaMemcpy3DParms *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaMemcpy3DParms *); + static auto func_ptr = + LoadSymbol("cudaGraphExecMemcpyNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphExecMemsetNodeSetParams( + cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaMemsetParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaMemsetParams *); + static auto func_ptr = + LoadSymbol("cudaGraphExecMemsetNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecHostNodeSetParams(cudaGraphExec_t hGraphExec, cudaGraphNode_t node, + const struct cudaHostNodeParams *pNodeParams) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraphNode_t, + const struct cudaHostNodeParams *); + static auto func_ptr = LoadSymbol("cudaGraphExecHostNodeSetParams"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, node, pNodeParams); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecUpdate(cudaGraphExec_t hGraphExec, cudaGraph_t hGraph, + cudaGraphNode_t *hErrorNode_out, + enum cudaGraphExecUpdateResult *updateResult_out) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaGraph_t, cudaGraphNode_t *, + enum cudaGraphExecUpdateResult *); + static auto func_ptr = LoadSymbol("cudaGraphExecUpdate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hGraphExec, hGraph, hErrorNode_out, updateResult_out); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphLaunch(cudaGraphExec_t graphExec, + cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphLaunch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphExecDestroy(cudaGraphExec_t graphExec) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphExec_t); + static auto func_ptr = LoadSymbol("cudaGraphExecDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graphExec); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphDestroy(cudaGraph_t graph) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t); + static auto func_ptr = LoadSymbol("cudaGraphDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetExportTable( + const void **ppExportTable, const cudaUUID_t *pExportTableId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void **, const cudaUUID_t *); + static auto func_ptr = LoadSymbol("cudaGetExportTable"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ppExportTable, pExportTableId); +} + +extern __host__ cudaError_t CUDARTAPI_CDECL +cudaGetFuncBySymbol(cudaFunction_t *functionPtr, const void *symbolPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaFunction_t *, const void *); + static auto func_ptr = LoadSymbol("_CDECL cudaGetFuncBySymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(functionPtr, symbolPtr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddEventRecordNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, + size_t numDependencies, cudaEvent_t event) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaGraphAddEventRecordNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphAddEventWaitNode(cudaGraphNode_t *pGraphNode, cudaGraph_t graph, + const cudaGraphNode_t *pDependencies, + size_t numDependencies, cudaEvent_t event) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphNode_t *, cudaGraph_t, + const cudaGraphNode_t *, size_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaGraphAddEventWaitNode"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pGraphNode, graph, pDependencies, numDependencies, event); +} + +#if CUDA_VERSION >= 11030 + +extern __host__ cudaError_t CUDARTAPI cudaUserObjectCreate( + cudaUserObject_t *object_out, void *ptr, cudaHostFn_t destroy, + unsigned int initialRefcount, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaUserObject_t *, void *, cudaHostFn_t, unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaUserObjectCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(object_out, ptr, destroy, initialRefcount, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaUserObjectRetain(cudaUserObject_t object, unsigned int count __dv(1)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaUserObject_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaUserObjectRetain"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(object, count); +} + +extern __host__ cudaError_t CUDARTAPI +cudaUserObjectRelease(cudaUserObject_t object, unsigned int count __dv(1)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaUserObject_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaUserObjectRelease"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(object, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphRetainUserObject( + cudaGraph_t graph, cudaUserObject_t object, unsigned int count __dv(1), + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaUserObject_t, + unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphRetainUserObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, object, count, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphReleaseUserObject( + cudaGraph_t graph, cudaUserObject_t object, unsigned int count __dv(1)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraph_t, cudaUserObject_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphReleaseUserObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(graph, object, count); +} + +#endif // CUDA_VERSION >= 11030 + +extern __host__ cudaError_t CUDARTAPI cudaGetDriverEntryPoint( + const char *symbol, void **funcPtr, unsigned long long flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const char *, void **, unsigned long long); + static auto func_ptr = LoadSymbol("cudaGetDriverEntryPoint"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, funcPtr, flags); +} + +} // extern "C" diff --git a/source/lib/src/cuda/cudart/cuda_runtime_9_0.inc b/source/lib/src/cuda/cudart/cuda_runtime_9_0.inc new file mode 100644 index 0000000000..6753ddcf78 --- /dev/null +++ b/source/lib/src/cuda/cudart/cuda_runtime_9_0.inc @@ -0,0 +1,1421 @@ +// Auto-generated, do not edit. + +extern "C" { + +extern __host__ cudaError_t CUDARTAPI cudaDeviceReset(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceReset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaDeviceSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceSetLimit(enum cudaLimit limit, + size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaDeviceSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetLimit(size_t *pValue, enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaDeviceGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaDeviceGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetStreamPriorityRange(int *leastPriority, int *greatestPriority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int *); + static auto func_ptr = + LoadSymbol("cudaDeviceGetStreamPriorityRange"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(leastPriority, greatestPriority); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaDeviceSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetSharedMemConfig(enum cudaSharedMemConfig *pConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig *); + static auto func_ptr = LoadSymbol("cudaDeviceGetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceSetSharedMemConfig(enum cudaSharedMemConfig config) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaDeviceSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(config); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceGetByPCIBusId(int *device, const char *pciBusId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const char *); + static auto func_ptr = LoadSymbol("cudaDeviceGetByPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, pciBusId); +} + +extern __host__ cudaError_t CUDARTAPI cudaDeviceGetPCIBusId(char *pciBusId, + int len, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(char *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetPCIBusId"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pciBusId, len, device); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetEventHandle(cudaIpcEventHandle_t *handle, cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcEventHandle_t *, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaIpcGetEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, event); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcOpenEventHandle(cudaEvent_t *event, cudaIpcEventHandle_t handle) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, cudaIpcEventHandle_t); + static auto func_ptr = LoadSymbol("cudaIpcOpenEventHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, handle); +} + +extern __host__ cudaError_t CUDARTAPI +cudaIpcGetMemHandle(cudaIpcMemHandle_t *handle, void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaIpcMemHandle_t *, void *); + static auto func_ptr = LoadSymbol("cudaIpcGetMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(handle, devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcOpenMemHandle( + void **devPtr, cudaIpcMemHandle_t handle, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, cudaIpcMemHandle_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaIpcOpenMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, handle, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaIpcCloseMemHandle(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaIpcCloseMemHandle"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaThreadExit(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadExit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ cudaError_t CUDARTAPI cudaThreadSynchronize(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaThreadSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ cudaError_t CUDARTAPI cudaThreadSetLimit(enum cudaLimit limit, + size_t value) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaLimit, size_t); + static auto func_ptr = LoadSymbol("cudaThreadSetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(limit, value); +} + +extern __host__ cudaError_t CUDARTAPI cudaThreadGetLimit(size_t *pValue, + enum cudaLimit limit) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, enum cudaLimit); + static auto func_ptr = LoadSymbol("cudaThreadGetLimit"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pValue, limit); +} + +extern __host__ cudaError_t CUDARTAPI +cudaThreadGetCacheConfig(enum cudaFuncCache *pCacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache *); + static auto func_ptr = LoadSymbol("cudaThreadGetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pCacheConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaThreadSetCacheConfig(enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaThreadSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(cacheConfig); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaGetLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaPeekAtLastError(void) { + using FuncPtr = cudaError_t(CUDARTAPI *)(); + static auto func_ptr = LoadSymbol("cudaPeekAtLastError"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorName(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorName"); + if (!func_ptr) return "cudaGetErrorName symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ const char *CUDARTAPI +cudaGetErrorString(cudaError_t error) { + using FuncPtr = const char *(CUDARTAPI *)(cudaError_t); + static auto func_ptr = LoadSymbol("cudaGetErrorString"); + if (!func_ptr) return "cudaGetErrorString symbol not found."; + return func_ptr(error); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceCount(int *count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceCount"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDeviceProperties(struct cudaDeviceProp *prop, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaDeviceProp *, int); + static auto func_ptr = LoadSymbol("cudaGetDeviceProperties"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(prop, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetAttribute(int *value, enum cudaDeviceAttr attr, int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceAttr, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaDeviceGetP2PAttribute(int *value, enum cudaDeviceP2PAttr attr, + int srcDevice, int dstDevice) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, enum cudaDeviceP2PAttr, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceGetP2PAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(value, attr, srcDevice, dstDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaChooseDevice(int *device, const struct cudaDeviceProp *prop) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const struct cudaDeviceProp *); + static auto func_ptr = LoadSymbol("cudaChooseDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device, prop); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDevice(int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaSetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaGetDevice(int *device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaGetDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetValidDevices(int *device_arr, + int len) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int); + static auto func_ptr = LoadSymbol("cudaSetValidDevices"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(device_arr, len); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDeviceFlags(unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int); + static auto func_ptr = LoadSymbol("cudaSetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetDeviceFlags(unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *); + static auto func_ptr = LoadSymbol("cudaGetDeviceFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamCreate(cudaStream_t *pStream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *); + static auto func_ptr = LoadSymbol("cudaStreamCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithFlags(cudaStream_t *pStream, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamCreateWithPriority(cudaStream_t *pStream, unsigned int flags, + int priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t *, unsigned int, int); + static auto func_ptr = LoadSymbol("cudaStreamCreateWithPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pStream, flags, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetPriority(cudaStream_t hStream, int *priority) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, int *); + static auto func_ptr = LoadSymbol("cudaStreamGetPriority"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, priority); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamGetFlags(cudaStream_t hStream, unsigned int *flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, unsigned int *); + static auto func_ptr = LoadSymbol("cudaStreamGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(hStream, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamDestroy(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaStreamWaitEvent( + cudaStream_t stream, cudaEvent_t event, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, cudaEvent_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamWaitEvent"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, event, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamAddCallback(cudaStream_t stream, cudaStreamCallback_t callback, + void *userData, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t, cudaStreamCallback_t, + void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAddCallback"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, callback, userData, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaStreamSynchronize(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaStreamQuery(cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaStream_t); + static auto func_ptr = LoadSymbol("cudaStreamQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaStreamAttachMemAsync(cudaStream_t stream, void *devPtr, + size_t length __dv(0), + unsigned int flags __dv(cudaMemAttachSingle)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaStream_t, void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaStreamAttachMemAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(stream, devPtr, length, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventCreate(cudaEvent_t *event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *); + static auto func_ptr = LoadSymbol("cudaEventCreate"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventCreateWithFlags(cudaEvent_t *event, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t *, unsigned int); + static auto func_ptr = LoadSymbol("cudaEventCreateWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventRecord(cudaEvent_t event, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaEventRecord"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventQuery(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventQuery"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventSynchronize(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventSynchronize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaEventDestroy(cudaEvent_t event) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventDestroy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(event); +} + +extern __host__ cudaError_t CUDARTAPI cudaEventElapsedTime(float *ms, + cudaEvent_t start, + cudaEvent_t end) { + using FuncPtr = cudaError_t(CUDARTAPI *)(float *, cudaEvent_t, cudaEvent_t); + static auto func_ptr = LoadSymbol("cudaEventElapsedTime"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ms, start, end); +} + +extern __host__ cudaError_t CUDARTAPI +cudaLaunchKernel(const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernel( + const void *func, dim3 gridDim, dim3 blockDim, void **args, + size_t sharedMem, cudaStream_t stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, dim3, dim3, void **, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaLaunchCooperativeKernel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, gridDim, blockDim, args, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunchCooperativeKernelMultiDevice( + struct cudaLaunchParams *launchParamsList, unsigned int numDevices, + unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaLaunchParams *, + unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaLaunchCooperativeKernelMultiDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(launchParamsList, numDevices, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetCacheConfig(const void *func, enum cudaFuncCache cacheConfig) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncCache); + static auto func_ptr = LoadSymbol("cudaFuncSetCacheConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, cacheConfig); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFuncSetSharedMemConfig(const void *func, enum cudaSharedMemConfig config) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaSharedMemConfig); + static auto func_ptr = LoadSymbol("cudaFuncSetSharedMemConfig"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, config); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncGetAttributes(struct cudaFuncAttributes *attr, const void *func) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaFuncAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaFuncGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attr, func); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFuncSetAttribute(const void *func, enum cudaFuncAttribute attr, int value) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, enum cudaFuncAttribute, int); + static auto func_ptr = LoadSymbol("cudaFuncSetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func, attr, value); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDoubleForDevice(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForDevice"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetDoubleForHost(double *d) { + using FuncPtr = cudaError_t(CUDARTAPI *)(double *); + static auto func_ptr = LoadSymbol("cudaSetDoubleForHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(d); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessor(int *numBlocks, const void *func, + int blockSize, + size_t dynamicSMemSize) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t); + static auto func_ptr = + LoadSymbol("cudaOccupancyMaxActiveBlocksPerMultiprocessor"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(int *numBlocks, + const void *func, + int blockSize, + size_t dynamicSMemSize, + unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int *, const void *, int, size_t, unsigned int); + static auto func_ptr = LoadSymbol( + "cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(numBlocks, func, blockSize, dynamicSMemSize, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaConfigureCall(dim3 gridDim, dim3 blockDim, size_t sharedMem __dv(0), + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(dim3, dim3, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaConfigureCall"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(gridDim, blockDim, sharedMem, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaSetupArgument(const void *arg, + size_t size, + size_t offset) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaSetupArgument"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(arg, size, offset); +} + +extern __host__ cudaError_t CUDARTAPI cudaLaunch(const void *func) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *); + static auto func_ptr = LoadSymbol("cudaLaunch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(func); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMallocManaged( + void **devPtr, size_t size, unsigned int flags __dv(cudaMemAttachGlobal)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocManaged"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMalloc(void **devPtr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMalloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocHost(void **ptr, size_t size) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t); + static auto func_ptr = LoadSymbol("cudaMallocHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocPitch(void **devPtr, + size_t *pitch, + size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t *, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMallocPitch"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocArray( + cudaArray_t *array, const struct cudaChannelFormatDesc *desc, size_t width, + size_t height __dv(0), unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + size_t, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, width, height, flags); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaFree(void *devPtr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFree"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeHost(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaFreeHost"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI cudaFreeArray(cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t); + static auto func_ptr = LoadSymbol("cudaFreeArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array); +} + +extern __host__ cudaError_t CUDARTAPI +cudaFreeMipmappedArray(cudaMipmappedArray_t mipmappedArray) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t); + static auto func_ptr = LoadSymbol("cudaFreeMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostAlloc(void **pHost, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostAlloc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pHost, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostRegister(void *ptr, size_t size, + unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostRegister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr, size, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostUnregister(void *ptr) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *); + static auto func_ptr = LoadSymbol("cudaHostUnregister"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, void *, unsigned int); + static auto func_ptr = LoadSymbol("cudaHostGetDevicePointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pDevice, pHost, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaHostGetFlags(unsigned int *pFlags, + void *pHost) { + using FuncPtr = cudaError_t(CUDARTAPI *)(unsigned int *, void *); + static auto func_ptr = LoadSymbol("cudaHostGetFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pFlags, pHost); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3D(struct cudaPitchedPtr *pitchedDevPtr, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr *, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMalloc3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, extent); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMalloc3DArray(cudaArray_t *array, const struct cudaChannelFormatDesc *desc, + struct cudaExtent extent, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t *, + const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int); + static auto func_ptr = LoadSymbol("cudaMalloc3DArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, desc, extent, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaMallocMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, + const struct cudaChannelFormatDesc *desc, struct cudaExtent extent, + unsigned int numLevels, unsigned int flags __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaMipmappedArray_t *, const struct cudaChannelFormatDesc *, + struct cudaExtent, unsigned int, unsigned int); + static auto func_ptr = LoadSymbol("cudaMallocMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, desc, extent, numLevels, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetMipmappedArrayLevel( + cudaArray_t *levelArray, cudaMipmappedArray_const_t mipmappedArray, + unsigned int level) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaMipmappedArray_const_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGetMipmappedArrayLevel"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(levelArray, mipmappedArray, level); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3D(const struct cudaMemcpy3DParms *p) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpy3DPeer(const struct cudaMemcpy3DPeerParms *p) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy3DAsync( + const struct cudaMemcpy3DParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DParms *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy3DPeerAsync( + const struct cudaMemcpy3DPeerParms *p, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct cudaMemcpy3DPeerParms *, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy3DPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(p, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemGetInfo(size_t *free, + size_t *total) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, size_t *); + static auto func_ptr = LoadSymbol("cudaMemGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(free, total); +} + +extern __host__ cudaError_t CUDARTAPI +cudaArrayGetInfo(struct cudaChannelFormatDesc *desc, struct cudaExtent *extent, + unsigned int *flags, cudaArray_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + struct cudaExtent *, unsigned int *, + cudaArray_t); + static auto func_ptr = LoadSymbol("cudaArrayGetInfo"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, extent, flags, array); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy(void *dst, const void *src, + size_t count, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyPeer(void *dst, int dstDevice, + const void *src, + int srcDevice, + size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, int, const void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, + const void *src, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t, size_t, size_t, const void *, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyFromArray(void *dst, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t count, enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t count, + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, cudaArray_const_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + count, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2D(void *dst, size_t dpitch, + const void *src, + size_t spitch, size_t width, + size_t height, + enum cudaMemcpyKind kind) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArray( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArray( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, size_t, + size_t, size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DArrayToArray( + cudaArray_t dst, size_t wOffsetDst, size_t hOffsetDst, + cudaArray_const_t src, size_t wOffsetSrc, size_t hOffsetSrc, size_t width, + size_t height, enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + cudaArray_const_t, size_t, size_t, + size_t, size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpy2DArrayToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffsetDst, hOffsetDst, src, wOffsetSrc, hOffsetSrc, + width, height, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbol( + const void *symbol, const void *src, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyHostToDevice)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, + size_t, enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbol( + void *dst, const void *symbol, size_t count, size_t offset __dv(0), + enum cudaMemcpyKind kind __dv(cudaMemcpyDeviceToHost)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbol"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemcpyAsync(void *dst, const void *src, size_t count, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemcpyPeerAsync(void *dst, int dstDevice, const void *src, int srcDevice, + size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, const void *, int, + size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyPeerAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dstDevice, src, srcDevice, count, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t count, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, const void *, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, count, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromArrayAsync( + void *dst, cudaArray_const_t src, size_t wOffset, size_t hOffset, + size_t count, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, cudaArray_const_t, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, src, wOffset, hOffset, count, kind, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemcpy2DAsync( + void *dst, size_t dpitch, const void *src, size_t spitch, size_t width, + size_t height, enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void *, size_t, const void *, size_t, size_t, + size_t, enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, spitch, width, height, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DToArrayAsync( + cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, + size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaArray_t, size_t, size_t, + const void *, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DToArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, wOffset, hOffset, src, spitch, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpy2DFromArrayAsync( + void *dst, size_t dpitch, cudaArray_const_t src, size_t wOffset, + size_t hOffset, size_t width, size_t height, enum cudaMemcpyKind kind, + cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, cudaArray_const_t, + size_t, size_t, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpy2DFromArrayAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, dpitch, src, wOffset, hOffset, width, height, kind, + stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyToSymbolAsync( + const void *symbol, const void *src, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyToSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(symbol, src, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemcpyFromSymbolAsync( + void *dst, const void *symbol, size_t count, size_t offset, + enum cudaMemcpyKind kind, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, const void *, size_t, size_t, + enum cudaMemcpyKind, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemcpyFromSymbolAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(dst, symbol, count, offset, kind, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset(void *devPtr, int value, + size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t); + static auto func_ptr = LoadSymbol("cudaMemset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset2D(void *devPtr, size_t pitch, + int value, size_t width, + size_t height) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaMemset2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemset3D( + struct cudaPitchedPtr pitchedDevPtr, int value, struct cudaExtent extent) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, struct cudaExtent); + static auto func_ptr = LoadSymbol("cudaMemset3D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI cudaMemsetAsync( + void *devPtr, int value, size_t count, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, int, size_t, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemsetAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, value, count, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset2DAsync(void *devPtr, size_t pitch, int value, size_t width, + size_t height, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void *, size_t, int, size_t, size_t, + cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset2DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, pitch, value, width, height, stream); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaMemset3DAsync(struct cudaPitchedPtr pitchedDevPtr, int value, + struct cudaExtent extent, cudaStream_t stream __dv(0)) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaPitchedPtr, int, + struct cudaExtent, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemset3DAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pitchedDevPtr, value, extent, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolAddress(void **devPtr, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(void **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolAddress"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSymbolSize(size_t *size, + const void *symbol) { + using FuncPtr = cudaError_t(CUDARTAPI *)(size_t *, const void *); + static auto func_ptr = LoadSymbol("cudaGetSymbolSize"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(size, symbol); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemPrefetchAsync(const void *devPtr, size_t count, int dstDevice, + cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const void *, size_t, int, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaMemPrefetchAsync"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, dstDevice, stream); +} + +extern __host__ cudaError_t CUDARTAPI +cudaMemAdvise(const void *devPtr, size_t count, enum cudaMemoryAdvise advice, + int device) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void *, size_t, + enum cudaMemoryAdvise, int); + static auto func_ptr = LoadSymbol("cudaMemAdvise"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, count, advice, device); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttribute( + void *data, size_t dataSize, enum cudaMemRangeAttribute attribute, + const void *devPtr, size_t count) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + void *, size_t, enum cudaMemRangeAttribute, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttribute"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSize, attribute, devPtr, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaMemRangeGetAttributes( + void **data, size_t *dataSizes, enum cudaMemRangeAttribute *attributes, + size_t numAttributes, const void *devPtr, size_t count) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, enum cudaMemRangeAttribute *, + size_t, const void *, size_t); + static auto func_ptr = LoadSymbol("cudaMemRangeGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(data, dataSizes, attributes, numAttributes, devPtr, count); +} + +extern __host__ cudaError_t CUDARTAPI cudaPointerGetAttributes( + struct cudaPointerAttributes *attributes, const void *ptr) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaPointerAttributes *, const void *); + static auto func_ptr = LoadSymbol("cudaPointerGetAttributes"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(attributes, ptr); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceCanAccessPeer(int *canAccessPeer, int device, int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *, int, int); + static auto func_ptr = LoadSymbol("cudaDeviceCanAccessPeer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(canAccessPeer, device, peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceEnablePeerAccess(int peerDevice, unsigned int flags) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int, unsigned int); + static auto func_ptr = LoadSymbol("cudaDeviceEnablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice, flags); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDeviceDisablePeerAccess(int peerDevice) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int); + static auto func_ptr = LoadSymbol("cudaDeviceDisablePeerAccess"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(peerDevice); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsUnregisterResource(cudaGraphicsResource_t resource) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnregisterResource"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceSetMapFlags( + cudaGraphicsResource_t resource, unsigned int flags) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaGraphicsResource_t, unsigned int); + static auto func_ptr = LoadSymbol("cudaGraphicsResourceSetMapFlags"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(resource, flags); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsMapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsMapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsUnmapResources( + int count, cudaGraphicsResource_t *resources, cudaStream_t stream __dv(0)) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(int, cudaGraphicsResource_t *, cudaStream_t); + static auto func_ptr = LoadSymbol("cudaGraphicsUnmapResources"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(count, resources, stream); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsResourceGetMappedPointer( + void **devPtr, size_t *size, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(void **, size_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedPointer"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(devPtr, size, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGraphicsSubResourceGetMappedArray( + cudaArray_t *array, cudaGraphicsResource_t resource, + unsigned int arrayIndex, unsigned int mipLevel) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaArray_t *, cudaGraphicsResource_t, unsigned int, unsigned int); + static auto func_ptr = + LoadSymbol("cudaGraphicsSubResourceGetMappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(array, resource, arrayIndex, mipLevel); +} + +extern __host__ cudaError_t CUDARTAPI +cudaGraphicsResourceGetMappedMipmappedArray( + cudaMipmappedArray_t *mipmappedArray, cudaGraphicsResource_t resource) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(cudaMipmappedArray_t *, cudaGraphicsResource_t); + static auto func_ptr = + LoadSymbol("cudaGraphicsResourceGetMappedMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(mipmappedArray, resource); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetChannelDesc( + struct cudaChannelFormatDesc *desc, cudaArray_const_t array) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaChannelFormatDesc *, + cudaArray_const_t); + static auto func_ptr = LoadSymbol("cudaGetChannelDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(desc, array); +} + +extern __host__ struct cudaChannelFormatDesc CUDARTAPI cudaCreateChannelDesc( + int x, int y, int z, int w, enum cudaChannelFormatKind f) { + using FuncPtr = struct cudaChannelFormatDesc(CUDARTAPI *)( + int, int, int, int, enum cudaChannelFormatKind); + static auto func_ptr = LoadSymbol("cudaCreateChannelDesc"); + if (!func_ptr) { + return cudaChannelFormatDesc{cudaChannelFormatKind(-1), 0, 0, 0}; + } + return func_ptr(x, y, z, w, f); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindTexture( + size_t *offset, const struct textureReference *texref, const void *devPtr, + const struct cudaChannelFormatDesc *desc, size_t size __dv(UINT_MAX)) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, size); +} + +extern __host__ cudaError_t CUDARTAPI +cudaBindTexture2D(size_t *offset, const struct textureReference *texref, + const void *devPtr, const struct cudaChannelFormatDesc *desc, + size_t width, size_t height, size_t pitch) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + size_t *, const struct textureReference *, const void *, + const struct cudaChannelFormatDesc *, size_t, size_t, size_t); + static auto func_ptr = LoadSymbol("cudaBindTexture2D"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref, devPtr, desc, width, height, pitch); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindTextureToArray( + const struct textureReference *texref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, array, desc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaBindTextureToMipmappedArray(const struct textureReference *texref, + cudaMipmappedArray_const_t mipmappedArray, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct textureReference *, cudaMipmappedArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindTextureToMipmappedArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, mipmappedArray, desc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaUnbindTexture(const struct textureReference *texref) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaUnbindTexture"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureAlignmentOffset( + size_t *offset, const struct textureReference *texref) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(size_t *, const struct textureReference *); + static auto func_ptr = LoadSymbol("cudaGetTextureAlignmentOffset"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(offset, texref); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureReference( + const struct textureReference **texref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct textureReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetTextureReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaBindSurfaceToArray( + const struct surfaceReference *surfref, cudaArray_const_t array, + const struct cudaChannelFormatDesc *desc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + const struct surfaceReference *, cudaArray_const_t, + const struct cudaChannelFormatDesc *); + static auto func_ptr = LoadSymbol("cudaBindSurfaceToArray"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, array, desc); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceReference( + const struct surfaceReference **surfref, const void *symbol) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(const struct surfaceReference **, const void *); + static auto func_ptr = LoadSymbol("cudaGetSurfaceReference"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfref, symbol); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateTextureObject( + cudaTextureObject_t *pTexObject, const struct cudaResourceDesc *pResDesc, + const struct cudaTextureDesc *pTexDesc, + const struct cudaResourceViewDesc *pResViewDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)( + cudaTextureObject_t *, const struct cudaResourceDesc *, + const struct cudaTextureDesc *, const struct cudaResourceViewDesc *); + static auto func_ptr = LoadSymbol("cudaCreateTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexObject, pResDesc, pTexDesc, pResViewDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroyTextureObject(cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaDestroyTextureObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectTextureDesc( + struct cudaTextureDesc *pTexDesc, cudaTextureObject_t texObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaTextureDesc *, cudaTextureObject_t); + static auto func_ptr = LoadSymbol("cudaGetTextureObjectTextureDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pTexDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetTextureObjectResourceViewDesc( + struct cudaResourceViewDesc *pResViewDesc, cudaTextureObject_t texObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(struct cudaResourceViewDesc *, + cudaTextureObject_t); + static auto func_ptr = + LoadSymbol("cudaGetTextureObjectResourceViewDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResViewDesc, texObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaCreateSurfaceObject( + cudaSurfaceObject_t *pSurfObject, const struct cudaResourceDesc *pResDesc) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t *, + const struct cudaResourceDesc *); + static auto func_ptr = LoadSymbol("cudaCreateSurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pSurfObject, pResDesc); +} + +extern __host__ cudaError_t CUDARTAPI +cudaDestroySurfaceObject(cudaSurfaceObject_t surfObject) { + using FuncPtr = cudaError_t(CUDARTAPI *)(cudaSurfaceObject_t); + static auto func_ptr = LoadSymbol("cudaDestroySurfaceObject"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetSurfaceObjectResourceDesc( + struct cudaResourceDesc *pResDesc, cudaSurfaceObject_t surfObject) { + using FuncPtr = + cudaError_t(CUDARTAPI *)(struct cudaResourceDesc *, cudaSurfaceObject_t); + static auto func_ptr = + LoadSymbol("cudaGetSurfaceObjectResourceDesc"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(pResDesc, surfObject); +} + +extern __host__ cudaError_t CUDARTAPI cudaDriverGetVersion(int *driverVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaDriverGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(driverVersion); +} + +extern __host__ __cudart_builtin__ cudaError_t CUDARTAPI +cudaRuntimeGetVersion(int *runtimeVersion) { + using FuncPtr = cudaError_t(CUDARTAPI *)(int *); + static auto func_ptr = LoadSymbol("cudaRuntimeGetVersion"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(runtimeVersion); +} + +extern __host__ cudaError_t CUDARTAPI cudaGetExportTable( + const void **ppExportTable, const cudaUUID_t *pExportTableId) { + using FuncPtr = cudaError_t(CUDARTAPI *)(const void **, const cudaUUID_t *); + static auto func_ptr = LoadSymbol("cudaGetExportTable"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(ppExportTable, pExportTableId); +} + +} // extern "C" diff --git a/source/lib/src/cuda/cudart/cudart_stub.cc b/source/lib/src/cuda/cudart/cudart_stub.cc new file mode 100644 index 0000000000..815e342368 --- /dev/null +++ b/source/lib/src/cuda/cudart/cudart_stub.cc @@ -0,0 +1,163 @@ +/* + dynamically load CUDA runtime library +*/ +#include +#include +#include +#include +#include "cuda_runtime_api.h" + +// wraps cuda runtime with dso loader + +namespace { +void *GetDsoHandle() { + static auto handle = []() -> void * { +#if defined(__gnu_linux__) + std::string libname = "libcudart.so"; +#elif defined(__APPLE__) + std::string libname = "libcudart.dylib"; +#elif defined(_WIN32) + std::string libname = "cudart.dll"; +#endif +#if defined(_WIN32) + void* dso_handle = LoadLibrary(libname.c_str()); +#else + void* dso_handle = dlopen(libname.c_str(), RTLD_NOW | RTLD_LOCAL); +#endif + if (!dso_handle) { + std::cerr << "DeePMD-kit: Cannot find " << libname << std::endl; + return nullptr; + } + std::cerr << "DeePMD-kit: Successfully load " << libname << std::endl; + return dso_handle; + }(); + return handle; +} + +template +T LoadSymbol(const char *symbol_name) { + void *symbol = nullptr; + void *handle = GetDsoHandle(); + if (handle) { + symbol = dlsym(handle, symbol_name); + } + return reinterpret_cast(symbol); +} + +// the following is copied from TensorFlow +/* Copyright 2015 The TensorFlow Authors. All Rights Reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +cudaError_t GetSymbolNotFoundError() { + return cudaErrorSharedObjectSymbolNotFound; +} +} // namespace + +#define __dv(v) +#define __CUDA_DEPRECATED +// CUDART_VERSION is defined in cuda_runtime_api.h +#if CUDART_VERSION < 10000 +#include "cuda_runtime_9_0.inc" +#elif CUDART_VERSION < 10010 +#include "cuda_runtime_10_0.inc" +#elif CUDART_VERSION < 10020 +#include "cuda_runtime_10_1.inc" +#elif CUDART_VERSION < 11000 +#include "cuda_runtime_10_2.inc" +#elif CUDART_VERSION < 11020 +#include "cuda_runtime_11_0.inc" +#else +#include "cuda_runtime_11_2.inc" +#endif +#undef __dv +#undef __CUDA_DEPRECATED + +extern "C" { + +// Following are private symbols in libcudart that got inserted by nvcc. +extern void CUDARTAPI __cudaRegisterFunction( + void **fatCubinHandle, const char *hostFun, char *deviceFun, + const char *deviceName, int thread_limit, uint3 *tid, uint3 *bid, + dim3 *bDim, dim3 *gDim, int *wSize) { + using FuncPtr = void(CUDARTAPI *)(void **fatCubinHandle, const char *hostFun, + char *deviceFun, const char *deviceName, + int thread_limit, uint3 *tid, uint3 *bid, + dim3 *bDim, dim3 *gDim, int *wSize); + static auto func_ptr = LoadSymbol("__cudaRegisterFunction"); + if (!func_ptr) return; + func_ptr(fatCubinHandle, hostFun, deviceFun, deviceName, thread_limit, tid, + bid, bDim, gDim, wSize); +} + +extern void CUDARTAPI __cudaUnregisterFatBinary(void **fatCubinHandle) { + using FuncPtr = void(CUDARTAPI *)(void **fatCubinHandle); + static auto func_ptr = LoadSymbol("__cudaUnregisterFatBinary"); + if (!func_ptr) return; + func_ptr(fatCubinHandle); +} + +extern void CUDARTAPI __cudaRegisterVar(void **fatCubinHandle, char *hostVar, + char *deviceAddress, + const char *deviceName, int ext, + size_t size, int constant, int global) { + using FuncPtr = void(CUDARTAPI *)( + void **fatCubinHandle, char *hostVar, char *deviceAddress, + const char *deviceName, int ext, size_t size, int constant, int global); + static auto func_ptr = LoadSymbol("__cudaRegisterVar"); + if (!func_ptr) return; + func_ptr(fatCubinHandle, hostVar, deviceAddress, deviceName, ext, size, + constant, global); +} + +extern void **CUDARTAPI __cudaRegisterFatBinary(void *fatCubin) { + using FuncPtr = void **(CUDARTAPI *)(void *fatCubin); + static auto func_ptr = LoadSymbol("__cudaRegisterFatBinary"); + if (!func_ptr) return nullptr; + return (void **)func_ptr(fatCubin); +} + +extern cudaError_t CUDARTAPI __cudaPopCallConfiguration(dim3 *gridDim, + dim3 *blockDim, + size_t *sharedMem, + void *stream) { + using FuncPtr = cudaError_t(CUDARTAPI *)(dim3 * gridDim, dim3 * blockDim, + size_t * sharedMem, void *stream); + static auto func_ptr = LoadSymbol("__cudaPopCallConfiguration"); + if (!func_ptr) return GetSymbolNotFoundError(); + return func_ptr(gridDim, blockDim, sharedMem, stream); +} + +extern __host__ __device__ unsigned CUDARTAPI __cudaPushCallConfiguration( + dim3 gridDim, dim3 blockDim, size_t sharedMem = 0, void *stream = 0) { + using FuncPtr = unsigned(CUDARTAPI *)(dim3 gridDim, dim3 blockDim, + size_t sharedMem, void *stream); + static auto func_ptr = LoadSymbol("__cudaPushCallConfiguration"); + if (!func_ptr) return 0; + return func_ptr(gridDim, blockDim, sharedMem, stream); +} + +extern char CUDARTAPI __cudaInitModule(void **fatCubinHandle) { + using FuncPtr = char(CUDARTAPI *)(void **fatCubinHandle); + static auto func_ptr = LoadSymbol("__cudaInitModule"); + if (!func_ptr) return 0; + return func_ptr(fatCubinHandle); +} + +#if CUDART_VERSION >= 10010 +extern void CUDARTAPI __cudaRegisterFatBinaryEnd(void **fatCubinHandle) { + using FuncPtr = void(CUDARTAPI *)(void **fatCubinHandle); + static auto func_ptr = LoadSymbol("__cudaRegisterFatBinaryEnd"); + if (!func_ptr) return; + func_ptr(fatCubinHandle); +} +#endif +} \ No newline at end of file diff --git a/source/lib/src/region.cc b/source/lib/src/region.cc index d8333e4929..8ce37c0584 100644 --- a/source/lib/src/region.cc +++ b/source/lib/src/region.cc @@ -1,5 +1,6 @@ #include #include +#include #include "region.h" #include "errors.h" #define BOXT_DIM 9 @@ -33,9 +34,7 @@ compute_volume(const FPTYPE * boxt) boxt[0*3+0] * (boxt[1*3+1]*boxt[2*3+2] - boxt[2*3+1]*boxt[1*3+2]) - boxt[0*3+1] * (boxt[1*3+0]*boxt[2*3+2] - boxt[2*3+0]*boxt[1*3+2]) + boxt[0*3+2] * (boxt[1*3+0]*boxt[2*3+1] - boxt[2*3+0]*boxt[1*3+1]); - if (volume < 0) { - throw deepmd::deepmd_exception("Negative volume detected. Please make sure the simulation cell obeys the right-hand rule."); - } + volume = std::abs(volume); return volume; } diff --git a/source/lib/src/rocm/CMakeLists.txt b/source/lib/src/rocm/CMakeLists.txt index 602f2f4524..0a499e9160 100644 --- a/source/lib/src/rocm/CMakeLists.txt +++ b/source/lib/src/rocm/CMakeLists.txt @@ -1,27 +1,39 @@ # required cmake version -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.21) # project name project(deepmd_op_rocm) set(CMAKE_LINK_WHAT_YOU_USE TRUE) # set c++ version c++11 -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_HIP_STANDARD 11) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_HIP_STANDARD 14) add_definitions("-DCUB_IGNORE_DEPRECATED_CPP_DIALECT") add_definitions("-DCUB_IGNORE_DEPRECATED_CPP_DIALECT") message(STATUS "HIP major version is " ${HIP_VERSION_MAJOR}) -set (HIP_HIPCC_FLAGS -hc; -fno-gpu-rdc; --amdgpu-target=gfx906; -fPIC; -O3; --std=c++11) +set (HIP_HIPCC_FLAGS -fno-gpu-rdc; -fPIC --std=c++14 ${HIP_HIPCC_FLAGS}) # --amdgpu-target=gfx906 +if (HIP_VERSION VERSION_LESS 3.5.1) + set (HIP_HIPCC_FLAGS -hc; ${HIP_HIPCC_FLAGS}) +endif() file (GLOB SOURCE_FILES "*.hip.cu" ) hip_add_library(deepmd_op_rocm SHARED ${SOURCE_FILES}) -target_include_directories(deepmd_op_rocm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include/) +target_include_directories( + deepmd_op_rocm PUBLIC + $ + $ +) +target_precompile_headers(deepmd_op_rocm PUBLIC [["device.h"]]) install(TARGETS deepmd_op_rocm DESTINATION lib/) if (BUILD_CPP_IF) - install(TARGETS deepmd_op_rocm DESTINATION lib/) + install( + TARGETS deepmd_op_rocm + EXPORT ${CMAKE_PROJECT_NAME}Targets + DESTINATION lib/ + ) endif (BUILD_CPP_IF) if (BUILD_PY_IF) install(TARGETS deepmd_op_rocm DESTINATION deepmd/op/) diff --git a/source/lib/src/rocm/neighbor_list.hip.cu b/source/lib/src/rocm/neighbor_list.hip.cu index 3bdfbee770..64f2b31497 100644 --- a/source/lib/src/rocm/neighbor_list.hip.cu +++ b/source/lib/src/rocm/neighbor_list.hip.cu @@ -288,7 +288,7 @@ void use_nei_info_gpu_rocm( dim3 block_grid(nloc, nblock); dim3 thread_grid(1, TPB); DPErrcheck(hipMemset(ntype, 0, sizeof(int) * nloc * nnei)); - DPErrcheck(hipMemset(nmask, 0, sizeof(FPTYPE) * nloc * nnei)); + DPErrcheck(hipMemset(nmask, 0, sizeof(bool) * nloc * nnei)); if (b_nlist_map){ hipLaunchKernelGGL(map_nei_info, block_grid, thread_grid, 0, 0, nlist, ntype, nmask, type, nlist_map, nloc, nnei, ntypes); } @@ -301,4 +301,4 @@ void use_nei_info_gpu_rocm( template int build_nlist_gpu_rocm(InputNlist & nlist, int * max_list_size, int * nlist_data, const float * c_cpy, const int & nloc, const int & nall, const int & mem_size, const float & rcut); template int build_nlist_gpu_rocm(InputNlist & nlist, int * max_list_size, int * nlist_data, const double * c_cpy, const int & nloc, const int & nall, const int & mem_size, const float & rcut); -} \ No newline at end of file +} diff --git a/source/lib/tests/CMakeLists.txt b/source/lib/tests/CMakeLists.txt index bcee2c3fb2..975b0a1458 100644 --- a/source/lib/tests/CMakeLists.txt +++ b/source/lib/tests/CMakeLists.txt @@ -1,107 +1,17 @@ cmake_minimum_required(VERSION 3.9) project(libdeepmd_test) -enable_testing() - -find_package(OpenMP) -if (OPENMP_FOUND) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") -endif() - -set(libname "deepmd") -set(BUILD_CPP_IF TRUE) -set(LIB_DEEPMD ${libname}) -add_subdirectory(${CMAKE_SOURCE_DIR}/.. lib) - -message(status "${CMAKE_SOURCE_DIR}") - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - -# Devices that have both ROCM and CUDA are not currently supported -if (USE_ROCM_TOOLKIT AND USE_CUDA_TOOLKIT) - message (FATAL_ERROR "Devices that have both ROCM and CUDA are not currently supported") -endif() - -# define USE_CUDA_TOOLKIT -if (USE_CUDA_TOOLKIT) - find_package(CUDA REQUIRED) - add_definitions("-DGOOGLE_CUDA") - message(STATUS "Found CUDA in ${CUDA_TOOLKIT_ROOT_DIR}, build nv GPU support") -else() - message(STATUS "Will not build nv GPU support") -endif(USE_CUDA_TOOLKIT) - -#define USE_ROCM_TOOLKIT -if (USE_ROCM_TOOLKIT) - list (APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake/) - find_package(ROCM REQUIRED) - add_definitions("-DTENSORFLOW_USE_ROCM") - add_compile_definitions(__HIP_PLATFORM_HCC__) -else() - message(STATUS "Will not build AMD GPU support") -endif (USE_ROCM_TOOLKIT) - file(GLOB TEST_SRC test_*.cc) -add_executable( runUnitTests ${TEST_SRC} ) - -add_library(coverage_config INTERFACE) -target_compile_options(coverage_config INTERFACE - -O0 # no optimization - -g # generate debug info - --coverage # sets all required flags -) -if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13) - target_link_options(coverage_config INTERFACE --coverage) -else() - target_link_libraries(coverage_config INTERFACE --coverage) -endif() - -find_package(Threads) -# find openmp -find_package(OpenMP) -if (OPENMP_FOUND) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") -endif() +add_executable( runUnitTests_lib ${TEST_SRC} ) -target_link_libraries(runUnitTests gtest gtest_main ${libname} coverage_config) -add_test( runUnitTests runUnitTests ) +target_link_libraries(runUnitTests_lib GTest::gtest_main ${LIB_DEEPMD} coverage_config) +add_test( runUnitTests_lib runUnitTests_lib ) set_target_properties( - runUnitTests + runUnitTests_lib PROPERTIES INSTALL_RPATH "$ORIGIN/../lib" ) -# include(GoogleTest) -# add_executable(FooTest tests/test_simulation_region.cc) -# gtest_add_tests(TARGET FooTest -# TEST_SUFFIX .noArgs -# TEST_LIST noArgsTests -# ) - -find_package(GTest) -if(NOT GTEST_LIBRARIES) - configure_file(../../cmake/googletest.cmake.in googletest-download/CMakeLists.txt) - execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) - if(result) - message(FATAL_ERROR "CMake step for googletest failed: ${result}") - endif() - execute_process(COMMAND ${CMAKE_COMMAND} --build . - RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) - if(result) - message(FATAL_ERROR "Build step for googletest failed: ${result}") - endif() - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) - add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src ${CMAKE_CURRENT_BINARY_DIR}/googletest-build EXCLUDE_FROM_ALL) -else () - include_directories(${GTEST_INCLUDE_DIRS}) -endif () - -install(TARGETS runUnitTests DESTINATION bin/) - +install(TARGETS runUnitTests_lib DESTINATION bin/) diff --git a/source/lmp/CMakeLists.txt b/source/lmp/CMakeLists.txt index 0eb3799ebe..c0d2136847 100644 --- a/source/lmp/CMakeLists.txt +++ b/source/lmp/CMakeLists.txt @@ -1,9 +1,4 @@ add_subdirectory(plugin) -if (NOT DEFINED LAMMPS_VERSION_NUMBER) - # set the default to stable_23Jun2022_update1 - set(LAMMPS_VERSION_NUMBER 20220623) -endif() -message(STATUS "LAMMPS version is ${LAMMPS_VERSION_NUMBER}") file(GLOB LMP_HEADER *.h) file(GLOB LMP_SRC *.cpp) diff --git a/source/lmp/deepmd_fix_ttm.patch b/source/lmp/deepmd_fix_ttm.patch deleted file mode 100644 index 8ca19d388d..0000000000 --- a/source/lmp/deepmd_fix_ttm.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff '--color=auto' -Naur lammps-16Mar18/src/USER-MISC/fix_ttm_mod.h lammps-16Mar18.new/src/USER-MISC/fix_ttm_mod.h ---- lammps-16Mar18/src/USER-MISC/fix_ttm_mod.h 2017-06-22 21:57:19.000000000 +0800 -+++ lammps-16Mar18.new/src/USER-MISC/fix_ttm_mod.h 2019-10-16 09:58:38.228813486 +0800 -@@ -21,6 +21,7 @@ - #define LMP_FIX_TTM_MOD_H - - #include "fix.h" -+#include - - namespace LAMMPS_NS { - -@@ -51,6 +52,22 @@ - double memory_usage(); - void grow_arrays(int); - double compute_vector(int); -+ ////////////////////////////////////////////////// -+ // added by deepmd-kit -+ std::vector get_nodes() const -+ { -+ std::vector tmp(3); -+ tmp[0] = nxnodes; -+ tmp[1] = nynodes; -+ tmp[2] = nznodes; -+ return tmp; -+ }; -+ double *** const get_T_electron()const -+ { -+ return T_electron; -+ } -+ // added by deepmd-kit -+ ////////////////////////////////////////////////// - - private: - int me; diff --git a/source/lmp/env.sh.in b/source/lmp/env.sh.in index b0b2f4d7bf..d00b6d9b5f 100644 --- a/source/lmp/env.sh.in +++ b/source/lmp/env.sh.in @@ -6,6 +6,6 @@ TF_INCLUDE_DIRS=`echo $TENSORFLOW_INCLUDE_DIRS | sed "s/;/ -I/g"` TF_LIBRARY_PATH=`echo $TENSORFLOW_LIBRARY_PATH | sed "s/;/ -L/g"` TF_RPATH=`echo $TENSORFLOW_LIBRARY_PATH | sed "s/;/ -Wl,-rpath=/g"` -NNP_INC=" -std=c++@CMAKE_CXX_STANDARD@ -D@prec_def@ @TTM_DEF@ -DLAMMPS_VERSION_NUMBER=@LAMMPS_VERSION_NUMBER@ -I$DEEPMD_ROOT/include/ " +NNP_INC=" -std=c++@CMAKE_CXX_STANDARD@ -D@prec_def@ -DLAMMPS_VERSION_NUMBER=$(./lmp_version.sh) -I$DEEPMD_ROOT/include/ " NNP_PATH=" -L$TF_LIBRARY_PATH -L$DEEPMD_ROOT/lib" -NNP_LIB=" -Wl,--no-as-needed -l@LIB_DEEPMD_CC@@variant_name@ -ltensorflow_cc -ltensorflow_framework -Wl,-rpath=$TF_RPATH -Wl,-rpath=$DEEPMD_ROOT/lib" +NNP_LIB=" -Wl,--no-as-needed -l@LIB_DEEPMD_CC@ -ltensorflow_cc -ltensorflow_framework -Wl,-rpath=$TF_RPATH -Wl,-rpath=$DEEPMD_ROOT/lib" diff --git a/source/lmp/env_py.sh.in b/source/lmp/env_py.sh.in index 59ccc1129b..f7a97b4771 100644 --- a/source/lmp/env_py.sh.in +++ b/source/lmp/env_py.sh.in @@ -5,9 +5,10 @@ PYTHON_LIBRARY_PATH="@Python_LIBRARY_DIRS@" TF_INCLUDE_DIRS=`echo $TENSORFLOW_INCLUDE_DIRS | sed "s/;/ -I/g"` TF_LIBRARY_PATH=`echo $TENSORFLOW_LIBRARY_PATH | sed "s/;/ -L/g"` +PY_LIBRARY_PATH=`echo $PYTHON_LIBRARY_PATH | sed "s/;/ -L/g"` TF_RPATH=`echo $TENSORFLOW_LIBRARY_PATH | sed "s/;/ -Wl,-rpath=/g"` PYTHON_RPATH=`echo $PYTHON_LIBRARY_PATH | sed "s/;/ -Wl,-rpath=/g"` -NNP_INC=" -D_GLIBCXX_USE_CXX11_ABI=@OP_CXX_ABI@ -std=c++@CMAKE_CXX_STANDARD@ -D@prec_def@ @TTM_DEF@ -DLAMMPS_VERSION_NUMBER=@LAMMPS_VERSION_NUMBER@ -I$TF_INCLUDE_DIRS -I$DEEPMD_ROOT/include/ " -NNP_PATH=" -L$TF_LIBRARY_PATH -L$DEEPMD_ROOT/lib" -NNP_LIB=" -Wl,--no-as-needed -l@LIB_DEEPMD_CC@@variant_name@ -ltensorflow_cc -ltensorflow_framework -lpython@Python_VERSION_MAJOR@.@Python_VERSION_MINOR@ -Wl,-rpath=$TF_RPATH -Wl,-rpath=$DEEPMD_ROOT/lib -Wl,-rpath=$PYTHON_RPATH " +NNP_INC=" -D_GLIBCXX_USE_CXX11_ABI=@OP_CXX_ABI@ -std=c++@CMAKE_CXX_STANDARD@ -D@prec_def@ -DLAMMPS_VERSION_NUMBER=$(./lmp_version.sh) -I$TF_INCLUDE_DIRS -I$DEEPMD_ROOT/include/ " +NNP_PATH=" -L$TF_LIBRARY_PATH -L$DEEPMD_ROOT/lib -L$PY_LIBRARY_PATH" +NNP_LIB=" -Wl,--no-as-needed -l@LIB_DEEPMD_CC@ -ltensorflow_cc -ltensorflow_framework -lpython@Python_VERSION_MAJOR@.@Python_VERSION_MINOR@ -Wl,-rpath=$TF_RPATH -Wl,-rpath=$DEEPMD_ROOT/lib -Wl,-rpath=$PYTHON_RPATH " diff --git a/source/lmp/fix_ttm_dp.h b/source/lmp/fix_ttm_dp.h new file mode 100644 index 0000000000..cf89eb53fb --- /dev/null +++ b/source/lmp/fix_ttm_dp.h @@ -0,0 +1,16 @@ +#include "fix_ttm.h" +#include + +namespace LAMMPS_NS { +class FixTTMDP : public FixTTM { +public: + std::vector get_nodes() const { + std::vector tmp(3); + tmp[0] = nxgrid; + tmp[1] = nygrid; + tmp[2] = nzgrid; + return tmp; + }; + double ***const get_T_electron() const { return T_electron; }; +}; +} // namespace LAMMPS_NS \ No newline at end of file diff --git a/source/lmp/lmp_version.sh b/source/lmp/lmp_version.sh new file mode 100755 index 0000000000..471c15c4a4 --- /dev/null +++ b/source/lmp/lmp_version.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -e +# Read LAMMPS version from version.h +version_line=$(grep LAMMPS_VERSION ../version.h) +# extract version +tmp=${version_line#*\"} # remove prefix ending in " +version=${tmp%\"*} # remove suffix starting with " +# string to int +date --date="$(printf $version)" +"%Y%m%d" diff --git a/source/lmp/pair_deepmd.cpp b/source/lmp/pair_deepmd.cpp index 91f8e4b7c9..0f1e7aa202 100644 --- a/source/lmp/pair_deepmd.cpp +++ b/source/lmp/pair_deepmd.cpp @@ -17,8 +17,10 @@ #include "modify.h" #include "fix.h" #include "citeme.h" -#ifdef USE_TTM -#include "fix_ttm_mod.h" +#if LAMMPS_VERSION_NUMBER>=20210831 +// in lammps #2902, fix_ttm members turns from private to protected +#define USE_TTM 1 +#include "fix_ttm_dp.h" #endif #include "pair_deepmd.h" @@ -188,10 +190,10 @@ void PairDeepMD::make_ttm_aparam( { assert(do_ttm); // get ttm_fix - const FixTTMMod * ttm_fix = NULL; + const FixTTMDP * ttm_fix = NULL; for (int ii = 0; ii < modify->nfix; ii++) { if (string(modify->fix[ii]->id) == ttm_fix_id){ - ttm_fix = dynamic_cast(modify->fix[ii]); + ttm_fix = dynamic_cast(modify->fix[ii]); } } assert(ttm_fix); @@ -310,6 +312,7 @@ void PairDeepMD::compute(int eflag, int vflag) { if (numb_models == 0) return; if (eflag || vflag) ev_setup(eflag,vflag); + if (vflag_atom) error->all(FLERR, "6-element atomic virial is not supported. Use compute centroid/stress/atom command for 9-element atomic virial."); bool do_ghost = true; double **x = atom->x; @@ -915,7 +918,7 @@ void PairDeepMD::settings(int narg, char **arg) ttm_fix_id = arg[iarg+1]; iarg += 1 + 1; #else - error->all(FLERR, "The deepmd-kit was compiled without support for TTM, please rebuild it with -DUSE_TTM"); + error->all(FLERR, "The deepmd-kit was compiled without support for TTM, please rebuild it with LAMMPS version >=20210831"); #endif } else if (string(arg[iarg]) == string("atomic")) { diff --git a/source/lmp/plugin/CMakeLists.txt b/source/lmp/plugin/CMakeLists.txt index f6ce774ca5..ca42a7267b 100644 --- a/source/lmp/plugin/CMakeLists.txt +++ b/source/lmp/plugin/CMakeLists.txt @@ -22,7 +22,9 @@ if (DEFINED LAMMPS_SOURCE_ROOT OR DEFINED LAMMPS_VERSION) find_package(MPI) if(MPI_FOUND) set(LAMMPS_MPI_INCLUDE_DIRS ${MPI_CXX_INCLUDE_DIRS}) - target_link_libraries(lammps_interface INTERFACE MPI::MPI_CXX) + # LAMMPS has linked MPI; do not link twice + # target_link_libraries(lammps_interface INTERFACE MPI::MPI_CXX) + target_include_directories(lammps_interface INTERFACE ${LAMMPS_MPI_INCLUDE_DIRS}) else() # Use LAMMPS serial mpi.h header target_include_directories(lammps_interface INTERFACE "${LAMMPS_HEADER_DIR}/STUBS") @@ -33,6 +35,7 @@ if (DEFINED LAMMPS_SOURCE_ROOT OR DEFINED LAMMPS_VERSION) include(${LAMMPS_SOURCE_ROOT}/cmake/Modules/LAMMPSUtils.cmake) get_lammps_version(${LAMMPS_HEADER_DIR}/version.h LAMMPS_VERSION_NUMBER) set(LAMMPS_VERSION_NUMBER ${LAMMPS_VERSION_NUMBER} PARENT_SCOPE) + message(STATUS "LAMMPS version is ${LAMMPS_VERSION_NUMBER}") configure_file("../pair_deepmd.h.in" "${CMAKE_CURRENT_BINARY_DIR}/pair_deepmd.h" @ONLY) @@ -42,40 +45,53 @@ if (DEFINED LAMMPS_SOURCE_ROOT OR DEFINED LAMMPS_VERSION) ${LAMMPS_SOURCE_ROOT}/src/kspace.cpp # for pppm_dplr ${LAMMPS_SOURCE_ROOT}/src/KSPACE/pppm.cpp ) + if (LAMMPS_VERSION_NUMBER GREATER 20210831) + list(APPEND LMP_SRC ${LAMMPS_SOURCE_ROOT}/src/EXTRA-FIX/fix_ttm.cpp) # for ttm + endif() function(_add_lmp_plugin_variant variant_name prec_def) set (libname "deepmd_lmp${variant_name}") add_library(${libname} MODULE ${LMP_SRC}) - # link: libdeepmd libtensorflow_cc libtensorflow_framework + # link: libdeepmd target_link_libraries (${libname} PUBLIC lammps_interface - ${LIB_DEEPMD_CC}${variant_name} - ${TensorFlow_LIBRARY} - ${TensorFlowFramework_LIBRARY} + ${LIB_DEEPMD_CC} ) target_include_directories(${libname} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${TensorFlow_INCLUDE_DIRS} ${LAMMPS_SOURCE_ROOT}/src/PLUGIN ${LAMMPS_SOURCE_ROOT}/src/KSPACE ${LAMMPS_SOURCE_ROOT}/src ) - + if (LAMMPS_VERSION_NUMBER GREATER 20210831) + target_include_directories(${libname} PRIVATE ${LAMMPS_SOURCE_ROOT}/src/EXTRA-FIX) # for ttm + endif() + if(CMAKE_SYSTEM_NAME STREQUAL Darwin) + set_target_properties(${libname} PROPERTIES LINK_FLAGS "-Wl,-undefined,dynamic_lookup") + else() set_target_properties( ${libname} PROPERTIES INSTALL_RPATH "$ORIGIN;${TensorFlow_LIBRARY_PATH}" LINK_FLAGS "-rdynamic" ) + endif() target_compile_definitions(${libname} PUBLIC ${prec_def} PRIVATE "LMPPLUGIN" # fix header path PRIVATE "LAMMPS_VERSION_NUMBER=${LAMMPS_VERSION_NUMBER}" ) + if (CMAKE_TESTING_ENABLED) + target_link_libraries(${libname} PRIVATE coverage_config) + endif() + + if(BUILD_PY_IF) + install(TARGETS ${libname} DESTINATION deepmd/op/) + else(BUILD_PY_IF) install(TARGETS ${libname} DESTINATION lib/) if (${LAMMPS_VERSION_NUMBER} GREATER_EQUAL 20220324) @@ -92,10 +108,15 @@ if (DEFINED LAMMPS_SOURCE_ROOT OR DEFINED LAMMPS_VERSION) )" ) endif() + endif(BUILD_PY_IF) endfunction() + if(BUILD_PY_IF) + _add_lmp_plugin_variant("plugin" "${HIGH_PREC_DEF}") + else(BUILD_PY_IF) _add_lmp_plugin_variant("${HIGH_PREC_VARIANT}" "${HIGH_PREC_DEF}") _add_lmp_plugin_variant("${LOW_PREC_VARIANT}" "${LOW_PREC_DEF}") + endif() else() message(STATUS "disable LAMMPS plugin mode") diff --git a/source/lmp/tests/.gitignore b/source/lmp/tests/.gitignore new file mode 100644 index 0000000000..76123e90cd --- /dev/null +++ b/source/lmp/tests/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +graph.pb +log.lammps +md.out \ No newline at end of file diff --git a/source/lmp/tests/data.lmp b/source/lmp/tests/data.lmp new file mode 100644 index 0000000000..37370f245d --- /dev/null +++ b/source/lmp/tests/data.lmp @@ -0,0 +1,16 @@ +# the first line must be comment +6 atoms +2 atom types +0.0 13.0 xlo xhi +0.0 13.0 ylo yhi +0.0 13.0 zlo zhi +0.0 0.0 0.0 xy xz yz + +Atoms + +1 1 12.83 2.56 2.18 +2 2 12.09 2.87 2.74 +3 2 0.25 3.32 1.68 +4 1 3.36 3.00 1.81 +5 2 3.51 2.51 2.60 +6 2 4.27 3.22 1.56 diff --git a/source/lmp/tests/test_lammps.py b/source/lmp/tests/test_lammps.py new file mode 100644 index 0000000000..014ef70d2a --- /dev/null +++ b/source/lmp/tests/test_lammps.py @@ -0,0 +1,207 @@ +import sys +import subprocess as sp +from pathlib import Path + +import pytest +import numpy as np +from lammps import PyLammps + + +pbtxt_file = Path(__file__).parent.parent.parent / "tests" / "infer" / "deeppot.pbtxt" +pbtxt_file2 = Path(__file__).parent.parent.parent / "tests" / "infer" / "deeppot-1.pbtxt" +pb_file = Path(__file__).parent / "graph.pb" +pb_file2 = Path(__file__).parent / "graph2.pb" +system_file = Path(__file__).parent.parent.parent / "tests" +data_file = Path(__file__).parent / "data.lmp" +md_file = Path(__file__).parent / "md.out" + +# this is as the same as python and c++ tests, test_deeppot_a.py +expected_ae = np.array([ + -9.275780747115504710e+01,-1.863501786584258468e+02,-1.863392472863538103e+02,-9.279281325486221021e+01,-1.863671545232153903e+02,-1.863619822847602165e+02, +]) +expected_e = np.sum(expected_ae) +expected_f = np.array([ + -3.034045420701179663e-01,8.405844663871177014e-01,7.696947487118485642e-02,7.662001266663505117e-01,-1.880601391333554251e-01,-6.183333871091722944e-01,-5.036172391059643427e-01,-6.529525836149027151e-01,5.432962643022043459e-01,6.382357912332115024e-01,-1.748518296794561167e-01,3.457363524891907125e-01,1.286482986991941552e-03,3.757251165286925043e-01,-5.972588700887541124e-01,-5.987006197104716154e-01,-2.004450304880958100e-01,2.495901655353461868e-01 +]).reshape(6, 3) + +expected_f2 = np.array([ + [-0.6454949 , 1.72457783, 0.18897958], + [ 1.68936514,-0.36995299,-1.36044464], + [-1.09902692,-1.35487928, 1.17416702], + [ 1.68426111,-0.50835585, 0.98340415], + [ 0.05771758, 1.12515818,-1.77561531], + [-1.686822 ,-0.61654789, 0.78950921], +]) + +expected_v = np.array([ + -2.912234126853306959e-01,-3.800610846612756388e-02,2.776624987489437202e-01,-5.053761003913598976e-02,-3.152373041953385746e-01,1.060894290092162379e-01,2.826389131596073745e-01,1.039129970665329250e-01,-2.584378792325942586e-01,-3.121722367954994914e-01,8.483275876786681990e-02,2.524662342344257682e-01,4.142176771106586414e-02,-3.820285230785245428e-02,-2.727311173065460545e-02,2.668859789777112135e-01,-6.448243569420382404e-02,-2.121731470426218846e-01,-8.624335220278558922e-02,-1.809695356746038597e-01,1.529875294531883312e-01,-1.283658185172031341e-01,-1.992682279795223999e-01,1.409924999632362341e-01,1.398322735274434292e-01,1.804318474574856390e-01,-1.470309318999652726e-01,-2.593983661598450730e-01,-4.236536279233147489e-02,3.386387920184946720e-02,-4.174017537818433543e-02,-1.003500282164128260e-01,1.525690815194478966e-01,3.398976109910181037e-02,1.522253908435125536e-01,-2.349125581341701963e-01,9.515545977581392825e-04,-1.643218849228543846e-02,1.993234765412972564e-02,6.027265332209678569e-04,-9.563256398907417355e-02,1.510815124001868293e-01,-7.738094816888557714e-03,1.502832772532304295e-01,-2.380965783745832010e-01,-2.309456719810296654e-01,-6.666961081213038098e-02,7.955566551234216632e-02,-8.099093777937517447e-02,-3.386641099800401927e-02,4.447884755740908608e-02,1.008593228579038742e-01,4.556718179228393811e-02,-6.078081273849572641e-02 +]).reshape(6, 9) +expected_v2 = np.array([ + [-0.70008436, -0.06399891, 0.63678391, -0.07642171, + -0.70580035, 0.20506145, 0.64098364, 0.20305781, + -0.57906794], + [-0.6372635 , 0.14315552, 0.51952246, 0.04604049, + -0.06003681, -0.02688702, 0.54489318, -0.10951559, + -0.43730539], + [-0.25090748, -0.37466262, 0.34085833, -0.26690852, + -0.37676917, 0.29080825, 0.31600481, 0.37558276, + -0.33251064], + [-0.80195614, -0.10273138, 0.06935364, -0.10429256, + -0.29693811, 0.45643496, 0.07247872, 0.45604679, + -0.71048816], + [-0.03840668, -0.07680205, 0.10940472, -0.02374189, + -0.27610266, 0.4336071 , 0.02465248, 0.4290638 , + -0.67496763], + [-0.61475065, -0.21163135, 0.26652929, -0.26134659, + -0.11560267, 0.15415902, 0.34343952, 0.1589482 , + -0.21370642] +]).reshape(6, 9) + +# https://github.com/lammps/lammps/blob/1e1311cf401c5fc2614b5d6d0ff3230642b76597/src/update.cpp#L193 +nktv2p = 1.6021765e6 + +sp.check_output("{} -m deepmd convert-from pbtxt -i {} -o {}".format( + sys.executable, + pbtxt_file.resolve(), + pb_file.resolve(), + ).split()) +sp.check_output("{} -m deepmd convert-from pbtxt -i {} -o {}".format( + sys.executable, + pbtxt_file2.resolve(), + pb_file2.resolve(), + ).split()) + + + +@pytest.fixture +def lammps() -> PyLammps: + lammps = PyLammps() + lammps.units("metal") + lammps.boundary("p p p") + lammps.atom_style("atomic") + lammps.neighbor("2.0 bin") + lammps.neigh_modify("every 10 delay 0 check no") + lammps.read_data(data_file.resolve()) + lammps.mass("1 16") + lammps.mass("2 2") + lammps.timestep(0.0005) + lammps.fix("1 all nve") + yield lammps + + +def test_pair_deepmd(lammps): + lammps.pair_style("deepmd {}".format(pb_file.resolve())) + lammps.pair_coeff("* *") + lammps.run(0) + assert lammps.eval("pe") == pytest.approx(expected_e) + for ii in range(6): + assert lammps.atoms[ii].force == pytest.approx(expected_f[ii]) + lammps.run(1) + + +def test_pair_deepmd_virial(lammps): + lammps.pair_style("deepmd {}".format(pb_file.resolve())) + lammps.pair_coeff("* *") + lammps.compute("virial all centroid/stress/atom NULL pair") + for ii in range(9): + jj = [0, 4, 8, 3, 6, 7, 1, 2, 5][ii] + lammps.variable(f"virial{jj} atom c_virial[{ii+1}]") + lammps.dump("1 all custom 1 dump id " + " ".join([f"v_virial{ii}" for ii in range(9)])) + lammps.run(0) + assert lammps.eval("pe") == pytest.approx(expected_e) + for ii in range(6): + assert lammps.atoms[ii].force == pytest.approx(expected_f[ii]) + for ii in range(9): + assert np.array(lammps.variables[f'virial{ii}'].value) / nktv2p == pytest.approx(expected_v[:, ii]) + + +def test_pair_deepmd_model_devi(lammps): + lammps.pair_style("deepmd {} {} out_file {} out_freq 1 atomic".format(pb_file.resolve(), pb_file2.resolve(), md_file.resolve())) + lammps.pair_coeff("* *") + lammps.run(0) + assert lammps.eval("pe") == pytest.approx(expected_e) + for ii in range(6): + assert lammps.atoms[ii].force == pytest.approx(expected_f[ii]) + # load model devi + md = np.loadtxt(md_file.resolve()) + expected_md_f = np.linalg.norm(np.std([expected_f, expected_f2], axis=0), axis=1) + assert md[7:] == pytest.approx(expected_md_f) + assert md[4] == pytest.approx(np.max(expected_md_f)) + assert md[5] == pytest.approx(np.min(expected_md_f)) + assert md[6] == pytest.approx(np.mean(expected_md_f)) + expected_md_v = np.std([np.sum(expected_v, axis=0), np.sum(expected_v2, axis=0)], axis=0) / 6 + assert md[1] == pytest.approx(np.max(expected_md_v)) + assert md[2] == pytest.approx(np.min(expected_md_v)) + assert md[3] == pytest.approx(np.sqrt(np.mean(np.square(expected_md_v)))) + + +def test_pair_deepmd_model_devi_virial(lammps): + lammps.pair_style("deepmd {} {} out_file {} out_freq 1 atomic".format(pb_file.resolve(), pb_file2.resolve(), md_file.resolve())) + lammps.pair_coeff("* *") + lammps.compute("virial all centroid/stress/atom NULL pair") + for ii in range(9): + jj = [0, 4, 8, 3, 6, 7, 1, 2, 5][ii] + lammps.variable(f"virial{jj} atom c_virial[{ii+1}]") + lammps.dump("1 all custom 1 dump id " + " ".join([f"v_virial{ii}" for ii in range(9)])) + lammps.run(0) + assert lammps.eval("pe") == pytest.approx(expected_e) + for ii in range(6): + assert lammps.atoms[ii].force == pytest.approx(expected_f[ii]) + for ii in range(9): + assert np.array(lammps.variables[f'virial{ii}'].value) / nktv2p == pytest.approx(expected_v[:, ii]) + # load model devi + md = np.loadtxt(md_file.resolve()) + expected_md_f = np.linalg.norm(np.std([expected_f, expected_f2], axis=0), axis=1) + assert md[7:] == pytest.approx(expected_md_f) + assert md[4] == pytest.approx(np.max(expected_md_f)) + assert md[5] == pytest.approx(np.min(expected_md_f)) + assert md[6] == pytest.approx(np.mean(expected_md_f)) + expected_md_v = np.std([np.sum(expected_v, axis=0), np.sum(expected_v2, axis=0)], axis=0) / 6 + assert md[1] == pytest.approx(np.max(expected_md_v)) + assert md[2] == pytest.approx(np.min(expected_md_v)) + assert md[3] == pytest.approx(np.sqrt(np.mean(np.square(expected_md_v)))) + + +def test_pair_deepmd_model_devi_atomic_relative(lammps): + relative = 1.0 + lammps.pair_style("deepmd {} {} out_file {} out_freq 1 atomic relative {}".format(pb_file.resolve(), pb_file2.resolve(), md_file.resolve(), relative)) + lammps.pair_coeff("* *") + lammps.run(0) + assert lammps.eval("pe") == pytest.approx(expected_e) + for ii in range(6): + assert lammps.atoms[ii].force == pytest.approx(expected_f[ii]) + # load model devi + md = np.loadtxt(md_file.resolve()) + norm = np.linalg.norm(np.mean([expected_f, expected_f2], axis=0), axis=1) + expected_md_f = np.linalg.norm(np.std([expected_f, expected_f2], axis=0), axis=1) + expected_md_f /= norm + relative + assert md[7:] == pytest.approx(expected_md_f) + assert md[4] == pytest.approx(np.max(expected_md_f)) + assert md[5] == pytest.approx(np.min(expected_md_f)) + assert md[6] == pytest.approx(np.mean(expected_md_f)) + expected_md_v = np.std([np.sum(expected_v, axis=0), np.sum(expected_v2, axis=0)], axis=0) / 6 + assert md[1] == pytest.approx(np.max(expected_md_v)) + assert md[2] == pytest.approx(np.min(expected_md_v)) + assert md[3] == pytest.approx(np.sqrt(np.mean(np.square(expected_md_v)))) + + +def test_pair_deepmd_model_devi_atomic_relative_v(lammps): + relative = 1.0 + lammps.pair_style("deepmd {} {} out_file {} out_freq 1 atomic relative_v {}".format(pb_file.resolve(), pb_file2.resolve(), md_file.resolve(), relative)) + lammps.pair_coeff("* *") + lammps.run(0) + assert lammps.eval("pe") == pytest.approx(expected_e) + for ii in range(6): + assert lammps.atoms[ii].force == pytest.approx(expected_f[ii]) + md = np.loadtxt(md_file.resolve()) + expected_md_f = np.linalg.norm(np.std([expected_f, expected_f2], axis=0), axis=1) + assert md[7:] == pytest.approx(expected_md_f) + assert md[4] == pytest.approx(np.max(expected_md_f)) + assert md[5] == pytest.approx(np.min(expected_md_f)) + assert md[6] == pytest.approx(np.mean(expected_md_f)) + expected_md_v = np.std([np.sum(expected_v, axis=0), np.sum(expected_v2, axis=0)], axis=0) / 6 + norm = np.abs(np.mean([np.sum(expected_v, axis=0), np.sum(expected_v2, axis=0)], axis=0)) / 6 + expected_md_v /= norm + relative + assert md[1] == pytest.approx(np.max(expected_md_v)) + assert md[2] == pytest.approx(np.min(expected_md_v)) + assert md[3] == pytest.approx(np.sqrt(np.mean(np.square(expected_md_v)))) diff --git a/source/op/CMakeLists.txt b/source/op/CMakeLists.txt index ddcd833b55..f2b0e72247 100644 --- a/source/op/CMakeLists.txt +++ b/source/op/CMakeLists.txt @@ -1,68 +1,55 @@ # libop -set(OP_LIB ${PROJECT_SOURCE_DIR}/lib/src/SimulationRegion.cpp ${PROJECT_SOURCE_DIR}/lib/src/neighbor_list.cc) - file(GLOB OP_SRC prod_env_mat_multi_device_nvnmd.cc map_nvnmd.cc matmul_nvnmd.cc quantize_nvnmd.cc tanh2_nvnmd.cc tanh4_nvnmd.cc custom_op.cc prod_force.cc prod_virial.cc descrpt.cc descrpt_se_a_ef.cc descrpt_se_a_ef.cc descrpt_se_a_ef_para.cc descrpt_se_a_ef_vert.cc pair_tab.cc prod_force_multi_device.cc prod_virial_multi_device.cc soft_min.cc soft_min_force.cc soft_min_virial.cc ewald_recp.cc gelu_multi_device.cc map_aparam.cc neighbor_stat.cc unaggregated_grad.cc tabulate_multi_device.cc prod_env_mat_multi_device.cc) file(GLOB OP_GRADS_SRC custom_op.cc prod_force_grad.cc prod_force_grad_multi_device.cc prod_virial_grad.cc prod_virial_grad_multi_device.cc soft_min_force_grad.cc soft_min_virial_grad.cc ) file(GLOB OP_PY *.py) file(GLOB OP_REMAPPER_SRC optimizer/parallel.cc) -if (BUILD_CPP_IF) - add_library(${LIB_DEEPMD_OP} MODULE ${OP_SRC}) - # link: libdeepmd libtensorflow_cc libtensorflow_framework - target_link_libraries (${LIB_DEEPMD_OP} PUBLIC ${TensorFlow_LIBRARY} ${TensorFlowFramework_LIBRARY}) - target_link_libraries (${LIB_DEEPMD_OP} PRIVATE ${LIB_DEEPMD}) - target_include_directories(${LIB_DEEPMD_OP} PUBLIC ${TensorFlow_INCLUDE_DIRS}) +add_library(${LIB_DEEPMD_OP} MODULE ${OP_SRC} ${OP_REMAPPER_SRC}) +# link: libdeepmd libtensorflow_cc libtensorflow_framework +target_link_libraries (${LIB_DEEPMD_OP} PRIVATE TensorFlow::tensorflow_framework) +target_link_libraries (${LIB_DEEPMD_OP} PRIVATE ${LIB_DEEPMD}) +if(APPLE) + set_target_properties(${LIB_DEEPMD_OP} PROPERTIES INSTALL_RPATH "@loader_path;${TensorFlow_LIBRARY_PATH}") +else() set_target_properties(${LIB_DEEPMD_OP} PROPERTIES INSTALL_RPATH "$ORIGIN;${TensorFlow_LIBRARY_PATH}") -endif (BUILD_CPP_IF) +endif() +if (CMAKE_TESTING_ENABLED) + target_link_libraries(${LIB_DEEPMD_OP} PRIVATE coverage_config) +endif() +target_precompile_headers(${LIB_DEEPMD_OP} PRIVATE custom_op.h) if (BUILD_PY_IF) - add_library(op_abi MODULE ${OP_SRC} ${OP_LIB} ${OP_REMAPPER_SRC}) add_library(op_grads MODULE ${OP_GRADS_SRC}) - - message(STATUS ${TensorFlowFramework_LIBRARY}) # link: libdeepmd libtensorflow_framework - target_link_libraries(op_abi PRIVATE ${LIB_DEEPMD}) target_link_libraries(op_grads PRIVATE ${LIB_DEEPMD}) target_link_libraries( - op_abi PRIVATE ${TensorFlowFramework_LIBRARY} - ) - target_link_libraries( - op_grads PRIVATE ${TensorFlowFramework_LIBRARY} + op_grads PRIVATE TensorFlow::tensorflow_framework ) - target_include_directories(op_abi PUBLIC ${TensorFlow_INCLUDE_DIRS}) - target_include_directories(op_grads PUBLIC ${TensorFlow_INCLUDE_DIRS}) - if (APPLE) - set_target_properties( - op_abi - PROPERTIES - INSTALL_RPATH @loader_path - ) + if(APPLE) set_target_properties( op_grads PROPERTIES INSTALL_RPATH @loader_path ) else() - set_target_properties( - op_abi - PROPERTIES - INSTALL_RPATH $ORIGIN - ) set_target_properties( op_grads PROPERTIES INSTALL_RPATH $ORIGIN ) endif () + if (CMAKE_TESTING_ENABLED) + target_link_libraries(op_grads PRIVATE coverage_config) + endif() + target_precompile_headers(op_grads PRIVATE custom_op.h) endif (BUILD_PY_IF) -if (BUILD_CPP_IF) - install(TARGETS ${LIB_DEEPMD_OP} DESTINATION lib/) -endif (BUILD_CPP_IF) if (BUILD_PY_IF) - install(TARGETS op_abi DESTINATION deepmd/op/) + install(TARGETS ${LIB_DEEPMD_OP} DESTINATION deepmd/op/) install(TARGETS op_grads DESTINATION deepmd/op/) install(FILES ${OP_PY} DESTINATION deepmd/op/) +else(BUILD_PY_IF) + install(TARGETS ${LIB_DEEPMD_OP} DESTINATION lib/) endif (BUILD_PY_IF) diff --git a/source/op/custom_op.h b/source/op/custom_op.h index 93bfc90c86..d00b1dfc4b 100644 --- a/source/op/custom_op.h +++ b/source/op/custom_op.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include diff --git a/source/op/legacy/descrpt_se_a.cc b/source/op/legacy/descrpt_se_a.cc deleted file mode 100644 index cd7abf8a76..0000000000 --- a/source/op/legacy/descrpt_se_a.cc +++ /dev/null @@ -1,350 +0,0 @@ -#include "custom_op.h" -#include "ComputeDescriptor.h" -#include "neighbor_list.h" -#include "fmt_nlist.h" -#include "env_mat.h" -#include "errors.h" - -typedef double boxtensor_t ; -typedef double compute_t; - -REGISTER_OP("DescrptSeA") - .Attr("T: {float, double}") - .Input("coord: T") //atomic coordinates - .Input("type: int32") //atomic type - .Input("natoms: int32") //local atomic number; each type atomic number; daizheyingxiangqude atomic numbers - .Input("box : T") - .Input("mesh : int32") - .Input("davg: T") //average value of data - .Input("dstd: T") //standard deviation - .Attr("rcut_a: float") //no use - .Attr("rcut_r: float") - .Attr("rcut_r_smth: float") - .Attr("sel_a: list(int)") - .Attr("sel_r: list(int)") //all zero - .Output("descrpt: T") - .Output("descrpt_deriv: T") - .Output("rij: T") - .Output("nlist: int32"); - -template -class DescrptSeAOp : public OpKernel { -public: - explicit DescrptSeAOp(OpKernelConstruction* context) : OpKernel(context) { - OP_REQUIRES_OK(context, context->GetAttr("rcut_a", &rcut_a)); - OP_REQUIRES_OK(context, context->GetAttr("rcut_r", &rcut_r)); - OP_REQUIRES_OK(context, context->GetAttr("rcut_r_smth", &rcut_r_smth)); - OP_REQUIRES_OK(context, context->GetAttr("sel_a", &sel_a)); - OP_REQUIRES_OK(context, context->GetAttr("sel_r", &sel_r)); - cum_sum (sec_a, sel_a); - cum_sum (sec_r, sel_r); - ndescrpt_a = sec_a.back() * 4; - ndescrpt_r = sec_r.back() * 1; - ndescrpt = ndescrpt_a + ndescrpt_r; - nnei_a = sec_a.back(); - nnei_r = sec_r.back(); - nnei = nnei_a + nnei_r; - fill_nei_a = (rcut_a < 0); - count_nei_idx_overflow = 0; - } - - void Compute(OpKernelContext* context) override { - // Grab the input tensor - int context_input_index = 0; - const Tensor& coord_tensor = context->input(context_input_index++); - const Tensor& type_tensor = context->input(context_input_index++); - const Tensor& natoms_tensor = context->input(context_input_index++); - const Tensor& box_tensor = context->input(context_input_index++); - const Tensor& mesh_tensor = context->input(context_input_index++); - const Tensor& avg_tensor = context->input(context_input_index++); - const Tensor& std_tensor = context->input(context_input_index++); - - // set size of the sample - OP_REQUIRES (context, (coord_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of coord should be 2")); - OP_REQUIRES (context, (type_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of type should be 2")); - OP_REQUIRES (context, (natoms_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of natoms should be 1")); - OP_REQUIRES (context, (box_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of box should be 2")); - OP_REQUIRES (context, (mesh_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of mesh should be 1")); - OP_REQUIRES (context, (avg_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of avg should be 2")); - OP_REQUIRES (context, (std_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of std should be 2")); - OP_REQUIRES (context, (fill_nei_a), errors::InvalidArgument ("Rotational free descriptor only support the case rcut_a < 0")); - OP_REQUIRES (context, (sec_r.back() == 0), errors::InvalidArgument ("Rotational free descriptor only support all-angular information: sel_r should be all zero.")); - - OP_REQUIRES (context, (natoms_tensor.shape().dim_size(0) >= 3), errors::InvalidArgument ("number of atoms should be larger than (or equal to) 3")); - auto natoms = natoms_tensor .flat(); - int nloc = natoms(0); - int nall = natoms(1); - int ntypes = natoms_tensor.shape().dim_size(0) - 2; - int nsamples = coord_tensor.shape().dim_size(0); - - // check the sizes - OP_REQUIRES (context, (nsamples == type_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nsamples == box_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (ntypes == avg_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of avg should be ntype")); - OP_REQUIRES (context, (ntypes == std_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of std should be ntype")); - - OP_REQUIRES (context, (nall * 3 == coord_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of atoms should match")); - OP_REQUIRES (context, (nall == type_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of atoms should match")); - OP_REQUIRES (context, (9 == box_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of box should be 9")); - OP_REQUIRES (context, (ndescrpt == avg_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of avg should be ndescrpt")); - OP_REQUIRES (context, (ndescrpt == std_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of std should be ndescrpt")); - - int nei_mode = 0; - if (mesh_tensor.shape().dim_size(0) == 16) { - // lammps neighbor list - nei_mode = 3; - } - else if (mesh_tensor.shape().dim_size(0) == 12) { - // user provided extended mesh - nei_mode = 2; - } - else if (mesh_tensor.shape().dim_size(0) == 6) { - // manual copied pbc - assert (nloc == nall); - nei_mode = 1; - } - else if (mesh_tensor.shape().dim_size(0) == 0) { - // no pbc - nei_mode = -1; - } - else { - throw deepmd::deepmd_exception("invalid mesh tensor"); - } - bool b_pbc = true; - // if region is given extended, do not use pbc - if (nei_mode >= 1 || nei_mode == -1) { - b_pbc = false; - } - bool b_norm_atom = false; - if (nei_mode == 1){ - b_norm_atom = true; - } - - // Create an output tensor - TensorShape descrpt_shape ; - descrpt_shape.AddDim (nsamples); - descrpt_shape.AddDim (nloc * ndescrpt); - TensorShape descrpt_deriv_shape ; - descrpt_deriv_shape.AddDim (nsamples); - descrpt_deriv_shape.AddDim (nloc * ndescrpt * 3); - TensorShape rij_shape ; - rij_shape.AddDim (nsamples); - rij_shape.AddDim (nloc * nnei * 3); - TensorShape nlist_shape ; - nlist_shape.AddDim (nsamples); - nlist_shape.AddDim (nloc * nnei); - - int context_output_index = 0; - Tensor* descrpt_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - descrpt_shape, - &descrpt_tensor)); - Tensor* descrpt_deriv_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - descrpt_deriv_shape, - &descrpt_deriv_tensor)); - Tensor* rij_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - rij_shape, - &rij_tensor)); - Tensor* nlist_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - nlist_shape, - &nlist_tensor)); - - auto coord = coord_tensor .matrix(); - auto type = type_tensor .matrix(); - auto box = box_tensor .matrix(); - auto mesh = mesh_tensor .flat(); - auto avg = avg_tensor .matrix(); - auto std = std_tensor .matrix(); - auto descrpt = descrpt_tensor ->matrix(); - auto descrpt_deriv = descrpt_deriv_tensor ->matrix(); - auto rij = rij_tensor ->matrix(); - auto nlist = nlist_tensor ->matrix(); - - // // check the types - // int max_type_v = 0; - // for (int ii = 0; ii < natoms; ++ii){ - // if (type(0, ii) > max_type_v) max_type_v = type(0, ii); - // } - // int ntypes = max_type_v + 1; - OP_REQUIRES (context, (ntypes == int(sel_a.size())), errors::InvalidArgument ("number of types should match the length of sel array")); - OP_REQUIRES (context, (ntypes == int(sel_r.size())), errors::InvalidArgument ("number of types should match the length of sel array")); - - for (int kk = 0; kk < nsamples; ++kk){ - // set region - boxtensor_t boxt [9] = {0}; - for (int dd = 0; dd < 9; ++dd) { - boxt[dd] = box(kk, dd); - } - SimulationRegion region; - region.reinitBox (boxt); - - // set & normalize coord - std::vector d_coord3 (nall*3); - for (int ii = 0; ii < nall; ++ii){ - for (int dd = 0; dd < 3; ++dd){ - d_coord3[ii*3+dd] = coord(kk, ii*3+dd); - } - if (b_norm_atom){ - compute_t inter[3]; - region.phys2Inter (inter, &d_coord3[3*ii]); - for (int dd = 0; dd < 3; ++dd){ - if (inter[dd] < 0 ) inter[dd] += 1.; - else if (inter[dd] >= 1) inter[dd] -= 1.; - } - region.inter2Phys (&d_coord3[3*ii], inter); - } - } - - // set type - std::vector d_type (nall); - for (int ii = 0; ii < nall; ++ii) d_type[ii] = type(kk, ii); - - // build nlist - std::vector > d_nlist_a; - std::vector > d_nlist_r; - std::vector nlist_map; - bool b_nlist_map = false; - if (nei_mode == 3) { - int * pilist, *pjrange, *pjlist; - memcpy (&pilist, &mesh(4), sizeof(int *)); - memcpy (&pjrange, &mesh(8), sizeof(int *)); - memcpy (&pjlist, &mesh(12), sizeof(int *)); - int inum = mesh(1); - assert (inum == nloc); - d_nlist_a.resize (inum); - d_nlist_r.resize (inum); - for (unsigned ii = 0; ii < inum; ++ii){ - d_nlist_r.reserve (pjrange[inum] / inum + 10); - } - for (unsigned ii = 0; ii < inum; ++ii){ - int i_idx = pilist[ii]; - for (unsigned jj = pjrange[ii]; jj < pjrange[ii+1]; ++jj){ - int j_idx = pjlist[jj]; - d_nlist_r[i_idx].push_back (j_idx); - } - } - } - else if (nei_mode == 2) { - std::vector nat_stt = {mesh(1-1), mesh(2-1), mesh(3-1)}; - std::vector nat_end = {mesh(4-1), mesh(5-1), mesh(6-1)}; - std::vector ext_stt = {mesh(7-1), mesh(8-1), mesh(9-1)}; - std::vector ext_end = {mesh(10-1), mesh(11-1), mesh(12-1)}; - std::vector global_grid (3); - for (int dd = 0; dd < 3; ++dd) global_grid[dd] = nat_end[dd] - nat_stt[dd]; - ::build_nlist (d_nlist_a, d_nlist_r, d_coord3, nloc, rcut_a, rcut_r, nat_stt, nat_end, ext_stt, ext_end, region, global_grid); - } - else if (nei_mode == 1) { - std::vector bk_d_coord3 = d_coord3; - std::vector bk_d_type = d_type; - std::vector ncell, ngcell; - copy_coord(d_coord3, d_type, nlist_map, ncell, ngcell, bk_d_coord3, bk_d_type, rcut_r, region); - b_nlist_map = true; - std::vector nat_stt(3, 0); - std::vector ext_stt(3), ext_end(3); - for (int dd = 0; dd < 3; ++dd){ - ext_stt[dd] = -ngcell[dd]; - ext_end[dd] = ncell[dd] + ngcell[dd]; - } - ::build_nlist (d_nlist_a, d_nlist_r, d_coord3, nloc, rcut_a, rcut_r, nat_stt, ncell, ext_stt, ext_end, region, ncell); - } - else if (nei_mode == -1){ - ::build_nlist (d_nlist_a, d_nlist_r, d_coord3, rcut_a, rcut_r, NULL); - } - else { - throw deepmd::deepmd_exception("unknow neighbor mode"); - } - - // loop over atoms, compute descriptors for each atom -#pragma omp parallel for - for (int ii = 0; ii < nloc; ++ii){ - std::vector fmt_nlist_a; - std::vector fmt_nlist_r; - int ret = -1; - if (fill_nei_a){ - if ((ret = format_nlist_i_fill_a (fmt_nlist_a, fmt_nlist_r, d_coord3, ntypes, d_type, region, b_pbc, ii, d_nlist_a[ii], d_nlist_r[ii], rcut_r, sec_a, sec_r)) != -1){ - if (count_nei_idx_overflow == 0) { - std::cout << "WARNING: Radial neighbor list length of type " << ret << " is not enough" << std::endl; - flush(std::cout); - count_nei_idx_overflow ++; - } - } - } - - std::vector d_descrpt_a; - std::vector d_descrpt_a_deriv; - std::vector d_descrpt_r; - std::vector d_descrpt_r_deriv; - std::vector d_rij_a; - std::vector d_rij_r; - env_mat_a (d_descrpt_a, - d_descrpt_a_deriv, - d_rij_a, - d_coord3, - ntypes, - d_type, - region, - b_pbc, - ii, - fmt_nlist_a, - sec_a, - rcut_r_smth, - rcut_r); - - // check sizes - assert (d_descrpt_a.size() == ndescrpt_a); - assert (d_descrpt_a_deriv.size() == ndescrpt_a * 3); - assert (d_rij_a.size() == nnei_a * 3); - assert (int(fmt_nlist_a.size()) == nnei_a); - // record outputs - for (int jj = 0; jj < ndescrpt_a; ++jj) { - descrpt(kk, ii * ndescrpt + jj) = (d_descrpt_a[jj] - avg(d_type[ii], jj)) / std(d_type[ii], jj); - } - for (int jj = 0; jj < ndescrpt_a * 3; ++jj) { - descrpt_deriv(kk, ii * ndescrpt * 3 + jj) = d_descrpt_a_deriv[jj] / std(d_type[ii], jj/3); - } - for (int jj = 0; jj < nnei_a * 3; ++jj){ - rij (kk, ii * nnei * 3 + jj) = d_rij_a[jj]; - } - for (int jj = 0; jj < nnei_a; ++jj){ - int record = fmt_nlist_a[jj]; - if (b_nlist_map && record >= 0) { - record = nlist_map[record]; - } - nlist (kk, ii * nnei + jj) = record; - } - } - } - } -private: - float rcut_a; - float rcut_r; - float rcut_r_smth; - std::vector sel_r; - std::vector sel_a; - std::vector sec_a; - std::vector sec_r; - int ndescrpt, ndescrpt_a, ndescrpt_r; - int nnei, nnei_a, nnei_r; - bool fill_nei_a; - int count_nei_idx_overflow; - void - cum_sum (std::vector & sec, - const std::vector & n_sel) const { - sec.resize (n_sel.size() + 1); - sec[0] = 0; - for (int ii = 1; ii < sec.size(); ++ii){ - sec[ii] = sec[ii-1] + n_sel[ii-1]; - } - } -}; - -#define REGISTER_CPU(T) \ -REGISTER_KERNEL_BUILDER( \ - Name("DescrptSeA").Device(DEVICE_CPU).TypeConstraint("T"), \ - DescrptSeAOp); -REGISTER_CPU(float); -REGISTER_CPU(double); - diff --git a/source/op/legacy/descrpt_se_r.cc b/source/op/legacy/descrpt_se_r.cc deleted file mode 100644 index 408818fbee..0000000000 --- a/source/op/legacy/descrpt_se_r.cc +++ /dev/null @@ -1,335 +0,0 @@ -#include "custom_op.h" -#include "ComputeDescriptor.h" -#include "neighbor_list.h" -#include "fmt_nlist.h" -#include "env_mat.h" -#include "errors.h" - -typedef double boxtensor_t ; -typedef double compute_t; - -REGISTER_OP("DescrptSeR") -.Attr("T: {float, double}") -.Input("coord: T") -.Input("type: int32") -.Input("natoms: int32") -.Input("box: T") -.Input("mesh: int32") -.Input("davg: T") -.Input("dstd: T") -.Attr("rcut: float") -.Attr("rcut_smth: float") -.Attr("sel: list(int)") -.Output("descrpt: T") -.Output("descrpt_deriv: T") -.Output("rij: T") -.Output("nlist: int32"); - -template -class DescrptSeROp : public OpKernel { -public: - explicit DescrptSeROp(OpKernelConstruction* context) : OpKernel(context) { - OP_REQUIRES_OK(context, context->GetAttr("rcut", &rcut)); - OP_REQUIRES_OK(context, context->GetAttr("rcut_smth", &rcut_smth)); - OP_REQUIRES_OK(context, context->GetAttr("sel", &sel)); - cum_sum (sec, sel); - sel_null.resize(3, 0); - cum_sum (sec_null, sel_null); - ndescrpt = sec.back() * 1; - nnei = sec.back(); - fill_nei_a = true; - count_nei_idx_overflow = 0; - } - - void Compute(OpKernelContext* context) override { - // Grab the input tensor - int context_input_index = 0; - const Tensor& coord_tensor = context->input(context_input_index++); - const Tensor& type_tensor = context->input(context_input_index++); - const Tensor& natoms_tensor = context->input(context_input_index++); - const Tensor& box_tensor = context->input(context_input_index++); - const Tensor& mesh_tensor = context->input(context_input_index++); - const Tensor& avg_tensor = context->input(context_input_index++); - const Tensor& std_tensor = context->input(context_input_index++); - - // set size of the sample - OP_REQUIRES (context, (coord_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of coord should be 2")); - OP_REQUIRES (context, (type_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of type should be 2")); - OP_REQUIRES (context, (natoms_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of natoms should be 1")); - OP_REQUIRES (context, (box_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of box should be 2")); - OP_REQUIRES (context, (mesh_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of mesh should be 1")); - OP_REQUIRES (context, (avg_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of avg should be 2")); - OP_REQUIRES (context, (std_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of std should be 2")); - OP_REQUIRES (context, (fill_nei_a), errors::InvalidArgument ("Rotational free descriptor only support the case rcut_a < 0")); - - OP_REQUIRES (context, (natoms_tensor.shape().dim_size(0) >= 3), errors::InvalidArgument ("number of atoms should be larger than (or equal to) 3")); - auto natoms = natoms_tensor .flat(); - int nloc = natoms(0); - int nall = natoms(1); - int ntypes = natoms_tensor.shape().dim_size(0) - 2; - int nsamples = coord_tensor.shape().dim_size(0); - - // check the sizes - OP_REQUIRES (context, (nsamples == type_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nsamples == box_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (ntypes == avg_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of avg should be ntype")); - OP_REQUIRES (context, (ntypes == std_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of std should be ntype")); - - OP_REQUIRES (context, (nall * 3 == coord_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of atoms should match")); - OP_REQUIRES (context, (nall == type_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of atoms should match")); - OP_REQUIRES (context, (9 == box_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of box should be 9")); - OP_REQUIRES (context, (ndescrpt == avg_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of avg should be ndescrpt")); - OP_REQUIRES (context, (ndescrpt == std_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of std should be ndescrpt")); - - int nei_mode = 0; - if (mesh_tensor.shape().dim_size(0) == 16) { - // lammps neighbor list - nei_mode = 3; - } - else if (mesh_tensor.shape().dim_size(0) == 12) { - // user provided extended mesh - nei_mode = 2; - } - else if (mesh_tensor.shape().dim_size(0) == 6) { - // manual copied pbc - assert (nloc == nall); - nei_mode = 1; - } - else if (mesh_tensor.shape().dim_size(0) == 0) { - // no pbc - nei_mode = -1; - } - else { - throw deepmd::deepmd_exception("invalid mesh tensor"); - } - bool b_pbc = true; - // if region is given extended, do not use pbc - if (nei_mode >= 1 || nei_mode == -1) { - b_pbc = false; - } - bool b_norm_atom = false; - if (nei_mode == 1){ - b_norm_atom = true; - } - - // Create an output tensor - TensorShape descrpt_shape ; - descrpt_shape.AddDim (nsamples); - descrpt_shape.AddDim (nloc * ndescrpt); - TensorShape descrpt_deriv_shape ; - descrpt_deriv_shape.AddDim (nsamples); - descrpt_deriv_shape.AddDim (nloc * ndescrpt * 3); - TensorShape rij_shape ; - rij_shape.AddDim (nsamples); - rij_shape.AddDim (nloc * nnei * 3); - TensorShape nlist_shape ; - nlist_shape.AddDim (nsamples); - nlist_shape.AddDim (nloc * nnei); - - int context_output_index = 0; - Tensor* descrpt_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - descrpt_shape, - &descrpt_tensor)); - Tensor* descrpt_deriv_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - descrpt_deriv_shape, - &descrpt_deriv_tensor)); - Tensor* rij_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - rij_shape, - &rij_tensor)); - Tensor* nlist_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - nlist_shape, - &nlist_tensor)); - - auto coord = coord_tensor .matrix(); - auto type = type_tensor .matrix(); - auto box = box_tensor .matrix(); - auto mesh = mesh_tensor .flat(); - auto avg = avg_tensor .matrix(); - auto std = std_tensor .matrix(); - auto descrpt = descrpt_tensor ->matrix(); - auto descrpt_deriv = descrpt_deriv_tensor ->matrix(); - auto rij = rij_tensor ->matrix(); - auto nlist = nlist_tensor ->matrix(); - - OP_REQUIRES (context, (ntypes == int(sel.size())), errors::InvalidArgument ("number of types should match the length of sel array")); - - for (int kk = 0; kk < nsamples; ++kk){ - // set region - boxtensor_t boxt [9] = {0}; - for (int dd = 0; dd < 9; ++dd) { - boxt[dd] = box(kk, dd); - } - SimulationRegion region; - region.reinitBox (boxt); - - // set & normalize coord - std::vector d_coord3 (nall*3); - for (int ii = 0; ii < nall; ++ii){ - for (int dd = 0; dd < 3; ++dd){ - d_coord3[ii*3+dd] = coord(kk, ii*3+dd); - } - if (b_norm_atom){ - compute_t inter[3]; - region.phys2Inter (inter, &d_coord3[3*ii]); - for (int dd = 0; dd < 3; ++dd){ - if (inter[dd] < 0 ) inter[dd] += 1.; - else if (inter[dd] >= 1) inter[dd] -= 1.; - } - region.inter2Phys (&d_coord3[3*ii], inter); - } - } - - // set type - std::vector d_type (nall); - for (int ii = 0; ii < nall; ++ii) d_type[ii] = type(kk, ii); - - // build nlist - std::vector > d_nlist; - std::vector > d_nlist_null; - std::vector nlist_map; - bool b_nlist_map = false; - if (nei_mode == 3) { - int * pilist, *pjrange, *pjlist; - memcpy (&pilist, &mesh(4), sizeof(int *)); - memcpy (&pjrange, &mesh(8), sizeof(int *)); - memcpy (&pjlist, &mesh(12), sizeof(int *)); - int inum = mesh(1); - assert (inum == nloc); - d_nlist_null.resize (inum); - d_nlist.resize (inum); - for (unsigned ii = 0; ii < inum; ++ii){ - d_nlist.reserve (pjrange[inum] / inum + 10); - } - for (unsigned ii = 0; ii < inum; ++ii){ - int i_idx = pilist[ii]; - for (unsigned jj = pjrange[ii]; jj < pjrange[ii+1]; ++jj){ - int j_idx = pjlist[jj]; - d_nlist[i_idx].push_back (j_idx); - } - } - } - else if (nei_mode == 2) { - std::vector nat_stt = {mesh(1-1), mesh(2-1), mesh(3-1)}; - std::vector nat_end = {mesh(4-1), mesh(5-1), mesh(6-1)}; - std::vector ext_stt = {mesh(7-1), mesh(8-1), mesh(9-1)}; - std::vector ext_end = {mesh(10-1), mesh(11-1), mesh(12-1)}; - std::vector global_grid (3); - for (int dd = 0; dd < 3; ++dd) global_grid[dd] = nat_end[dd] - nat_stt[dd]; - ::build_nlist (d_nlist_null, d_nlist, d_coord3, nloc, -1, rcut, nat_stt, nat_end, ext_stt, ext_end, region, global_grid); - } - else if (nei_mode == 1) { - std::vector bk_d_coord3 = d_coord3; - std::vector bk_d_type = d_type; - std::vector ncell, ngcell; - copy_coord(d_coord3, d_type, nlist_map, ncell, ngcell, bk_d_coord3, bk_d_type, rcut, region); - b_nlist_map = true; - std::vector nat_stt(3, 0); - std::vector ext_stt(3), ext_end(3); - for (int dd = 0; dd < 3; ++dd){ - ext_stt[dd] = -ngcell[dd]; - ext_end[dd] = ncell[dd] + ngcell[dd]; - } - ::build_nlist (d_nlist_null, d_nlist, d_coord3, nloc, -1, rcut, nat_stt, ncell, ext_stt, ext_end, region, ncell); - } - else if (nei_mode == -1){ - ::build_nlist (d_nlist_null, d_nlist, d_coord3, -1, rcut, NULL); - } - else { - throw deepmd::deepmd_exception("unknow neighbor mode"); - } - - // loop over atoms, compute descriptors for each atom -#pragma omp parallel for - for (int ii = 0; ii < nloc; ++ii){ - std::vector fmt_nlist_null; - std::vector fmt_nlist; - int ret = -1; - if (fill_nei_a){ - if ((ret = format_nlist_i_fill_a (fmt_nlist, fmt_nlist_null, d_coord3, ntypes, d_type, region, b_pbc, ii, d_nlist_null[ii], d_nlist[ii], rcut, sec, sec_null)) != -1){ - if (count_nei_idx_overflow == 0) { - std::cout << "WARNING: Radial neighbor list length of type " << ret << " is not enough" << std::endl; - flush(std::cout); - count_nei_idx_overflow ++; - } - } - } - // std::cout << ii << " " ; - // for (int jj = 0 ; jj < fmt_nlist.size(); ++jj){ - // std::cout << fmt_nlist[jj] << " " ; - // } - // std::cout << std::endl; - - std::vector d_descrpt; - std::vector d_descrpt_deriv; - std::vector d_rij; - env_mat_r (d_descrpt, - d_descrpt_deriv, - d_rij, - d_coord3, - ntypes, - d_type, - region, - b_pbc, - ii, - fmt_nlist, - sec, - rcut_smth, - rcut); - - // check sizes - assert (d_descrpt_deriv.size() == ndescrpt * 3); - assert (d_rij.size() == nnei * 3); - assert (int(fmt_nlist.size()) == nnei); - // record outputs - for (int jj = 0; jj < ndescrpt; ++jj) { - descrpt(kk, ii * ndescrpt + jj) = (d_descrpt[jj] - avg(d_type[ii], jj)) / std(d_type[ii], jj); - } - for (int jj = 0; jj < ndescrpt * 3; ++jj) { - descrpt_deriv(kk, ii * ndescrpt * 3 + jj) = d_descrpt_deriv[jj] / std(d_type[ii], jj/3); - } - for (int jj = 0; jj < nnei * 3; ++jj){ - rij (kk, ii * nnei * 3 + jj) = d_rij[jj]; - } - for (int jj = 0; jj < nnei; ++jj){ - int record = fmt_nlist[jj]; - if (b_nlist_map && record >= 0) { - record = nlist_map[record]; - } - nlist (kk, ii * nnei + jj) = record; - } - } - } - } -private: - float rcut; - float rcut_smth; - std::vector sel; - std::vector sel_null; - std::vector sec; - std::vector sec_null; - int ndescrpt; - int nnei; - bool fill_nei_a; - int count_nei_idx_overflow; - void - cum_sum (std::vector & sec, - const std::vector & n_sel) const { - sec.resize (n_sel.size() + 1); - sec[0] = 0; - for (int ii = 1; ii < sec.size(); ++ii){ - sec[ii] = sec[ii-1] + n_sel[ii-1]; - } - } -}; - -#define REGISTER_CPU(T) \ -REGISTER_KERNEL_BUILDER( \ - Name("DescrptSeR").Device(DEVICE_CPU).TypeConstraint("T"), \ - DescrptSeROp); -REGISTER_CPU(float); -REGISTER_CPU(double); - diff --git a/source/op/legacy/prod_force_se_a.cc b/source/op/legacy/prod_force_se_a.cc deleted file mode 100644 index a07cd1d02d..0000000000 --- a/source/op/legacy/prod_force_se_a.cc +++ /dev/null @@ -1,114 +0,0 @@ -#include "custom_op.h" -#include "prod_force.h" - -REGISTER_OP("ProdForceSeA") -.Attr("T: {float, double}") -.Input("net_deriv: T") -.Input("in_deriv: T") -.Input("nlist: int32") -.Input("natoms: int32") -.Attr("n_a_sel: int") -.Attr("n_r_sel: int") -.Output("force: T"); - - -using namespace tensorflow; - -using CPUDevice = Eigen::ThreadPoolDevice; -using GPUDevice = Eigen::GpuDevice; - -template -class ProdForceSeAOp : public OpKernel { - public: - explicit ProdForceSeAOp(OpKernelConstruction* context) : OpKernel(context) { - OP_REQUIRES_OK(context, context->GetAttr("n_a_sel", &n_a_sel)); - OP_REQUIRES_OK(context, context->GetAttr("n_r_sel", &n_r_sel)); - // n_a_shift = n_a_sel * 4; - } - - void Compute(OpKernelContext* context) override { - // Grab the input tensor - int context_input_index = 0; - const Tensor& net_deriv_tensor = context->input(context_input_index++); - const Tensor& in_deriv_tensor = context->input(context_input_index++); - const Tensor& nlist_tensor = context->input(context_input_index++); - const Tensor& natoms_tensor = context->input(context_input_index++); - - // set size of the sample - OP_REQUIRES (context, (net_deriv_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of net deriv should be 2")); - OP_REQUIRES (context, (in_deriv_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of input deriv should be 2")); - OP_REQUIRES (context, (nlist_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of nlist should be 2")); - OP_REQUIRES (context, (natoms_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of natoms should be 1")); - - OP_REQUIRES (context, (natoms_tensor.shape().dim_size(0) >= 3), errors::InvalidArgument ("number of atoms should be larger than (or equal to) 3")); - auto natoms = natoms_tensor .flat(); - - int nframes = net_deriv_tensor.shape().dim_size(0); - int nloc = natoms(0); - int nall = natoms(1); - int ndescrpt = net_deriv_tensor.shape().dim_size(1) / nloc; - int nnei = nlist_tensor.shape().dim_size(1) / nloc; - - // check the sizes - OP_REQUIRES (context, (nframes == in_deriv_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nframes == nlist_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - - OP_REQUIRES (context, (nloc * ndescrpt * 3 == in_deriv_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of descriptors should match")); - OP_REQUIRES (context, (nnei == n_a_sel + n_r_sel), errors::InvalidArgument ("number of neighbors should match")); - OP_REQUIRES (context, (0 == n_r_sel), errors::InvalidArgument ("Rotational free only support all-angular information")); - - // Create an output tensor - TensorShape force_shape ; - force_shape.AddDim (nframes); - force_shape.AddDim (3 * nall); - Tensor* force_tensor = NULL; - int context_output_index = 0; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - force_shape, &force_tensor)); - - // flat the tensors - auto net_deriv = net_deriv_tensor.flat(); - auto in_deriv = in_deriv_tensor.flat(); - auto nlist = nlist_tensor.flat(); - auto force = force_tensor->flat(); - - assert (nframes == force_shape.dim_size(0)); - assert (nframes == net_deriv_tensor.shape().dim_size(0)); - assert (nframes == in_deriv_tensor.shape().dim_size(0)); - assert (nframes == nlist_tensor.shape().dim_size(0)); - assert (nall * 3 == force_shape.dim_size(1)); - assert (nloc * ndescrpt == net_deriv_tensor.shape().dim_size(1)); - assert (nloc * ndescrpt * 3 == in_deriv_tensor.shape().dim_size(1)); - assert (nloc * nnei == nlist_tensor.shape().dim_size(1)); - assert (nnei * 4 == ndescrpt); - - // loop over samples -#pragma omp parallel for - for (int kk = 0; kk < nframes; ++kk){ - int force_iter = kk * nall * 3; - int net_iter = kk * nloc * ndescrpt; - int in_iter = kk * nloc * ndescrpt * 3; - int nlist_iter = kk * nloc * nnei; - - deepmd::prod_force_a_cpu( - &force(force_iter), - &net_deriv(net_iter), - &in_deriv(in_iter), - &nlist(nlist_iter), - nloc, - nall, - nnei); - } - } -private: - int n_r_sel, n_a_sel; -}; - -// Register the CPU kernels. -#define REGISTER_CPU(T) \ -REGISTER_KERNEL_BUILDER( \ - Name("ProdForceSeA").Device(DEVICE_CPU).TypeConstraint("T"), \ - ProdForceSeAOp); -REGISTER_CPU(float); -REGISTER_CPU(double); - diff --git a/source/op/legacy/prod_force_se_r.cc b/source/op/legacy/prod_force_se_r.cc deleted file mode 100644 index 1aa6d76760..0000000000 --- a/source/op/legacy/prod_force_se_r.cc +++ /dev/null @@ -1,104 +0,0 @@ -#include "custom_op.h" -#include "prod_force.h" - -REGISTER_OP("ProdForceSeR") -.Attr("T: {float, double}") -.Input("net_deriv: T") -.Input("in_deriv: T") -.Input("nlist: int32") -.Input("natoms: int32") -.Output("force: T"); - -using namespace tensorflow; - -using CPUDevice = Eigen::ThreadPoolDevice; - -template -class ProdForceSeROp : public OpKernel { - public: - explicit ProdForceSeROp(OpKernelConstruction* context) : OpKernel(context) { - } - - void Compute(OpKernelContext* context) override { - // Grab the input tensor - int context_input_index = 0; - const Tensor& net_deriv_tensor = context->input(context_input_index++); - const Tensor& in_deriv_tensor = context->input(context_input_index++); - const Tensor& nlist_tensor = context->input(context_input_index++); - const Tensor& natoms_tensor = context->input(context_input_index++); - - // set size of the sample - OP_REQUIRES (context, (net_deriv_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of net deriv should be 2")); - OP_REQUIRES (context, (in_deriv_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of input deriv should be 2")); - OP_REQUIRES (context, (nlist_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of nlist should be 2")); - OP_REQUIRES (context, (natoms_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of natoms should be 1")); - - OP_REQUIRES (context, (natoms_tensor.shape().dim_size(0) >= 3), errors::InvalidArgument ("number of atoms should be larger than (or equal to) 3")); - auto natoms = natoms_tensor .flat(); - - int nframes = net_deriv_tensor.shape().dim_size(0); - int nloc = natoms(0); - int nall = natoms(1); - int ndescrpt = net_deriv_tensor.shape().dim_size(1) / nloc; - int nnei = nlist_tensor.shape().dim_size(1) / nloc; - - // check the sizes - OP_REQUIRES (context, (nframes == in_deriv_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nframes == nlist_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - - OP_REQUIRES (context, (nloc * ndescrpt * 3 == in_deriv_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of descriptors should match")); - - // Create an output tensor - TensorShape force_shape ; - force_shape.AddDim (nframes); - force_shape.AddDim (3 * nall); - Tensor* force_tensor = NULL; - int context_output_index = 0; - OP_REQUIRES_OK(context, context->allocate_output(context_output_index++, - force_shape, &force_tensor)); - - // flat the tensors - auto net_deriv = net_deriv_tensor.flat(); - auto in_deriv = in_deriv_tensor.flat(); - auto nlist = nlist_tensor.flat(); - auto force = force_tensor->flat(); - - assert (nframes == force_shape.dim_size(0)); - assert (nframes == net_deriv_tensor.shape().dim_size(0)); - assert (nframes == in_deriv_tensor.shape().dim_size(0)); - assert (nframes == nlist_tensor.shape().dim_size(0)); - assert (nall * 3 == force_shape.dim_size(1)); - assert (nloc * ndescrpt == net_deriv_tensor.shape().dim_size(1)); - assert (nloc * ndescrpt * 3 == in_deriv_tensor.shape().dim_size(1)); - assert (nloc * nnei == nlist_tensor.shape().dim_size(1)); - assert (nnei * 1 == ndescrpt); - - // loop over samples -#pragma omp parallel for - for (int kk = 0; kk < nframes; ++kk){ - int force_iter = kk * nall * 3; - int net_iter = kk * nloc * ndescrpt; - int in_iter = kk * nloc * ndescrpt * 3; - int nlist_iter = kk * nloc * nnei; - - deepmd::prod_force_r_cpu( - &force(force_iter), - &net_deriv(net_iter), - &in_deriv(in_iter), - &nlist(nlist_iter), - nloc, - nall, - nnei); - } - } -}; - -// Register the CPU kernels. -#define REGISTER_CPU(T) \ -REGISTER_KERNEL_BUILDER( \ - Name("ProdForceSeR").Device(DEVICE_CPU).TypeConstraint("T"), \ - ProdForceSeROp); -REGISTER_CPU(float); -REGISTER_CPU(double); - - diff --git a/source/op/legacy/prod_virial_se_a.cc b/source/op/legacy/prod_virial_se_a.cc deleted file mode 100644 index 80223f5e67..0000000000 --- a/source/op/legacy/prod_virial_se_a.cc +++ /dev/null @@ -1,119 +0,0 @@ -#include "custom_op.h" -#include "prod_virial.h" - -REGISTER_OP("ProdVirialSeA") -.Attr("T: {float, double}") -.Input("net_deriv: T") -.Input("in_deriv: T") -.Input("rij: T") -.Input("nlist: int32") -.Input("natoms: int32") -.Attr("n_a_sel: int") -.Attr("n_r_sel: int") -.Output("virial: T") -.Output("atom_virial: T"); - -using namespace tensorflow; - -using CPUDevice = Eigen::ThreadPoolDevice; -using GPUDevice = Eigen::GpuDevice; - -template -class ProdVirialSeAOp : public OpKernel { - public: - explicit ProdVirialSeAOp(OpKernelConstruction* context) : OpKernel(context) { - OP_REQUIRES_OK(context, context->GetAttr("n_a_sel", &n_a_sel)); - OP_REQUIRES_OK(context, context->GetAttr("n_r_sel", &n_r_sel)); - // n_a_shift = n_a_sel * 4; - } - - void Compute(OpKernelContext* context) override { - // Grab the input tensor - int context_input_index = 0; - const Tensor& net_deriv_tensor = context->input(context_input_index++); - const Tensor& in_deriv_tensor = context->input(context_input_index++); - const Tensor& rij_tensor = context->input(context_input_index++); - const Tensor& nlist_tensor = context->input(context_input_index++); - const Tensor& natoms_tensor = context->input(context_input_index++); - - // set size of the sample - OP_REQUIRES (context, (net_deriv_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of net deriv should be 2")); - OP_REQUIRES (context, (in_deriv_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of input deriv should be 2")); - OP_REQUIRES (context, (rij_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of rij should be 2")); - OP_REQUIRES (context, (nlist_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of nlist should be 2")); - OP_REQUIRES (context, (natoms_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of natoms should be 1")); - - OP_REQUIRES (context, (natoms_tensor.shape().dim_size(0) >= 3), errors::InvalidArgument ("number of atoms should be larger than (or equal to) 3")); - auto natoms = natoms_tensor .flat(); - - int nframes = net_deriv_tensor.shape().dim_size(0); - int nloc = natoms(0); - int nall = natoms(1); - int ndescrpt = net_deriv_tensor.shape().dim_size(1) / nloc; - int nnei = nlist_tensor.shape().dim_size(1) / nloc; - - // check the sizes - OP_REQUIRES (context, (nframes == in_deriv_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nframes == rij_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nframes == nlist_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - - OP_REQUIRES (context, (nloc * ndescrpt * 3 == in_deriv_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of descriptors should match")); - OP_REQUIRES (context, (nloc * nnei * 3 == rij_tensor.shape().dim_size(1)), errors::InvalidArgument ("dim of rij should be nnei * 3")); - OP_REQUIRES (context, (nnei == n_a_sel + n_r_sel), errors::InvalidArgument ("number of neighbors should match")); - - // Create an output tensor - TensorShape virial_shape ; - virial_shape.AddDim (nframes); - virial_shape.AddDim (9); - Tensor* virial_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(0, virial_shape, &virial_tensor)); - TensorShape atom_virial_shape ; - atom_virial_shape.AddDim (nframes); - atom_virial_shape.AddDim (9 * nall); - Tensor* atom_virial_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(1, atom_virial_shape, &atom_virial_tensor)); - - // flat the tensors - auto net_deriv = net_deriv_tensor.flat(); - auto in_deriv = in_deriv_tensor.flat(); - auto rij = rij_tensor.flat(); - auto nlist = nlist_tensor.flat(); - auto virial = virial_tensor->flat(); - auto atom_virial = atom_virial_tensor->flat(); - - // loop over samples -#pragma omp parallel for - for (int kk = 0; kk < nframes; ++kk){ - int net_iter = kk * nloc * ndescrpt; - int in_iter = kk * nloc * ndescrpt * 3; - int rij_iter = kk * nloc * nnei * 3; - int nlist_iter = kk * nloc * nnei; - int virial_iter = kk * 9; - int atom_virial_iter = kk * nall * 9; - - deepmd::prod_virial_a_cpu( - &virial(virial_iter), - &atom_virial(atom_virial_iter), - &net_deriv(net_iter), - &in_deriv(in_iter), - &rij(rij_iter), - &nlist(nlist_iter), - nloc, - nall, - nnei); - } - } -private: - int n_r_sel, n_a_sel; -}; - -// Register the CPU kernels. -#define REGISTER_CPU(T) \ -REGISTER_KERNEL_BUILDER( \ - Name("ProdVirialSeA").Device(DEVICE_CPU).TypeConstraint("T"), \ - ProdVirialSeAOp); -REGISTER_CPU(float); -REGISTER_CPU(double); - - - diff --git a/source/op/legacy/prod_virial_se_r.cc b/source/op/legacy/prod_virial_se_r.cc deleted file mode 100644 index d063de03a3..0000000000 --- a/source/op/legacy/prod_virial_se_r.cc +++ /dev/null @@ -1,109 +0,0 @@ -#include "custom_op.h" -#include "prod_virial.h" - -REGISTER_OP("ProdVirialSeR") -.Attr("T: {float, double}") -.Input("net_deriv: T") -.Input("in_deriv: T") -.Input("rij: T") -.Input("nlist: int32") -.Input("natoms: int32") -.Output("virial: T") -.Output("atom_virial: T"); - -using namespace tensorflow; - -using CPUDevice = Eigen::ThreadPoolDevice; - -template -class ProdVirialSeROp : public OpKernel { - public: - explicit ProdVirialSeROp(OpKernelConstruction* context) : OpKernel(context) { - } - - void Compute(OpKernelContext* context) override { - // Grab the input tensor - int context_input_index = 0; - const Tensor& net_deriv_tensor = context->input(context_input_index++); - const Tensor& in_deriv_tensor = context->input(context_input_index++); - const Tensor& rij_tensor = context->input(context_input_index++); - const Tensor& nlist_tensor = context->input(context_input_index++); - const Tensor& natoms_tensor = context->input(context_input_index++); - - // set size of the sample - OP_REQUIRES (context, (net_deriv_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of net deriv should be 2")); - OP_REQUIRES (context, (in_deriv_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of input deriv should be 2")); - OP_REQUIRES (context, (rij_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of rij should be 2")); - OP_REQUIRES (context, (nlist_tensor.shape().dims() == 2), errors::InvalidArgument ("Dim of nlist should be 2")); - OP_REQUIRES (context, (natoms_tensor.shape().dims() == 1), errors::InvalidArgument ("Dim of natoms should be 1")); - - OP_REQUIRES (context, (natoms_tensor.shape().dim_size(0) >= 3), errors::InvalidArgument ("number of atoms should be larger than (or equal to) 3")); - auto natoms = natoms_tensor .flat(); - - int nframes = net_deriv_tensor.shape().dim_size(0); - int nloc = natoms(0); - int nall = natoms(1); - int ndescrpt = net_deriv_tensor.shape().dim_size(1) / nloc; - int nnei = nlist_tensor.shape().dim_size(1) / nloc; - - // check the sizes - OP_REQUIRES (context, (nframes == in_deriv_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nframes == rij_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - OP_REQUIRES (context, (nframes == nlist_tensor.shape().dim_size(0)), errors::InvalidArgument ("number of samples should match")); - - OP_REQUIRES (context, (nloc * ndescrpt * 3 == in_deriv_tensor.shape().dim_size(1)), errors::InvalidArgument ("number of descriptors should match")); - OP_REQUIRES (context, (nloc * nnei * 3 == rij_tensor.shape().dim_size(1)), errors::InvalidArgument ("dim of rij should be nnei * 3")); - - // Create an output tensor - TensorShape virial_shape ; - virial_shape.AddDim (nframes); - virial_shape.AddDim (9); - Tensor* virial_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(0, virial_shape, &virial_tensor)); - TensorShape atom_virial_shape ; - atom_virial_shape.AddDim (nframes); - atom_virial_shape.AddDim (9 * nall); - Tensor* atom_virial_tensor = NULL; - OP_REQUIRES_OK(context, context->allocate_output(1, atom_virial_shape, &atom_virial_tensor)); - - // flat the tensors - auto net_deriv = net_deriv_tensor.flat(); - auto in_deriv = in_deriv_tensor.flat(); - auto rij = rij_tensor.flat(); - auto nlist = nlist_tensor.flat(); - auto virial = virial_tensor->flat(); - auto atom_virial = atom_virial_tensor->flat(); - - // loop over samples -#pragma omp parallel for - for (int kk = 0; kk < nframes; ++kk){ - int net_iter = kk * nloc * ndescrpt; - int in_iter = kk * nloc * ndescrpt * 3; - int rij_iter = kk * nloc * nnei * 3; - int nlist_iter = kk * nloc * nnei; - int virial_iter = kk * 9; - int atom_virial_iter = kk * nall * 9; - - deepmd::prod_virial_r_cpu( - &virial(virial_iter), - &atom_virial(atom_virial_iter), - &net_deriv(net_iter), - &in_deriv(in_iter), - &rij(rij_iter), - &nlist(nlist_iter), - nloc, - nall, - nnei); - } - } -}; - -#define REGISTER_CPU(T) \ -REGISTER_KERNEL_BUILDER( \ - Name("ProdVirialSeR").Device(DEVICE_CPU).TypeConstraint("T"), \ - ProdVirialSeROp); -REGISTER_CPU(float); -REGISTER_CPU(double); - - - diff --git a/source/op/optimizer/parallel.cc b/source/op/optimizer/parallel.cc index c3919f5e5d..b0542fa94e 100644 --- a/source/op/optimizer/parallel.cc +++ b/source/op/optimizer/parallel.cc @@ -60,13 +60,13 @@ Status ParallelProdForce(RemapperContext *ctx, int node_index, std::vector *nodes_to_delete) { // skip on GPUs if (GetNumAvailableGPUs() > 0) - return Status::OK(); + return Status(); const NodeDef *ori_node = ctx->graph_view.GetNode(node_index)->node(); auto &src_attr = ori_node->attr(); TF_INT64 tot = GetNThreads(); if (tot <= 1) - return Status::OK(); + return Status(); NodeDef sum_node; sum_node.set_name(ori_node->name()); @@ -104,7 +104,7 @@ Status ParallelProdForce(RemapperContext *ctx, int node_index, TF_RETURN_IF_ERROR(mutation->Apply()); (*invalidated_nodes)[node_index] = true; - return Status::OK(); + return Status(); } Status DPParallel::Optimize(Cluster *cluster, const GrapplerItem &item, @@ -153,7 +153,7 @@ Status DPParallel::Optimize(Cluster *cluster, const GrapplerItem &item, *optimized_graph = std::move(mutable_item.graph); - return Status::OK(); + return Status(); } REGISTER_GRAPH_OPTIMIZER_AS(DPParallel, "dpparallel"); diff --git a/source/op/optimizer/parallel.h b/source/op/optimizer/parallel.h index 4fa4f69648..f7f6b1816c 100644 --- a/source/op/optimizer/parallel.h +++ b/source/op/optimizer/parallel.h @@ -10,7 +10,7 @@ class DPParallel : public CustomGraphOptimizer { public: Status Init( const tensorflow::RewriterConfig_CustomGraphOptimizer* config) override { - return Status::OK(); + return Status(); } std::string name() const override { return "dpparallel"; }; bool UsesFunctionLibrary() const override { return false; } diff --git a/source/tests/common.py b/source/tests/common.py index 38c5bc1aee..64a10d6cc5 100644 --- a/source/tests/common.py +++ b/source/tests/common.py @@ -1,11 +1,14 @@ import os, sys, dpdata, shutil import numpy as np import pathlib +import collections +import glob from deepmd.env import tf from deepmd.env import GLOBAL_NP_FLOAT_PRECISION from deepmd.common import j_loader as dp_j_loader from deepmd.utils import random as dp_random +from deepmd.entrypoints.main import main if GLOBAL_NP_FLOAT_PRECISION == np.float32 : global_default_fv_hh = 1e-2 @@ -407,3 +410,489 @@ def strerch_box(old_coord, old_box, new_box): nbox = new_box.reshape(3,3) ncoord = ocoord @ np.linalg.inv(obox) @ nbox return ncoord.reshape(old_coord.shape) + + +def run_dp(cmd: str) -> int: + """Run DP directly from the entry point instead of the subprocess. + + It is quite slow to start DeePMD-kit with subprocess. + + Parameters + ---------- + cmd : str + The command to run. + + Returns + ------- + int + Always returns 0. + """ + cmds = cmd.split() + if cmds[0] == 'dp': + cmds = cmds[1:] + else: + raise RuntimeError('The command is not dp') + + main(cmds) + return 0 + + +# some tests still need this class +class DataSets (object): + """ + Outdated class for one data system. + .. deprecated:: 2.0.0 + This class is not maintained any more. + """ + def __init__ (self, + sys_path, + set_prefix, + seed = None, + shuffle_test = True) : + self.dirs = glob.glob (os.path.join(sys_path, set_prefix + ".*")) + self.dirs.sort() + # load atom type + self.atom_type, self.idx_map, self.idx3_map = self.load_type (sys_path) + # load atom type map + self.type_map = self.load_type_map(sys_path) + if self.type_map is not None: + assert(len(self.type_map) >= max(self.atom_type)+1) + # train dirs + self.test_dir = self.dirs[-1] + if len(self.dirs) == 1 : + self.train_dirs = self.dirs + else : + self.train_dirs = self.dirs[:-1] + # check fparam + has_fparam = [ os.path.isfile(os.path.join(ii, 'fparam.npy')) for ii in self.dirs ] + if any(has_fparam) and (not all(has_fparam)) : + raise RuntimeError("system %s: if any set has frame parameter, then all sets should have frame parameter" % sys_path) + if all(has_fparam) : + self.has_fparam = 0 + else : + self.has_fparam = -1 + # check aparam + has_aparam = [ os.path.isfile(os.path.join(ii, 'aparam.npy')) for ii in self.dirs ] + if any(has_aparam) and (not all(has_aparam)) : + raise RuntimeError("system %s: if any set has frame parameter, then all sets should have frame parameter" % sys_path) + if all(has_aparam) : + self.has_aparam = 0 + else : + self.has_aparam = -1 + # energy norm + self.eavg = self.stats_energy() + # load sets + self.set_count = 0 + self.load_batch_set (self.train_dirs[self.set_count % self.get_numb_set()]) + self.load_test_set (self.test_dir, shuffle_test) + + def check_batch_size (self, batch_size) : + for ii in self.train_dirs : + tmpe = np.load(os.path.join(ii, "coord.npy")) + if tmpe.shape[0] < batch_size : + return ii, tmpe.shape[0] + return None + + def check_test_size (self, test_size) : + tmpe = np.load(os.path.join(self.test_dir, "coord.npy")) + if tmpe.shape[0] < test_size : + return self.test_dir, tmpe.shape[0] + else : + return None + + def load_type (self, sys_path) : + atom_type = np.loadtxt (os.path.join(sys_path, "type.raw"), dtype=np.int32, ndmin=1) + natoms = atom_type.shape[0] + idx = np.arange (natoms) + idx_map = np.lexsort ((idx, atom_type)) + atom_type3 = np.repeat(atom_type, 3) + idx3 = np.arange (natoms * 3) + idx3_map = np.lexsort ((idx3, atom_type3)) + return atom_type, idx_map, idx3_map + + def load_type_map(self, sys_path) : + fname = os.path.join(sys_path, 'type_map.raw') + if os.path.isfile(fname) : + with open(os.path.join(sys_path, 'type_map.raw')) as fp: + return fp.read().split() + else : + return None + + def get_type_map(self) : + return self.type_map + + def get_numb_set (self) : + return len (self.train_dirs) + + def stats_energy (self) : + eners = np.array([]) + for ii in self.train_dirs: + ener_file = os.path.join(ii, "energy.npy") + if os.path.isfile(ener_file) : + ei = np.load(ener_file) + eners = np.append(eners, ei) + if eners.size == 0 : + return 0 + else : + return np.average(eners) + + def load_energy(self, + set_name, + nframes, + nvalues, + energy_file, + atom_energy_file) : + """ + return : coeff_ener, ener, coeff_atom_ener, atom_ener + """ + # load atom_energy + coeff_atom_ener, atom_ener = self.load_data(set_name, atom_energy_file, [nframes, nvalues], False) + # ignore energy_file + if coeff_atom_ener == 1: + ener = np.sum(atom_ener, axis = 1) + coeff_ener = 1 + # load energy_file + else: + coeff_ener, ener = self.load_data(set_name, energy_file, [nframes], False) + return coeff_ener, ener, coeff_atom_ener, atom_ener + + def load_data(self, set_name, data_name, shape, is_necessary = True): + path = os.path.join(set_name, data_name+".npy") + if os.path.isfile (path) : + data = np.load(path) + data = np.reshape(data, shape) + if is_necessary: + return data + return 1, data + elif is_necessary: + raise OSError("%s not found!" % path) + else: + data = np.zeros(shape) + return 0, data + + def load_set(self, set_name, shuffle = True): + data = {} + data["box"] = self.load_data(set_name, "box", [-1, 9]) + nframe = data["box"].shape[0] + data["coord"] = self.load_data(set_name, "coord", [nframe, -1]) + ncoord = data["coord"].shape[1] + if self.has_fparam >= 0: + data["fparam"] = self.load_data(set_name, "fparam", [nframe, -1]) + if self.has_fparam == 0 : + self.has_fparam = data["fparam"].shape[1] + else : + assert self.has_fparam == data["fparam"].shape[1] + if self.has_aparam >= 0: + data["aparam"] = self.load_data(set_name, "aparam", [nframe, -1]) + if self.has_aparam == 0 : + self.has_aparam = data["aparam"].shape[1] // (ncoord//3) + else : + assert self.has_aparam == data["aparam"].shape[1] // (ncoord//3) + data["prop_c"] = np.zeros(5) + data["prop_c"][0], data["energy"], data["prop_c"][3], data["atom_ener"] \ + = self.load_energy (set_name, nframe, ncoord // 3, "energy", "atom_ener") + data["prop_c"][1], data["force"] = self.load_data(set_name, "force", [nframe, ncoord], False) + data["prop_c"][2], data["virial"] = self.load_data(set_name, "virial", [nframe, 9], False) + data["prop_c"][4], data["atom_pref"] = self.load_data(set_name, "atom_pref", [nframe, ncoord//3], False) + data["atom_pref"] = np.repeat(data["atom_pref"], 3, axis=1) + # shuffle data + if shuffle: + idx = np.arange (nframe) + dp_random.shuffle(idx) + for ii in data: + if ii != "prop_c": + data[ii] = data[ii][idx] + data["type"] = np.tile (self.atom_type, (nframe, 1)) + # sort according to type + for ii in ["type", "atom_ener"]: + data[ii] = data[ii][:, self.idx_map] + for ii in ["coord", "force", "atom_pref"]: + data[ii] = data[ii][:, self.idx3_map] + return data + + def load_batch_set (self, + set_name) : + self.batch_set = self.load_set(set_name, True) + self.reset_iter () + + def load_test_set (self, + set_name, + shuffle_test) : + self.test_set = self.load_set(set_name, shuffle_test) + + def reset_iter (self) : + self.iterator = 0 + self.set_count += 1 + + def get_set(self, data, idx = None) : + new_data = {} + for ii in data: + dd = data[ii] + if ii == "prop_c": + new_data[ii] = dd.astype(np.float32) + else: + if idx is not None: + dd = dd[idx] + if ii == "type": + new_data[ii] = dd + else: + new_data[ii] = dd.astype(GLOBAL_NP_FLOAT_PRECISION) + return new_data + + def get_test (self) : + """ + returned property prefector [4] in order: + energy, force, virial, atom_ener + """ + return self.get_set(self.test_set) + + def get_batch (self, + batch_size) : + """ + returned property prefector [4] in order: + energy, force, virial, atom_ener + """ + set_size = self.batch_set["energy"].shape[0] + # assert (batch_size <= set_size), "batch size should be no more than set size" + if self.iterator + batch_size > set_size : + self.load_batch_set (self.train_dirs[self.set_count % self.get_numb_set()]) + set_size = self.batch_set["energy"].shape[0] + # print ("%d %d %d" % (self.iterator, self.iterator + batch_size, set_size)) + iterator_1 = self.iterator + batch_size + if iterator_1 >= set_size : + iterator_1 = set_size + idx = np.arange (self.iterator, iterator_1) + self.iterator += batch_size + return self.get_set(self.batch_set, idx) + + def get_natoms (self) : + sample_type = self.batch_set["type"][0] + natoms = len(sample_type) + return natoms + + def get_natoms_2 (self, ntypes) : + sample_type = self.batch_set["type"][0] + natoms = len(sample_type) + natoms_vec = np.zeros (ntypes).astype(int) + for ii in range (ntypes) : + natoms_vec[ii] = np.count_nonzero(sample_type == ii) + return natoms, natoms_vec + + def get_natoms_vec (self, ntypes) : + natoms, natoms_vec = self.get_natoms_2 (ntypes) + tmp = [natoms, natoms] + tmp = np.append (tmp, natoms_vec) + return tmp.astype(np.int32) + + def set_numb_batch (self, + batch_size) : + return self.batch_set["energy"].shape[0] // batch_size + + def get_sys_numb_batch (self, batch_size) : + return self.set_numb_batch(batch_size) * self.get_numb_set() + + def get_ener (self) : + return self.eavg + + def numb_fparam(self) : + return self.has_fparam + + def numb_aparam(self) : + return self.has_aparam + + +class DataSystem (object) : + """ + Outdated class for the data systems. + .. deprecated:: 2.0.0 + This class is not maintained any more. + """ + def __init__ (self, + systems, + set_prefix, + batch_size, + test_size, + rcut, + run_opt = None) : + self.system_dirs = systems + self.nsystems = len(self.system_dirs) + self.batch_size = batch_size + if isinstance(self.batch_size, int) : + self.batch_size = self.batch_size * np.ones(self.nsystems, dtype=int) + assert(isinstance(self.batch_size, (list,np.ndarray))) + assert(len(self.batch_size) == self.nsystems) + self.data_systems = [] + self.ntypes = [] + self.natoms = [] + self.natoms_vec = [] + self.nbatches = [] + for ii in self.system_dirs : + self.data_systems.append(DataSets(ii, set_prefix)) + sys_all_types = np.loadtxt(os.path.join(ii, "type.raw")).astype(int) + self.ntypes.append(np.max(sys_all_types) + 1) + self.sys_ntypes = max(self.ntypes) + type_map = [] + for ii in range(self.nsystems) : + self.natoms.append(self.data_systems[ii].get_natoms()) + self.natoms_vec.append(self.data_systems[ii].get_natoms_vec(self.sys_ntypes).astype(int)) + self.nbatches.append(self.data_systems[ii].get_sys_numb_batch(self.batch_size[ii])) + type_map.append(self.data_systems[ii].get_type_map()) + self.type_map = self.check_type_map_consistency(type_map) + + # check frame parameters + has_fparam = [ii.numb_fparam() for ii in self.data_systems] + for ii in has_fparam : + if ii != has_fparam[0] : + raise RuntimeError("if any system has frame parameter, then all systems should have the same number of frame parameter") + self.has_fparam = has_fparam[0] + + # check the size of data if they satisfy the requirement of batch and test + for ii in range(self.nsystems) : + chk_ret = self.data_systems[ii].check_batch_size(self.batch_size[ii]) + if chk_ret is not None : + raise RuntimeError ("system %s required batch size %d is larger than the size %d of the dataset %s" % \ + (self.system_dirs[ii], self.batch_size[ii], chk_ret[1], chk_ret[0])) + chk_ret = self.data_systems[ii].check_test_size(test_size) + if chk_ret is not None : + print("WARNNING: system %s required test size %d is larger than the size %d of the dataset %s" % \ + (self.system_dirs[ii], test_size, chk_ret[1], chk_ret[0])) + + if run_opt is not None: + self.print_summary(run_opt) + + self.prob_nbatches = [ float(i) for i in self.nbatches] / np.sum(self.nbatches) + + self.test_data = collections.defaultdict(list) + self.default_mesh = [] + for ii in range(self.nsystems) : + test_system_data = self.data_systems[ii].get_test () + for nn in test_system_data: + self.test_data[nn].append(test_system_data[nn]) + cell_size = np.max (rcut) + avg_box = np.average (test_system_data["box"], axis = 0) + avg_box = np.reshape (avg_box, [3,3]) + ncell = (np.linalg.norm(avg_box, axis=1)/ cell_size).astype(np.int32) + ncell[ncell < 2] = 2 + default_mesh = np.zeros (6, dtype = np.int32) + default_mesh[3:6] = ncell + self.default_mesh.append(default_mesh) + self.pick_idx = 0 + + + def check_type_map_consistency(self, type_map_list): + ret = [] + for ii in type_map_list: + if ii is not None: + min_len = min([len(ii), len(ret)]) + for idx in range(min_len) : + if ii[idx] != ret[idx] : + raise RuntimeError('inconsistent type map: %s %s' % (str(ret), str(ii))) + if len(ii) > len(ret) : + ret = ii + return ret + + + def get_type_map(self): + return self.type_map + + + def format_name_length(self, name, width) : + if len(name) <= width: + return '{: >{}}'.format(name, width) + else : + name = name[-(width-3):] + name = '-- ' + name + return name + + def print_summary(self) : + tmp_msg = "" + # width 65 + sys_width = 42 + tmp_msg += "---Summary of DataSystem-----------------------------------------\n" + tmp_msg += "find %d system(s):\n" % self.nsystems + tmp_msg += "%s " % self.format_name_length('system', sys_width) + tmp_msg += "%s %s %s\n" % ('natoms', 'bch_sz', 'n_bch') + for ii in range(self.nsystems) : + tmp_msg += ("%s %6d %6d %5d\n" % + (self.format_name_length(self.system_dirs[ii], sys_width), + self.natoms[ii], + self.batch_size[ii], + self.nbatches[ii]) ) + tmp_msg += "-----------------------------------------------------------------\n" + #log.info(tmp_msg) + + def compute_energy_shift(self) : + sys_ener = np.array([]) + for ss in self.data_systems : + sys_ener = np.append(sys_ener, ss.get_ener()) + sys_tynatom = np.array(self.natoms_vec, dtype = float) + sys_tynatom = np.reshape(sys_tynatom, [self.nsystems,-1]) + sys_tynatom = sys_tynatom[:,2:] + energy_shift,resd,rank,s_value \ + = np.linalg.lstsq(sys_tynatom, sys_ener, rcond = 1e-3) + return energy_shift + + def process_sys_weights(self, sys_weights) : + sys_weights = np.array(sys_weights) + type_filter = sys_weights >= 0 + assigned_sum_prob = np.sum(type_filter * sys_weights) + assert assigned_sum_prob <= 1, "the sum of assigned probability should be less than 1" + rest_sum_prob = 1. - assigned_sum_prob + rest_nbatch = (1 - type_filter) * self.nbatches + rest_prob = rest_sum_prob * rest_nbatch / np.sum(rest_nbatch) + ret_prob = rest_prob + type_filter * sys_weights + assert np.sum(ret_prob) == 1, "sum of probs should be 1" + return ret_prob + + def get_batch (self, + sys_idx = None, + sys_weights = None, + style = "prob_sys_size") : + if sys_idx is not None : + self.pick_idx = sys_idx + else : + if sys_weights is None : + if style == "prob_sys_size" : + prob = self.prob_nbatches + elif style == "prob_uniform" : + prob = None + else : + raise RuntimeError("unkown get_batch style") + else : + prob = self.process_sys_weights(sys_weights) + self.pick_idx = dp_random.choice(np.arange(self.nsystems), p=prob) + b_data = self.data_systems[self.pick_idx].get_batch(self.batch_size[self.pick_idx]) + b_data["natoms_vec"] = self.natoms_vec[self.pick_idx] + b_data["default_mesh"] = self.default_mesh[self.pick_idx] + return b_data + + def get_test (self, + sys_idx = None) : + if sys_idx is not None : + idx = sys_idx + else : + idx = self.pick_idx + test_system_data = {} + for nn in self.test_data: + test_system_data[nn] = self.test_data[nn][idx] + test_system_data["natoms_vec"] = self.natoms_vec[idx] + test_system_data["default_mesh"] = self.default_mesh[idx] + return test_system_data + + def get_nbatches (self) : + return self.nbatches + + def get_ntypes (self) : + return self.sys_ntypes + + def get_nsystems (self) : + return self.nsystems + + def get_sys (self, sys_idx) : + return self.data_systems[sys_idx] + + def get_batch_size(self) : + return self.batch_size + + def numb_fparam(self) : + return self.has_fparam diff --git a/source/tests/finetune/data/set.000/box.npy b/source/tests/finetune/data/set.000/box.npy new file mode 100644 index 0000000000..95a3ab9fdf Binary files /dev/null and b/source/tests/finetune/data/set.000/box.npy differ diff --git a/source/tests/finetune/data/set.000/coord.npy b/source/tests/finetune/data/set.000/coord.npy new file mode 100644 index 0000000000..02bc329da2 Binary files /dev/null and b/source/tests/finetune/data/set.000/coord.npy differ diff --git a/source/tests/finetune/data/set.000/energy.npy b/source/tests/finetune/data/set.000/energy.npy new file mode 100644 index 0000000000..f94e57291a Binary files /dev/null and b/source/tests/finetune/data/set.000/energy.npy differ diff --git a/source/tests/finetune/data/set.000/force.npy b/source/tests/finetune/data/set.000/force.npy new file mode 100644 index 0000000000..c2cf133d95 Binary files /dev/null and b/source/tests/finetune/data/set.000/force.npy differ diff --git a/source/tests/finetune/data/type.raw b/source/tests/finetune/data/type.raw new file mode 100644 index 0000000000..97e8fdfcf8 --- /dev/null +++ b/source/tests/finetune/data/type.raw @@ -0,0 +1,192 @@ +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 diff --git a/source/tests/finetune/data/type_map.raw b/source/tests/finetune/data/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/source/tests/finetune/data/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/source/tests/finetune/data_mixed_type/set.000/box.npy b/source/tests/finetune/data_mixed_type/set.000/box.npy new file mode 100644 index 0000000000..95a3ab9fdf Binary files /dev/null and b/source/tests/finetune/data_mixed_type/set.000/box.npy differ diff --git a/source/tests/finetune/data_mixed_type/set.000/coord.npy b/source/tests/finetune/data_mixed_type/set.000/coord.npy new file mode 100644 index 0000000000..02bc329da2 Binary files /dev/null and b/source/tests/finetune/data_mixed_type/set.000/coord.npy differ diff --git a/source/tests/finetune/data_mixed_type/set.000/energy.npy b/source/tests/finetune/data_mixed_type/set.000/energy.npy new file mode 100644 index 0000000000..f94e57291a Binary files /dev/null and b/source/tests/finetune/data_mixed_type/set.000/energy.npy differ diff --git a/source/tests/finetune/data_mixed_type/set.000/force.npy b/source/tests/finetune/data_mixed_type/set.000/force.npy new file mode 100644 index 0000000000..c2cf133d95 Binary files /dev/null and b/source/tests/finetune/data_mixed_type/set.000/force.npy differ diff --git a/source/tests/finetune/data_mixed_type/set.000/real_atom_types.npy b/source/tests/finetune/data_mixed_type/set.000/real_atom_types.npy new file mode 100644 index 0000000000..805e403c80 Binary files /dev/null and b/source/tests/finetune/data_mixed_type/set.000/real_atom_types.npy differ diff --git a/source/tests/finetune/data_mixed_type/type.raw b/source/tests/finetune/data_mixed_type/type.raw new file mode 100644 index 0000000000..d918d211c4 --- /dev/null +++ b/source/tests/finetune/data_mixed_type/type.raw @@ -0,0 +1,192 @@ +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 diff --git a/source/tests/finetune/data_mixed_type/type_map.raw b/source/tests/finetune/data_mixed_type/type_map.raw new file mode 100644 index 0000000000..e900768b1d --- /dev/null +++ b/source/tests/finetune/data_mixed_type/type_map.raw @@ -0,0 +1,2 @@ +O +H diff --git a/source/tests/finetune/input_finetune.json b/source/tests/finetune/input_finetune.json new file mode 100644 index 0000000000..22d878fcf0 --- /dev/null +++ b/source/tests/finetune/input_finetune.json @@ -0,0 +1,52 @@ +{ + "_comment": " model parameters", + "model": { +"type_embedding": {"trainable": false}, +"type_map": ["O", "H"], +"descriptor" :{"_comment": " that's all"}, +"fitting_net" : {"_comment": " that's all"}, +"_comment": " that's all" + }, + + "learning_rate" :{ +"type": "exp", +"decay_steps": 5000, +"start_lr": 0.001, +"stop_lr": 3.51e-8, +"_comment": "that's all" + }, + + "loss" :{ +"type": "ener", +"start_pref_e": 0.02, +"limit_pref_e": 1, +"start_pref_f": 1000, +"limit_pref_f": 1, +"start_pref_v": 1, +"limit_pref_v": 1, +"_comment": " that's all" + }, + + "training" : { +"training_data": { + "systems": ["finetune/data"], + "batch_size": "auto", + "_comment": "that's all" +}, +"validation_data":{ + "systems": ["finetune/data"], + "batch_size": 1, + "numb_btch": 3, + "_comment": "that's all" +}, +"numb_steps": 0, +"seed": 10, +"disp_file": "lcurve.out", +"disp_freq": 1, +"save_freq": 1, +"_comment": "that's all" + }, + + "_comment": "that's all" +} + diff --git a/source/tests/finetune/input_pretrain.json b/source/tests/finetune/input_pretrain.json new file mode 100644 index 0000000000..c448eab43f --- /dev/null +++ b/source/tests/finetune/input_pretrain.json @@ -0,0 +1,70 @@ +{ + "_comment": " model parameters", + "model": { +"type_map": ["H", "X1", "X2", "O"], +"descriptor" :{ + "type": "se_atten", + "sel": 120, + "rcut_smth": 0.50, + "rcut": 6.00, + "neuron": [4, 8, 16], + "resnet_dt": false, + "axis_neuron": 16, + "attn": 128, + "attn_layer": 2, + "attn_dotr": true, + "attn_mask": false, + "seed": 1, + "_comment": " that's all" +}, +"fitting_net" : { + "neuron": [20, 20, 20], + "resnet_dt": true, + "seed": 1, + "_comment": " that's all" +}, +"_comment": " that's all" + }, + + "learning_rate" :{ +"type": "exp", +"decay_steps": 5000, +"start_lr": 0.001, +"stop_lr": 3.51e-8, +"_comment": "that's all" + }, + + "loss" :{ +"type": "ener", +"start_pref_e": 0.02, +"limit_pref_e": 1, +"start_pref_f": 1000, +"limit_pref_f": 1, +"start_pref_v": 1, +"limit_pref_v": 1, +"_comment": " that's all" + }, + + "training" : { +"training_data": { + "systems": ["finetune/data"], + "batch_size": "auto", + "_comment": "that's all" +}, +"validation_data":{ + "systems": ["finetune/data"], + "batch_size": 1, + "numb_btch": 3, + "_comment": "that's all" +}, +"numb_steps": 1, +"seed": 10, +"disp_file": "lcurve.out", +"disp_freq": 1, +"save_freq": 1, +"_comment": "that's all" + }, + + "_comment": "that's all" +} + diff --git a/source/tests/infer/in.test b/source/tests/infer/in.test new file mode 100644 index 0000000000..f647c1b132 --- /dev/null +++ b/source/tests/infer/in.test @@ -0,0 +1,22 @@ +# test cibuildwheel + +units metal +boundary p p p +atom_style atomic + +neighbor 2.0 bin +neigh_modify every 10 delay 0 check no + +read_data ../../../examples/water/lmp/water.lmp +mass 1 16 +mass 2 2 + +pair_style deepmd deep_pot.pb +pair_coeff * * + +velocity all create 330.0 23456789 + +fix 1 all nve +timestep 0.0005 + +run 1 diff --git a/source/tests/infer/sea_012.pbtxt b/source/tests/infer/sea_012.pbtxt new file mode 100644 index 0000000000..4be031a4c7 --- /dev/null +++ b/source/tests/infer/sea_012.pbtxt @@ -0,0 +1,13409 @@ +node { + name: "t_avg" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 2 + } + dim { + size: 8 + } + } + tensor_content: "=jt\221\306\201\346?\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=jt\221\306\201\346?\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\370\005&\t\377\265\352?\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\370\005&\t\377\265\352?\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "t_avg/read" + op: "Identity" + input: "t_avg" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@t_avg" + } + } + } +} +node { + name: "t_std" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 2 + } + dim { + size: 8 + } + } + tensor_content: "\007~\223\256\265w\325?;e!U\261\307\334?;e!U\261\307\334?;e!U\261\307\334?\007~\223\256\265w\325?;e!U\261\307\334?;e!U\261\307\334?;e!U\261\307\334?\207\031\275\035!?\310?UH\363[\260\234\337?UH\363[\260\234\337?UH\363[\260\234\337?\207\031\275\035!?\310?UH\363[\260\234\337?UH\363[\260\234\337?UH\363[\260\234\337?" + } + } + } +} +node { + name: "t_std/read" + op: "Identity" + input: "t_std" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@t_std" + } + } + } +} +node { + name: "t_rcut" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + } + double_val: 6.0 + } + } + } +} +node { + name: "t_ntypes" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "t_coord" + op: "Placeholder" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "shape" + value { + shape { + dim { + size: -1 + } + } + } + } +} +node { + name: "t_type" + op: "Placeholder" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "shape" + value { + shape { + dim { + size: -1 + } + } + } + } +} +node { + name: "t_natoms" + op: "Placeholder" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "shape" + value { + shape { + dim { + size: 4 + } + } + } + } +} +node { + name: "t_box" + op: "Placeholder" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "shape" + value { + shape { + dim { + size: -1 + } + dim { + size: 9 + } + } + } + } +} +node { + name: "t_mesh" + op: "Placeholder" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "shape" + value { + shape { + dim { + size: -1 + } + } + } + } +} +node { + name: "strided_slice/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 2 + } + } + } +} +node { + name: "strided_slice/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice/stack" + input: "strided_slice/stack_1" + input: "strided_slice/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "mul/y" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 3 + } + } + } +} +node { + name: "mul" + op: "Mul" + input: "strided_slice" + input: "mul/y" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "Reshape/shape/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: -1 + } + } + } +} +node { + name: "Reshape/shape" + op: "Pack" + input: "Reshape/shape/0" + input: "mul" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "Reshape" + op: "Reshape" + input: "t_coord" + input: "Reshape/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "strided_slice_1/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_1/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 2 + } + } + } +} +node { + name: "strided_slice_1/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_1" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_1/stack" + input: "strided_slice_1/stack_1" + input: "strided_slice_1/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "Reshape_1/shape/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: -1 + } + } + } +} +node { + name: "Reshape_1/shape" + op: "Pack" + input: "Reshape_1/shape/0" + input: "strided_slice_1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "Reshape_1" + op: "Reshape" + input: "t_type" + input: "Reshape_1/shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DescrptNorot" + op: "DescrptNorot" + input: "Reshape" + input: "Reshape_1" + input: "t_natoms" + input: "t_box" + input: "t_mesh" + input: "t_avg/read" + input: "t_std/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "rcut_a" + value { + f: -1.0 + } + } + attr { + key: "rcut_r" + value { + f: 6.0 + } + } + attr { + key: "rcut_r_smth" + value { + f: 5.800000190734863 + } + } + attr { + key: "sel_a" + value { + list { + i: 1 + i: 1 + } + } + } + attr { + key: "sel_r" + value { + list { + i: 0 + i: 0 + } + } + } +} +node { + name: "Reshape_2/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\010\000\000\000" + } + } + } +} +node { + name: "Reshape_2" + op: "Reshape" + input: "DescrptNorot" + input: "Reshape_2/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "strided_slice_2/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "strided_slice_2/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_2/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_2" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_2/stack" + input: "strided_slice_2/stack_1" + input: "strided_slice_2/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "mul_1/x" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 8 + } + } + } +} +node { + name: "mul_1" + op: "Mul" + input: "mul_1/x" + input: "strided_slice_2" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "Reshape_3/shape/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: -1 + } + } + } +} +node { + name: "Reshape_3/shape" + op: "Pack" + input: "Reshape_3/shape/0" + input: "mul_1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "Reshape_3" + op: "Reshape" + input: "Reshape_2" + input: "Reshape_3/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "strided_slice_3/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 2 + } + } + } +} +node { + name: "strided_slice_3/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 3 + } + } + } +} +node { + name: "strided_slice_3/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_3" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_3/stack" + input: "strided_slice_3/stack_1" + input: "strided_slice_3/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "mul_2/y" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 8 + } + } + } +} +node { + name: "mul_2" + op: "Mul" + input: "strided_slice_3" + input: "mul_2/y" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "Slice/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "Slice/size/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: -1 + } + } + } +} +node { + name: "Slice/size" + op: "Pack" + input: "Slice/size/0" + input: "mul_2" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "Slice" + op: "Slice" + input: "Reshape_3" + input: "Slice/begin" + input: "Slice/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "Reshape_4/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\010\000\000\000" + } + } + } +} +node { + name: "Reshape_4" + op: "Reshape" + input: "Slice" + input: "Reshape_4/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "strided_slice_4/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 2 + } + } + } +} +node { + name: "strided_slice_4/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 3 + } + } + } +} +node { + name: "strided_slice_4/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_4" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_4/stack" + input: "strided_slice_4/stack_1" + input: "strided_slice_4/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "add/x" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 0 + } + } + } +} +node { + name: "add" + op: "Add" + input: "add/x" + input: "strided_slice_4" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_0/Slice/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice" + op: "Slice" + input: "Reshape_4" + input: "DS_layer_type_0/Slice/begin" + input: "DS_layer_type_0/Slice/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/Reshape/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Reshape" + op: "Reshape" + input: "DS_layer_type_0/Slice" + input: "DS_layer_type_0/Reshape/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_0/Slice_1/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice_1/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice_1" + op: "Slice" + input: "DS_layer_type_0/Reshape" + input: "DS_layer_type_0/Slice_1/begin" + input: "DS_layer_type_0/Slice_1/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/Reshape_1/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Reshape_1" + op: "Reshape" + input: "DS_layer_type_0/Slice_1" + input: "DS_layer_type_0/Reshape_1/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_0/matrix_1_0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: -0.5929978920085608 + } + } + } +} +node { + name: "DS_layer_type_0/matrix_1_0/read" + op: "Identity" + input: "DS_layer_type_0/matrix_1_0" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@DS_layer_type_0/matrix_1_0" + } + } + } +} +node { + name: "DS_layer_type_0/bias_1_0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: 0.9983645075733464 + } + } + } +} +node { + name: "DS_layer_type_0/bias_1_0/read" + op: "Identity" + input: "DS_layer_type_0/bias_1_0" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@DS_layer_type_0/bias_1_0" + } + } + } +} +node { + name: "DS_layer_type_0/MatMul" + op: "MatMul" + input: "DS_layer_type_0/Reshape_1" + input: "DS_layer_type_0/matrix_1_0/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: false + } + } +} +node { + name: "DS_layer_type_0/add" + op: "Add" + input: "DS_layer_type_0/MatMul" + input: "DS_layer_type_0/bias_1_0/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/Tanh" + op: "Tanh" + input: "DS_layer_type_0/add" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/add_1" + op: "Add" + input: "DS_layer_type_0/Reshape_1" + input: "DS_layer_type_0/Tanh" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/Reshape_2/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\377\377\377\377\001\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Reshape_2" + op: "Reshape" + input: "DS_layer_type_0/add_1" + input: "DS_layer_type_0/Reshape_2/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_0/Slice_2/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice_2/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice_2" + op: "Slice" + input: "Reshape_4" + input: "DS_layer_type_0/Slice_2/begin" + input: "DS_layer_type_0/Slice_2/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/Reshape_3/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Reshape_3" + op: "Reshape" + input: "DS_layer_type_0/Slice_2" + input: "DS_layer_type_0/Reshape_3/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_0/Slice_3/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice_3/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice_3" + op: "Slice" + input: "DS_layer_type_0/Reshape_3" + input: "DS_layer_type_0/Slice_3/begin" + input: "DS_layer_type_0/Slice_3/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/Reshape_4/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Reshape_4" + op: "Reshape" + input: "DS_layer_type_0/Slice_3" + input: "DS_layer_type_0/Reshape_4/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_0/matrix_1_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: 0.18976932648679823 + } + } + } +} +node { + name: "DS_layer_type_0/matrix_1_1/read" + op: "Identity" + input: "DS_layer_type_0/matrix_1_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@DS_layer_type_0/matrix_1_1" + } + } + } +} +node { + name: "DS_layer_type_0/bias_1_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: -0.387826139590999 + } + } + } +} +node { + name: "DS_layer_type_0/bias_1_1/read" + op: "Identity" + input: "DS_layer_type_0/bias_1_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@DS_layer_type_0/bias_1_1" + } + } + } +} +node { + name: "DS_layer_type_0/MatMul_1" + op: "MatMul" + input: "DS_layer_type_0/Reshape_4" + input: "DS_layer_type_0/matrix_1_1/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: false + } + } +} +node { + name: "DS_layer_type_0/add_2" + op: "Add" + input: "DS_layer_type_0/MatMul_1" + input: "DS_layer_type_0/bias_1_1/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/Tanh_1" + op: "Tanh" + input: "DS_layer_type_0/add_2" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/add_3" + op: "Add" + input: "DS_layer_type_0/Reshape_4" + input: "DS_layer_type_0/Tanh_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/Reshape_5/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\377\377\377\377\001\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Reshape_5" + op: "Reshape" + input: "DS_layer_type_0/add_3" + input: "DS_layer_type_0/Reshape_5/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_0/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "DS_layer_type_0/concat" + op: "ConcatV2" + input: "DS_layer_type_0/Reshape_2" + input: "DS_layer_type_0/Reshape_5" + input: "DS_layer_type_0/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_0/Reshape_6/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\377\377\377\377\002\000\000\000\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Reshape_6" + op: "Reshape" + input: "Reshape_4" + input: "DS_layer_type_0/Reshape_6/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_0/MatMul_2" + op: "BatchMatMulV2" + input: "DS_layer_type_0/Reshape_6" + input: "DS_layer_type_0/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: true + } + } + attr { + key: "adj_y" + value { + b: false + } + } +} +node { + name: "DS_layer_type_0/mul/y" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + } + double_val: 0.5 + } + } + } +} +node { + name: "DS_layer_type_0/mul" + op: "Mul" + input: "DS_layer_type_0/MatMul_2" + input: "DS_layer_type_0/mul/y" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/Slice_4/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\000\000\000\000\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice_4/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\377\377\377\377\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Slice_4" + op: "Slice" + input: "DS_layer_type_0/mul" + input: "DS_layer_type_0/Slice_4/begin" + input: "DS_layer_type_0/Slice_4/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_0/MatMul_3" + op: "BatchMatMulV2" + input: "DS_layer_type_0/mul" + input: "DS_layer_type_0/Slice_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: true + } + } + attr { + key: "adj_y" + value { + b: false + } + } +} +node { + name: "DS_layer_type_0/Reshape_7/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_0/Reshape_7" + op: "Reshape" + input: "DS_layer_type_0/MatMul_3" + input: "DS_layer_type_0/Reshape_7/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "layer_0_type_0/matrix" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: 0.14726844145773643 + } + } + } +} +node { + name: "layer_0_type_0/matrix/read" + op: "Identity" + input: "layer_0_type_0/matrix" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@layer_0_type_0/matrix" + } + } + } +} +node { + name: "layer_0_type_0/bias" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + } + double_val: -0.36511124387384836 + } + } + } +} +node { + name: "layer_0_type_0/bias/read" + op: "Identity" + input: "layer_0_type_0/bias" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@layer_0_type_0/bias" + } + } + } +} +node { + name: "layer_0_type_0/MatMul" + op: "MatMul" + input: "DS_layer_type_0/Reshape_7" + input: "layer_0_type_0/matrix/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: false + } + } +} +node { + name: "layer_0_type_0/add" + op: "Add" + input: "layer_0_type_0/MatMul" + input: "layer_0_type_0/bias/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "Tanh" + op: "Tanh" + input: "layer_0_type_0/add" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "final_layer_type_0/matrix" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: 0.3939480642205348 + } + } + } +} +node { + name: "final_layer_type_0/matrix/read" + op: "Identity" + input: "final_layer_type_0/matrix" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@final_layer_type_0/matrix" + } + } + } +} +node { + name: "final_layer_type_0/bias" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + } + double_val: -93.5768035239284 + } + } + } +} +node { + name: "final_layer_type_0/bias/read" + op: "Identity" + input: "final_layer_type_0/bias" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@final_layer_type_0/bias" + } + } + } +} +node { + name: "final_layer_type_0/MatMul" + op: "MatMul" + input: "Tanh" + input: "final_layer_type_0/matrix/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: false + } + } +} +node { + name: "final_layer_type_0/add" + op: "Add" + input: "final_layer_type_0/MatMul" + input: "final_layer_type_0/bias/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "strided_slice_5/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 2 + } + } + } +} +node { + name: "strided_slice_5/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 3 + } + } + } +} +node { + name: "strided_slice_5/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_5" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_5/stack" + input: "strided_slice_5/stack_1" + input: "strided_slice_5/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "Reshape_5/shape/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "Reshape_5/shape" + op: "Pack" + input: "Reshape_5/shape/0" + input: "strided_slice_5" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "Reshape_5" + op: "Reshape" + input: "final_layer_type_0/add" + input: "Reshape_5/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "mul_3/y" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 8 + } + } + } +} +node { + name: "mul_3" + op: "Mul" + input: "add" + input: "mul_3/y" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "strided_slice_6/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 3 + } + } + } +} +node { + name: "strided_slice_6/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 4 + } + } + } +} +node { + name: "strided_slice_6/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_6" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_6/stack" + input: "strided_slice_6/stack_1" + input: "strided_slice_6/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "mul_4/y" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 8 + } + } + } +} +node { + name: "mul_4" + op: "Mul" + input: "strided_slice_6" + input: "mul_4/y" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "Slice_1/begin/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 0 + } + } + } +} +node { + name: "Slice_1/begin" + op: "Pack" + input: "Slice_1/begin/0" + input: "mul_3" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "Slice_1/size/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: -1 + } + } + } +} +node { + name: "Slice_1/size" + op: "Pack" + input: "Slice_1/size/0" + input: "mul_4" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "Slice_1" + op: "Slice" + input: "Reshape_3" + input: "Slice_1/begin" + input: "Slice_1/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "Reshape_6/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\010\000\000\000" + } + } + } +} +node { + name: "Reshape_6" + op: "Reshape" + input: "Slice_1" + input: "Reshape_6/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_1/Slice/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice" + op: "Slice" + input: "Reshape_6" + input: "DS_layer_type_1/Slice/begin" + input: "DS_layer_type_1/Slice/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/Reshape/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Reshape" + op: "Reshape" + input: "DS_layer_type_1/Slice" + input: "DS_layer_type_1/Reshape/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_1/Slice_1/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice_1/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice_1" + op: "Slice" + input: "DS_layer_type_1/Reshape" + input: "DS_layer_type_1/Slice_1/begin" + input: "DS_layer_type_1/Slice_1/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/Reshape_1/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Reshape_1" + op: "Reshape" + input: "DS_layer_type_1/Slice_1" + input: "DS_layer_type_1/Reshape_1/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_1/matrix_1_0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: -0.17935075392063676 + } + } + } +} +node { + name: "DS_layer_type_1/matrix_1_0/read" + op: "Identity" + input: "DS_layer_type_1/matrix_1_0" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@DS_layer_type_1/matrix_1_0" + } + } + } +} +node { + name: "DS_layer_type_1/bias_1_0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: -0.5601597468396246 + } + } + } +} +node { + name: "DS_layer_type_1/bias_1_0/read" + op: "Identity" + input: "DS_layer_type_1/bias_1_0" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@DS_layer_type_1/bias_1_0" + } + } + } +} +node { + name: "DS_layer_type_1/MatMul" + op: "MatMul" + input: "DS_layer_type_1/Reshape_1" + input: "DS_layer_type_1/matrix_1_0/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: false + } + } +} +node { + name: "DS_layer_type_1/add" + op: "Add" + input: "DS_layer_type_1/MatMul" + input: "DS_layer_type_1/bias_1_0/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/Tanh" + op: "Tanh" + input: "DS_layer_type_1/add" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/add_1" + op: "Add" + input: "DS_layer_type_1/Reshape_1" + input: "DS_layer_type_1/Tanh" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/Reshape_2/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\377\377\377\377\001\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Reshape_2" + op: "Reshape" + input: "DS_layer_type_1/add_1" + input: "DS_layer_type_1/Reshape_2/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_1/Slice_2/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice_2/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice_2" + op: "Slice" + input: "Reshape_6" + input: "DS_layer_type_1/Slice_2/begin" + input: "DS_layer_type_1/Slice_2/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/Reshape_3/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Reshape_3" + op: "Reshape" + input: "DS_layer_type_1/Slice_2" + input: "DS_layer_type_1/Reshape_3/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_1/Slice_3/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice_3/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice_3" + op: "Slice" + input: "DS_layer_type_1/Reshape_3" + input: "DS_layer_type_1/Slice_3/begin" + input: "DS_layer_type_1/Slice_3/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/Reshape_4/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Reshape_4" + op: "Reshape" + input: "DS_layer_type_1/Slice_3" + input: "DS_layer_type_1/Reshape_4/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_1/matrix_1_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: 0.3205658142933548 + } + } + } +} +node { + name: "DS_layer_type_1/matrix_1_1/read" + op: "Identity" + input: "DS_layer_type_1/matrix_1_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@DS_layer_type_1/matrix_1_1" + } + } + } +} +node { + name: "DS_layer_type_1/bias_1_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: 0.12077221835391395 + } + } + } +} +node { + name: "DS_layer_type_1/bias_1_1/read" + op: "Identity" + input: "DS_layer_type_1/bias_1_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@DS_layer_type_1/bias_1_1" + } + } + } +} +node { + name: "DS_layer_type_1/MatMul_1" + op: "MatMul" + input: "DS_layer_type_1/Reshape_4" + input: "DS_layer_type_1/matrix_1_1/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: false + } + } +} +node { + name: "DS_layer_type_1/add_2" + op: "Add" + input: "DS_layer_type_1/MatMul_1" + input: "DS_layer_type_1/bias_1_1/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/Tanh_1" + op: "Tanh" + input: "DS_layer_type_1/add_2" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/add_3" + op: "Add" + input: "DS_layer_type_1/Reshape_4" + input: "DS_layer_type_1/Tanh_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/Reshape_5/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\377\377\377\377\001\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Reshape_5" + op: "Reshape" + input: "DS_layer_type_1/add_3" + input: "DS_layer_type_1/Reshape_5/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_1/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "DS_layer_type_1/concat" + op: "ConcatV2" + input: "DS_layer_type_1/Reshape_2" + input: "DS_layer_type_1/Reshape_5" + input: "DS_layer_type_1/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_1/Reshape_6/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\377\377\377\377\002\000\000\000\004\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Reshape_6" + op: "Reshape" + input: "Reshape_6" + input: "DS_layer_type_1/Reshape_6/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "DS_layer_type_1/MatMul_2" + op: "BatchMatMulV2" + input: "DS_layer_type_1/Reshape_6" + input: "DS_layer_type_1/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: true + } + } + attr { + key: "adj_y" + value { + b: false + } + } +} +node { + name: "DS_layer_type_1/mul/y" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + } + double_val: 0.5 + } + } + } +} +node { + name: "DS_layer_type_1/mul" + op: "Mul" + input: "DS_layer_type_1/MatMul_2" + input: "DS_layer_type_1/mul/y" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/Slice_4/begin" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\000\000\000\000\000\000\000\000\000\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice_4/size" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 3 + } + } + tensor_content: "\377\377\377\377\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Slice_4" + op: "Slice" + input: "DS_layer_type_1/mul" + input: "DS_layer_type_1/Slice_4/begin" + input: "DS_layer_type_1/Slice_4/size" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "DS_layer_type_1/MatMul_3" + op: "BatchMatMulV2" + input: "DS_layer_type_1/mul" + input: "DS_layer_type_1/Slice_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: true + } + } + attr { + key: "adj_y" + value { + b: false + } + } +} +node { + name: "DS_layer_type_1/Reshape_7/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\001\000\000\000" + } + } + } +} +node { + name: "DS_layer_type_1/Reshape_7" + op: "Reshape" + input: "DS_layer_type_1/MatMul_3" + input: "DS_layer_type_1/Reshape_7/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "layer_0_type_1/matrix" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: 0.1934560948696963 + } + } + } +} +node { + name: "layer_0_type_1/matrix/read" + op: "Identity" + input: "layer_0_type_1/matrix" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@layer_0_type_1/matrix" + } + } + } +} +node { + name: "layer_0_type_1/bias" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + } + double_val: -0.17107361582243172 + } + } + } +} +node { + name: "layer_0_type_1/bias/read" + op: "Identity" + input: "layer_0_type_1/bias" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@layer_0_type_1/bias" + } + } + } +} +node { + name: "layer_0_type_1/MatMul" + op: "MatMul" + input: "DS_layer_type_1/Reshape_7" + input: "layer_0_type_1/matrix/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: false + } + } +} +node { + name: "layer_0_type_1/add" + op: "Add" + input: "layer_0_type_1/MatMul" + input: "layer_0_type_1/bias/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "Tanh_1" + op: "Tanh" + input: "layer_0_type_1/add" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "final_layer_type_1/matrix" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + dim { + size: 1 + } + } + double_val: 0.3119468727172958 + } + } + } +} +node { + name: "final_layer_type_1/matrix/read" + op: "Identity" + input: "final_layer_type_1/matrix" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@final_layer_type_1/matrix" + } + } + } +} +node { + name: "final_layer_type_1/bias" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + dim { + size: 1 + } + } + double_val: -187.15053100832083 + } + } + } +} +node { + name: "final_layer_type_1/bias/read" + op: "Identity" + input: "final_layer_type_1/bias" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@final_layer_type_1/bias" + } + } + } +} +node { + name: "final_layer_type_1/MatMul" + op: "MatMul" + input: "Tanh_1" + input: "final_layer_type_1/matrix/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: false + } + } +} +node { + name: "final_layer_type_1/add" + op: "Add" + input: "final_layer_type_1/MatMul" + input: "final_layer_type_1/bias/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "strided_slice_8/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 3 + } + } + } +} +node { + name: "strided_slice_8/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 4 + } + } + } +} +node { + name: "strided_slice_8/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_8" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_8/stack" + input: "strided_slice_8/stack_1" + input: "strided_slice_8/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "Reshape_7/shape/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "Reshape_7/shape" + op: "Pack" + input: "Reshape_7/shape/0" + input: "strided_slice_8" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "Reshape_7" + op: "Reshape" + input: "final_layer_type_1/add" + input: "Reshape_7/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "concat" + op: "ConcatV2" + input: "Reshape_5" + input: "Reshape_7" + input: "concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "Reshape_8/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: -1 + } + } + } +} +node { + name: "Reshape_8" + op: "Reshape" + input: "concat" + input: "Reshape_8/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "strided_slice_9/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "strided_slice_9/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_9/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_9" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_9/stack" + input: "strided_slice_9/stack_1" + input: "strided_slice_9/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "atom_energy_test/shape/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: -1 + } + } + } +} +node { + name: "atom_energy_test/shape" + op: "Pack" + input: "atom_energy_test/shape/0" + input: "strided_slice_9" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "atom_energy_test" + op: "Reshape" + input: "Reshape_8" + input: "atom_energy_test/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "energy_test/reduction_indices" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "energy_test" + op: "Sum" + input: "atom_energy_test" + input: "energy_test/reduction_indices" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/Shape" + op: "Shape" + input: "Reshape_8" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/grad_ys_0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_DOUBLE + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_DOUBLE + tensor_shape { + } + double_val: 1.0 + } + } + } +} +node { + name: "gradients/Fill" + op: "Fill" + input: "gradients/Shape" + input: "gradients/grad_ys_0" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "index_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Reshape_8_grad/Shape" + op: "Shape" + input: "concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Reshape_8_grad/Reshape" + op: "Reshape" + input: "gradients/Fill" + input: "gradients/Reshape_8_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/concat_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/concat_grad/mod" + op: "FloorMod" + input: "concat/axis" + input: "gradients/concat_grad/Rank" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/concat_grad/ShapeN" + op: "ShapeN" + input: "Reshape_5" + input: "Reshape_7" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/concat_grad/ConcatOffset" + op: "ConcatOffset" + input: "gradients/concat_grad/mod" + input: "gradients/concat_grad/ShapeN" + input: "gradients/concat_grad/ShapeN:1" + attr { + key: "N" + value { + i: 2 + } + } +} +node { + name: "gradients/concat_grad/Slice" + op: "Slice" + input: "gradients/Reshape_8_grad/Reshape" + input: "gradients/concat_grad/ConcatOffset" + input: "gradients/concat_grad/ShapeN" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/concat_grad/Slice_1" + op: "Slice" + input: "gradients/Reshape_8_grad/Reshape" + input: "gradients/concat_grad/ConcatOffset:1" + input: "gradients/concat_grad/ShapeN:1" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/Reshape_5_grad/Shape" + op: "Shape" + input: "final_layer_type_0/add" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Reshape_5_grad/Reshape" + op: "Reshape" + input: "gradients/concat_grad/Slice" + input: "gradients/Reshape_5_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Reshape_7_grad/Shape" + op: "Shape" + input: "final_layer_type_1/add" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Reshape_7_grad/Reshape" + op: "Reshape" + input: "gradients/concat_grad/Slice_1" + input: "gradients/Reshape_7_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/final_layer_type_0/add_grad/Shape" + op: "Shape" + input: "final_layer_type_0/MatMul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/final_layer_type_0/add_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/final_layer_type_0/add_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/final_layer_type_0/add_grad/Shape" + input: "gradients/final_layer_type_0/add_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/final_layer_type_0/add_grad/Sum" + op: "Sum" + input: "gradients/Reshape_5_grad/Reshape" + input: "gradients/final_layer_type_0/add_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/final_layer_type_0/add_grad/Reshape" + op: "Reshape" + input: "gradients/final_layer_type_0/add_grad/Sum" + input: "gradients/final_layer_type_0/add_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/final_layer_type_1/add_grad/Shape" + op: "Shape" + input: "final_layer_type_1/MatMul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/final_layer_type_1/add_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/final_layer_type_1/add_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/final_layer_type_1/add_grad/Shape" + input: "gradients/final_layer_type_1/add_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/final_layer_type_1/add_grad/Sum" + op: "Sum" + input: "gradients/Reshape_7_grad/Reshape" + input: "gradients/final_layer_type_1/add_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/final_layer_type_1/add_grad/Reshape" + op: "Reshape" + input: "gradients/final_layer_type_1/add_grad/Sum" + input: "gradients/final_layer_type_1/add_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/final_layer_type_0/MatMul_grad/MatMul" + op: "MatMul" + input: "gradients/final_layer_type_0/add_grad/Reshape" + input: "final_layer_type_0/matrix/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: true + } + } +} +node { + name: "gradients/final_layer_type_1/MatMul_grad/MatMul" + op: "MatMul" + input: "gradients/final_layer_type_1/add_grad/Reshape" + input: "final_layer_type_1/matrix/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: true + } + } +} +node { + name: "gradients/Tanh_grad/TanhGrad" + op: "TanhGrad" + input: "Tanh" + input: "gradients/final_layer_type_0/MatMul_grad/MatMul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/Tanh_1_grad/TanhGrad" + op: "TanhGrad" + input: "Tanh_1" + input: "gradients/final_layer_type_1/MatMul_grad/MatMul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/layer_0_type_0/add_grad/Shape" + op: "Shape" + input: "layer_0_type_0/MatMul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/layer_0_type_0/add_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/layer_0_type_0/add_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/layer_0_type_0/add_grad/Shape" + input: "gradients/layer_0_type_0/add_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/layer_0_type_0/add_grad/Sum" + op: "Sum" + input: "gradients/Tanh_grad/TanhGrad" + input: "gradients/layer_0_type_0/add_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/layer_0_type_0/add_grad/Reshape" + op: "Reshape" + input: "gradients/layer_0_type_0/add_grad/Sum" + input: "gradients/layer_0_type_0/add_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/layer_0_type_1/add_grad/Shape" + op: "Shape" + input: "layer_0_type_1/MatMul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/layer_0_type_1/add_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/layer_0_type_1/add_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/layer_0_type_1/add_grad/Shape" + input: "gradients/layer_0_type_1/add_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/layer_0_type_1/add_grad/Sum" + op: "Sum" + input: "gradients/Tanh_1_grad/TanhGrad" + input: "gradients/layer_0_type_1/add_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/layer_0_type_1/add_grad/Reshape" + op: "Reshape" + input: "gradients/layer_0_type_1/add_grad/Sum" + input: "gradients/layer_0_type_1/add_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/layer_0_type_0/MatMul_grad/MatMul" + op: "MatMul" + input: "gradients/layer_0_type_0/add_grad/Reshape" + input: "layer_0_type_0/matrix/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: true + } + } +} +node { + name: "gradients/layer_0_type_1/MatMul_grad/MatMul" + op: "MatMul" + input: "gradients/layer_0_type_1/add_grad/Reshape" + input: "layer_0_type_1/matrix/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: true + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_7_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/MatMul_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_7_grad/Reshape" + op: "Reshape" + input: "gradients/layer_0_type_0/MatMul_grad/MatMul" + input: "gradients/DS_layer_type_0/Reshape_7_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_7_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/MatMul_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_7_grad/Reshape" + op: "Reshape" + input: "gradients/layer_0_type_1/MatMul_grad/MatMul" + input: "gradients/DS_layer_type_1/Reshape_7_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/MatMul" + op: "BatchMatMulV2" + input: "DS_layer_type_0/Slice_4" + input: "gradients/DS_layer_type_0/Reshape_7_grad/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: false + } + } + attr { + key: "adj_y" + value { + b: true + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/MatMul_1" + op: "BatchMatMulV2" + input: "DS_layer_type_0/mul" + input: "gradients/DS_layer_type_0/Reshape_7_grad/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: false + } + } + attr { + key: "adj_y" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/mul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_0/Slice_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: -2 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice" + op: "StridedSlice" + input: "gradients/DS_layer_type_0/MatMul_3_grad/Shape" + input: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice/stack" + input: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice/stack_1" + input: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 1 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice_1/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice_1/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: -2 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice_1/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice_1" + op: "StridedSlice" + input: "gradients/DS_layer_type_0/MatMul_3_grad/Shape_1" + input: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice_1/stack" + input: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice_1/stack_1" + input: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice_1/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 1 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice" + input: "gradients/DS_layer_type_0/MatMul_3_grad/strided_slice_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_0/MatMul_3_grad/MatMul" + input: "gradients/DS_layer_type_0/MatMul_3_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/MatMul_3_grad/Sum" + input: "gradients/DS_layer_type_0/MatMul_3_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/Sum_1" + op: "Sum" + input: "gradients/DS_layer_type_0/MatMul_3_grad/MatMul_1" + input: "gradients/DS_layer_type_0/MatMul_3_grad/BroadcastGradientArgs:1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_3_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_0/MatMul_3_grad/Sum_1" + input: "gradients/DS_layer_type_0/MatMul_3_grad/Shape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/MatMul" + op: "BatchMatMulV2" + input: "DS_layer_type_1/Slice_4" + input: "gradients/DS_layer_type_1/Reshape_7_grad/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: false + } + } + attr { + key: "adj_y" + value { + b: true + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/MatMul_1" + op: "BatchMatMulV2" + input: "DS_layer_type_1/mul" + input: "gradients/DS_layer_type_1/Reshape_7_grad/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: false + } + } + attr { + key: "adj_y" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/mul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_1/Slice_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: -2 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice" + op: "StridedSlice" + input: "gradients/DS_layer_type_1/MatMul_3_grad/Shape" + input: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice/stack" + input: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice/stack_1" + input: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 1 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice_1/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice_1/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: -2 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice_1/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice_1" + op: "StridedSlice" + input: "gradients/DS_layer_type_1/MatMul_3_grad/Shape_1" + input: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice_1/stack" + input: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice_1/stack_1" + input: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice_1/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 1 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice" + input: "gradients/DS_layer_type_1/MatMul_3_grad/strided_slice_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_1/MatMul_3_grad/MatMul" + input: "gradients/DS_layer_type_1/MatMul_3_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/MatMul_3_grad/Sum" + input: "gradients/DS_layer_type_1/MatMul_3_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/Sum_1" + op: "Sum" + input: "gradients/DS_layer_type_1/MatMul_3_grad/MatMul_1" + input: "gradients/DS_layer_type_1/MatMul_3_grad/BroadcastGradientArgs:1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_3_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_1/MatMul_3_grad/Sum_1" + input: "gradients/DS_layer_type_1/MatMul_3_grad/Shape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 3 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Slice_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_0/Slice_4_grad/Rank" + input: "gradients/DS_layer_type_0/Slice_4_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_0/Slice_4/begin" + input: "gradients/DS_layer_type_0/Slice_4_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_0/mul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_4_grad/Shape_1" + input: "gradients/DS_layer_type_0/Slice_4_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_4_grad/sub" + input: "DS_layer_type_0/Slice_4/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_0/Slice_4_grad/sub_1" + input: "gradients/DS_layer_type_0/Slice_4_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_0/Slice_4_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_4_grad/Reshape_1" + input: "gradients/DS_layer_type_0/Slice_4_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_4_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_0/MatMul_3_grad/Reshape_1" + input: "gradients/DS_layer_type_0/Slice_4_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 3 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Slice_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_1/Slice_4_grad/Rank" + input: "gradients/DS_layer_type_1/Slice_4_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_1/Slice_4/begin" + input: "gradients/DS_layer_type_1/Slice_4_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_1/mul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_4_grad/Shape_1" + input: "gradients/DS_layer_type_1/Slice_4_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_4_grad/sub" + input: "DS_layer_type_1/Slice_4/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_1/Slice_4_grad/sub_1" + input: "gradients/DS_layer_type_1/Slice_4_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_1/Slice_4_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_4_grad/Reshape_1" + input: "gradients/DS_layer_type_1/Slice_4_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_4_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_1/MatMul_3_grad/Reshape_1" + input: "gradients/DS_layer_type_1/Slice_4_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/AddN" + op: "AddN" + input: "gradients/DS_layer_type_0/MatMul_3_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_4_grad/Pad" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@gradients/DS_layer_type_0/MatMul_3_grad/Reshape" + } + } + } +} +node { + name: "gradients/DS_layer_type_0/mul_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/MatMul_2" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/mul_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + } + } + } + } + } +} +node { + name: "gradients/DS_layer_type_0/mul_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_0/mul_grad/Shape" + input: "gradients/DS_layer_type_0/mul_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/mul_grad/Mul" + op: "Mul" + input: "gradients/AddN" + input: "DS_layer_type_0/mul/y" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_0/mul_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_0/mul_grad/Mul" + input: "gradients/DS_layer_type_0/mul_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/mul_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/mul_grad/Sum" + input: "gradients/DS_layer_type_0/mul_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/AddN_1" + op: "AddN" + input: "gradients/DS_layer_type_1/MatMul_3_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_4_grad/Pad" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@gradients/DS_layer_type_1/MatMul_3_grad/Reshape" + } + } + } +} +node { + name: "gradients/DS_layer_type_1/mul_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/MatMul_2" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/mul_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + } + } + } + } + } +} +node { + name: "gradients/DS_layer_type_1/mul_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_1/mul_grad/Shape" + input: "gradients/DS_layer_type_1/mul_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/mul_grad/Mul" + op: "Mul" + input: "gradients/AddN_1" + input: "DS_layer_type_1/mul/y" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_1/mul_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_1/mul_grad/Mul" + input: "gradients/DS_layer_type_1/mul_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/mul_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/mul_grad/Sum" + input: "gradients/DS_layer_type_1/mul_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/MatMul" + op: "BatchMatMulV2" + input: "DS_layer_type_0/concat" + input: "gradients/DS_layer_type_0/mul_grad/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: false + } + } + attr { + key: "adj_y" + value { + b: true + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/MatMul_1" + op: "BatchMatMulV2" + input: "DS_layer_type_0/Reshape_6" + input: "gradients/DS_layer_type_0/mul_grad/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: false + } + } + attr { + key: "adj_y" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Reshape_6" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_0/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: -2 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice" + op: "StridedSlice" + input: "gradients/DS_layer_type_0/MatMul_2_grad/Shape" + input: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice/stack" + input: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice/stack_1" + input: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 1 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice_1/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice_1/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: -2 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice_1/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice_1" + op: "StridedSlice" + input: "gradients/DS_layer_type_0/MatMul_2_grad/Shape_1" + input: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice_1/stack" + input: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice_1/stack_1" + input: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice_1/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 1 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice" + input: "gradients/DS_layer_type_0/MatMul_2_grad/strided_slice_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_0/MatMul_2_grad/MatMul" + input: "gradients/DS_layer_type_0/MatMul_2_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/MatMul_2_grad/Sum" + input: "gradients/DS_layer_type_0/MatMul_2_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/Sum_1" + op: "Sum" + input: "gradients/DS_layer_type_0/MatMul_2_grad/MatMul_1" + input: "gradients/DS_layer_type_0/MatMul_2_grad/BroadcastGradientArgs:1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_2_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_0/MatMul_2_grad/Sum_1" + input: "gradients/DS_layer_type_0/MatMul_2_grad/Shape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/MatMul" + op: "BatchMatMulV2" + input: "DS_layer_type_1/concat" + input: "gradients/DS_layer_type_1/mul_grad/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: false + } + } + attr { + key: "adj_y" + value { + b: true + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/MatMul_1" + op: "BatchMatMulV2" + input: "DS_layer_type_1/Reshape_6" + input: "gradients/DS_layer_type_1/mul_grad/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "adj_x" + value { + b: false + } + } + attr { + key: "adj_y" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Reshape_6" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_1/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: -2 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice" + op: "StridedSlice" + input: "gradients/DS_layer_type_1/MatMul_2_grad/Shape" + input: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice/stack" + input: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice/stack_1" + input: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 1 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice_1/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice_1/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: -2 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice_1/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice_1" + op: "StridedSlice" + input: "gradients/DS_layer_type_1/MatMul_2_grad/Shape_1" + input: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice_1/stack" + input: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice_1/stack_1" + input: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice_1/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 1 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice" + input: "gradients/DS_layer_type_1/MatMul_2_grad/strided_slice_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_1/MatMul_2_grad/MatMul" + input: "gradients/DS_layer_type_1/MatMul_2_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/MatMul_2_grad/Sum" + input: "gradients/DS_layer_type_1/MatMul_2_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/Sum_1" + op: "Sum" + input: "gradients/DS_layer_type_1/MatMul_2_grad/MatMul_1" + input: "gradients/DS_layer_type_1/MatMul_2_grad/BroadcastGradientArgs:1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_2_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_1/MatMul_2_grad/Sum_1" + input: "gradients/DS_layer_type_1/MatMul_2_grad/Shape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_6_grad/Shape" + op: "Shape" + input: "Reshape_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_6_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/MatMul_2_grad/Reshape" + input: "gradients/DS_layer_type_0/Reshape_6_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/concat_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 3 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/concat_grad/mod" + op: "FloorMod" + input: "DS_layer_type_0/concat/axis" + input: "gradients/DS_layer_type_0/concat_grad/Rank" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/concat_grad/ShapeN" + op: "ShapeN" + input: "DS_layer_type_0/Reshape_2" + input: "DS_layer_type_0/Reshape_5" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/concat_grad/ConcatOffset" + op: "ConcatOffset" + input: "gradients/DS_layer_type_0/concat_grad/mod" + input: "gradients/DS_layer_type_0/concat_grad/ShapeN" + input: "gradients/DS_layer_type_0/concat_grad/ShapeN:1" + attr { + key: "N" + value { + i: 2 + } + } +} +node { + name: "gradients/DS_layer_type_0/concat_grad/Slice" + op: "Slice" + input: "gradients/DS_layer_type_0/MatMul_2_grad/Reshape_1" + input: "gradients/DS_layer_type_0/concat_grad/ConcatOffset" + input: "gradients/DS_layer_type_0/concat_grad/ShapeN" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_0/concat_grad/Slice_1" + op: "Slice" + input: "gradients/DS_layer_type_0/MatMul_2_grad/Reshape_1" + input: "gradients/DS_layer_type_0/concat_grad/ConcatOffset:1" + input: "gradients/DS_layer_type_0/concat_grad/ShapeN:1" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_6_grad/Shape" + op: "Shape" + input: "Reshape_6" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_6_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/MatMul_2_grad/Reshape" + input: "gradients/DS_layer_type_1/Reshape_6_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/concat_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 3 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/concat_grad/mod" + op: "FloorMod" + input: "DS_layer_type_1/concat/axis" + input: "gradients/DS_layer_type_1/concat_grad/Rank" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/concat_grad/ShapeN" + op: "ShapeN" + input: "DS_layer_type_1/Reshape_2" + input: "DS_layer_type_1/Reshape_5" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/concat_grad/ConcatOffset" + op: "ConcatOffset" + input: "gradients/DS_layer_type_1/concat_grad/mod" + input: "gradients/DS_layer_type_1/concat_grad/ShapeN" + input: "gradients/DS_layer_type_1/concat_grad/ShapeN:1" + attr { + key: "N" + value { + i: 2 + } + } +} +node { + name: "gradients/DS_layer_type_1/concat_grad/Slice" + op: "Slice" + input: "gradients/DS_layer_type_1/MatMul_2_grad/Reshape_1" + input: "gradients/DS_layer_type_1/concat_grad/ConcatOffset" + input: "gradients/DS_layer_type_1/concat_grad/ShapeN" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_1/concat_grad/Slice_1" + op: "Slice" + input: "gradients/DS_layer_type_1/MatMul_2_grad/Reshape_1" + input: "gradients/DS_layer_type_1/concat_grad/ConcatOffset:1" + input: "gradients/DS_layer_type_1/concat_grad/ShapeN:1" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_2_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/add_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_2_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/concat_grad/Slice" + input: "gradients/DS_layer_type_0/Reshape_2_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_5_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/add_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_5_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/concat_grad/Slice_1" + input: "gradients/DS_layer_type_0/Reshape_5_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_2_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/add_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_2_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/concat_grad/Slice" + input: "gradients/DS_layer_type_1/Reshape_2_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_5_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/add_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_5_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/concat_grad/Slice_1" + input: "gradients/DS_layer_type_1/Reshape_5_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_1_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Reshape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_1_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_0/Tanh" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_1_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_0/add_1_grad/Shape" + input: "gradients/DS_layer_type_0/add_1_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_1_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_0/Reshape_2_grad/Reshape" + input: "gradients/DS_layer_type_0/add_1_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/add_1_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/add_1_grad/Sum" + input: "gradients/DS_layer_type_0/add_1_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_1_grad/Sum_1" + op: "Sum" + input: "gradients/DS_layer_type_0/Reshape_2_grad/Reshape" + input: "gradients/DS_layer_type_0/add_1_grad/BroadcastGradientArgs:1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/add_1_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_0/add_1_grad/Sum_1" + input: "gradients/DS_layer_type_0/add_1_grad/Shape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_3_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Reshape_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_3_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_0/Tanh_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_3_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_0/add_3_grad/Shape" + input: "gradients/DS_layer_type_0/add_3_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_3_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_0/Reshape_5_grad/Reshape" + input: "gradients/DS_layer_type_0/add_3_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/add_3_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/add_3_grad/Sum" + input: "gradients/DS_layer_type_0/add_3_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_3_grad/Sum_1" + op: "Sum" + input: "gradients/DS_layer_type_0/Reshape_5_grad/Reshape" + input: "gradients/DS_layer_type_0/add_3_grad/BroadcastGradientArgs:1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/add_3_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_0/add_3_grad/Sum_1" + input: "gradients/DS_layer_type_0/add_3_grad/Shape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_1_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Reshape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_1_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_1/Tanh" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_1_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_1/add_1_grad/Shape" + input: "gradients/DS_layer_type_1/add_1_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_1_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_1/Reshape_2_grad/Reshape" + input: "gradients/DS_layer_type_1/add_1_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/add_1_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/add_1_grad/Sum" + input: "gradients/DS_layer_type_1/add_1_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_1_grad/Sum_1" + op: "Sum" + input: "gradients/DS_layer_type_1/Reshape_2_grad/Reshape" + input: "gradients/DS_layer_type_1/add_1_grad/BroadcastGradientArgs:1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/add_1_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_1/add_1_grad/Sum_1" + input: "gradients/DS_layer_type_1/add_1_grad/Shape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_3_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Reshape_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_3_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_1/Tanh_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_3_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_1/add_3_grad/Shape" + input: "gradients/DS_layer_type_1/add_3_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_3_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_1/Reshape_5_grad/Reshape" + input: "gradients/DS_layer_type_1/add_3_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/add_3_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/add_3_grad/Sum" + input: "gradients/DS_layer_type_1/add_3_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_3_grad/Sum_1" + op: "Sum" + input: "gradients/DS_layer_type_1/Reshape_5_grad/Reshape" + input: "gradients/DS_layer_type_1/add_3_grad/BroadcastGradientArgs:1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/add_3_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_1/add_3_grad/Sum_1" + input: "gradients/DS_layer_type_1/add_3_grad/Shape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Tanh_grad/TanhGrad" + op: "TanhGrad" + input: "DS_layer_type_0/Tanh" + input: "gradients/DS_layer_type_0/add_1_grad/Reshape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_0/Tanh_1_grad/TanhGrad" + op: "TanhGrad" + input: "DS_layer_type_0/Tanh_1" + input: "gradients/DS_layer_type_0/add_3_grad/Reshape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_1/Tanh_grad/TanhGrad" + op: "TanhGrad" + input: "DS_layer_type_1/Tanh" + input: "gradients/DS_layer_type_1/add_1_grad/Reshape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_1/Tanh_1_grad/TanhGrad" + op: "TanhGrad" + input: "DS_layer_type_1/Tanh_1" + input: "gradients/DS_layer_type_1/add_3_grad/Reshape_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } +} +node { + name: "gradients/DS_layer_type_0/add_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/MatMul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\001\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "gradients/DS_layer_type_0/add_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_0/add_grad/Shape" + input: "gradients/DS_layer_type_0/add_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_0/Tanh_grad/TanhGrad" + input: "gradients/DS_layer_type_0/add_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/add_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/add_grad/Sum" + input: "gradients/DS_layer_type_0/add_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_2_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/MatMul_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_2_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\001\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "gradients/DS_layer_type_0/add_2_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_0/add_2_grad/Shape" + input: "gradients/DS_layer_type_0/add_2_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/add_2_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_0/Tanh_1_grad/TanhGrad" + input: "gradients/DS_layer_type_0/add_2_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_0/add_2_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/add_2_grad/Sum" + input: "gradients/DS_layer_type_0/add_2_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/MatMul" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\001\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "gradients/DS_layer_type_1/add_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_1/add_grad/Shape" + input: "gradients/DS_layer_type_1/add_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_1/Tanh_grad/TanhGrad" + input: "gradients/DS_layer_type_1/add_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/add_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/add_grad/Sum" + input: "gradients/DS_layer_type_1/add_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_2_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/MatMul_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_2_grad/Shape_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\001\000\000\000\001\000\000\000" + } + } + } +} +node { + name: "gradients/DS_layer_type_1/add_2_grad/BroadcastGradientArgs" + op: "BroadcastGradientArgs" + input: "gradients/DS_layer_type_1/add_2_grad/Shape" + input: "gradients/DS_layer_type_1/add_2_grad/Shape_1" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/add_2_grad/Sum" + op: "Sum" + input: "gradients/DS_layer_type_1/Tanh_1_grad/TanhGrad" + input: "gradients/DS_layer_type_1/add_2_grad/BroadcastGradientArgs" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } + attr { + key: "keep_dims" + value { + b: false + } + } +} +node { + name: "gradients/DS_layer_type_1/add_2_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/add_2_grad/Sum" + input: "gradients/DS_layer_type_1/add_2_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_grad/MatMul" + op: "MatMul" + input: "gradients/DS_layer_type_0/add_grad/Reshape" + input: "DS_layer_type_0/matrix_1_0/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: true + } + } +} +node { + name: "gradients/DS_layer_type_0/MatMul_1_grad/MatMul" + op: "MatMul" + input: "gradients/DS_layer_type_0/add_2_grad/Reshape" + input: "DS_layer_type_0/matrix_1_1/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: true + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_grad/MatMul" + op: "MatMul" + input: "gradients/DS_layer_type_1/add_grad/Reshape" + input: "DS_layer_type_1/matrix_1_0/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: true + } + } +} +node { + name: "gradients/DS_layer_type_1/MatMul_1_grad/MatMul" + op: "MatMul" + input: "gradients/DS_layer_type_1/add_2_grad/Reshape" + input: "DS_layer_type_1/matrix_1_1/read" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "transpose_a" + value { + b: false + } + } + attr { + key: "transpose_b" + value { + b: true + } + } +} +node { + name: "gradients/AddN_2" + op: "AddN" + input: "gradients/DS_layer_type_0/add_1_grad/Reshape" + input: "gradients/DS_layer_type_0/MatMul_grad/MatMul" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@gradients/DS_layer_type_0/add_1_grad/Reshape" + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_1_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Slice_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_1_grad/Reshape" + op: "Reshape" + input: "gradients/AddN_2" + input: "gradients/DS_layer_type_0/Reshape_1_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/AddN_3" + op: "AddN" + input: "gradients/DS_layer_type_0/add_3_grad/Reshape" + input: "gradients/DS_layer_type_0/MatMul_1_grad/MatMul" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@gradients/DS_layer_type_0/add_3_grad/Reshape" + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_4_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Slice_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_4_grad/Reshape" + op: "Reshape" + input: "gradients/AddN_3" + input: "gradients/DS_layer_type_0/Reshape_4_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/AddN_4" + op: "AddN" + input: "gradients/DS_layer_type_1/add_1_grad/Reshape" + input: "gradients/DS_layer_type_1/MatMul_grad/MatMul" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@gradients/DS_layer_type_1/add_1_grad/Reshape" + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_1_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Slice_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_1_grad/Reshape" + op: "Reshape" + input: "gradients/AddN_4" + input: "gradients/DS_layer_type_1/Reshape_1_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/AddN_5" + op: "AddN" + input: "gradients/DS_layer_type_1/add_3_grad/Reshape" + input: "gradients/DS_layer_type_1/MatMul_1_grad/MatMul" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@gradients/DS_layer_type_1/add_3_grad/Reshape" + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_4_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Slice_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_4_grad/Reshape" + op: "Reshape" + input: "gradients/AddN_5" + input: "gradients/DS_layer_type_1/Reshape_4_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Slice_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_0/Slice_1_grad/Rank" + input: "gradients/DS_layer_type_0/Slice_1_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_0/Slice_1/begin" + input: "gradients/DS_layer_type_0/Slice_1_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_0/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_1_grad/Shape_1" + input: "gradients/DS_layer_type_0/Slice_1_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_1_grad/sub" + input: "DS_layer_type_0/Slice_1/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_0/Slice_1_grad/sub_1" + input: "gradients/DS_layer_type_0/Slice_1_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_0/Slice_1_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_1_grad/Reshape_1" + input: "gradients/DS_layer_type_0/Slice_1_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_1_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_0/Reshape_1_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_1_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Slice_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_0/Slice_3_grad/Rank" + input: "gradients/DS_layer_type_0/Slice_3_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_0/Slice_3/begin" + input: "gradients/DS_layer_type_0/Slice_3_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_0/Reshape_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_3_grad/Shape_1" + input: "gradients/DS_layer_type_0/Slice_3_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_3_grad/sub" + input: "DS_layer_type_0/Slice_3/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_0/Slice_3_grad/sub_1" + input: "gradients/DS_layer_type_0/Slice_3_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_0/Slice_3_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_3_grad/Reshape_1" + input: "gradients/DS_layer_type_0/Slice_3_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_3_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_0/Reshape_4_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_3_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Slice_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_1/Slice_1_grad/Rank" + input: "gradients/DS_layer_type_1/Slice_1_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_1/Slice_1/begin" + input: "gradients/DS_layer_type_1/Slice_1_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_1/Reshape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_1_grad/Shape_1" + input: "gradients/DS_layer_type_1/Slice_1_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_1_grad/sub" + input: "DS_layer_type_1/Slice_1/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_1/Slice_1_grad/sub_1" + input: "gradients/DS_layer_type_1/Slice_1_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_1/Slice_1_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_1_grad/Reshape_1" + input: "gradients/DS_layer_type_1/Slice_1_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_1_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_1/Reshape_1_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_1_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Slice_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_1/Slice_3_grad/Rank" + input: "gradients/DS_layer_type_1/Slice_3_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_1/Slice_3/begin" + input: "gradients/DS_layer_type_1/Slice_3_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/Shape_1" + op: "Shape" + input: "DS_layer_type_1/Reshape_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_3_grad/Shape_1" + input: "gradients/DS_layer_type_1/Slice_3_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_3_grad/sub" + input: "DS_layer_type_1/Slice_3/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_1/Slice_3_grad/sub_1" + input: "gradients/DS_layer_type_1/Slice_3_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_1/Slice_3_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_3_grad/Reshape_1" + input: "gradients/DS_layer_type_1/Slice_3_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_3_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_1/Reshape_4_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_3_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Slice" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/Slice_1_grad/Pad" + input: "gradients/DS_layer_type_0/Reshape_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_3_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Slice_2" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Reshape_3_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_0/Slice_3_grad/Pad" + input: "gradients/DS_layer_type_0/Reshape_3_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Slice" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/Slice_1_grad/Pad" + input: "gradients/DS_layer_type_1/Reshape_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_3_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Slice_2" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Reshape_3_grad/Reshape" + op: "Reshape" + input: "gradients/DS_layer_type_1/Slice_3_grad/Pad" + input: "gradients/DS_layer_type_1/Reshape_3_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Slice" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_0/Slice_grad/Rank" + input: "gradients/DS_layer_type_0/Slice_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_0/Slice/begin" + input: "gradients/DS_layer_type_0/Slice_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/Shape_1" + op: "Shape" + input: "Reshape_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_grad/Shape_1" + input: "gradients/DS_layer_type_0/Slice_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_grad/sub" + input: "DS_layer_type_0/Slice/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_0/Slice_grad/sub_1" + input: "gradients/DS_layer_type_0/Slice_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_0/Slice_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_grad/Reshape_1" + input: "gradients/DS_layer_type_0/Slice_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_0/Reshape_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/Shape" + op: "Shape" + input: "DS_layer_type_0/Slice_2" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_0/Slice_2_grad/Rank" + input: "gradients/DS_layer_type_0/Slice_2_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_0/Slice_2/begin" + input: "gradients/DS_layer_type_0/Slice_2_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/Shape_1" + op: "Shape" + input: "Reshape_4" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_2_grad/Shape_1" + input: "gradients/DS_layer_type_0/Slice_2_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_0/Slice_2_grad/sub" + input: "DS_layer_type_0/Slice_2/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_0/Slice_2_grad/sub_1" + input: "gradients/DS_layer_type_0/Slice_2_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_0/Slice_2_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_2_grad/Reshape_1" + input: "gradients/DS_layer_type_0/Slice_2_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_0/Slice_2_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_0/Reshape_3_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_2_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Slice" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_1/Slice_grad/Rank" + input: "gradients/DS_layer_type_1/Slice_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_1/Slice/begin" + input: "gradients/DS_layer_type_1/Slice_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/Shape_1" + op: "Shape" + input: "Reshape_6" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_grad/Shape_1" + input: "gradients/DS_layer_type_1/Slice_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_grad/sub" + input: "DS_layer_type_1/Slice/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_1/Slice_grad/sub_1" + input: "gradients/DS_layer_type_1/Slice_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_1/Slice_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_grad/Reshape_1" + input: "gradients/DS_layer_type_1/Slice_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_1/Reshape_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/Shape" + op: "Shape" + input: "DS_layer_type_1/Slice_2" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/stack" + op: "Pack" + input: "gradients/DS_layer_type_1/Slice_2_grad/Rank" + input: "gradients/DS_layer_type_1/Slice_2_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/Reshape" + op: "Reshape" + input: "DS_layer_type_1/Slice_2/begin" + input: "gradients/DS_layer_type_1/Slice_2_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/Shape_1" + op: "Shape" + input: "Reshape_6" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/sub" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_2_grad/Shape_1" + input: "gradients/DS_layer_type_1/Slice_2_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/sub_1" + op: "Sub" + input: "gradients/DS_layer_type_1/Slice_2_grad/sub" + input: "DS_layer_type_1/Slice_2/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/Reshape_1" + op: "Reshape" + input: "gradients/DS_layer_type_1/Slice_2_grad/sub_1" + input: "gradients/DS_layer_type_1/Slice_2_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/concat" + op: "ConcatV2" + input: "gradients/DS_layer_type_1/Slice_2_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_2_grad/Reshape_1" + input: "gradients/DS_layer_type_1/Slice_2_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/DS_layer_type_1/Slice_2_grad/Pad" + op: "Pad" + input: "gradients/DS_layer_type_1/Reshape_3_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_2_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/AddN_6" + op: "AddN" + input: "gradients/DS_layer_type_0/Reshape_6_grad/Reshape" + input: "gradients/DS_layer_type_0/Slice_grad/Pad" + input: "gradients/DS_layer_type_0/Slice_2_grad/Pad" + attr { + key: "N" + value { + i: 3 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@gradients/DS_layer_type_0/Reshape_6_grad/Reshape" + } + } + } +} +node { + name: "gradients/Reshape_4_grad/Shape" + op: "Shape" + input: "Slice" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Reshape_4_grad/Reshape" + op: "Reshape" + input: "gradients/AddN_6" + input: "gradients/Reshape_4_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/AddN_7" + op: "AddN" + input: "gradients/DS_layer_type_1/Reshape_6_grad/Reshape" + input: "gradients/DS_layer_type_1/Slice_grad/Pad" + input: "gradients/DS_layer_type_1/Slice_2_grad/Pad" + attr { + key: "N" + value { + i: 3 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@gradients/DS_layer_type_1/Reshape_6_grad/Reshape" + } + } + } +} +node { + name: "gradients/Reshape_6_grad/Shape" + op: "Shape" + input: "Slice_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Reshape_6_grad/Reshape" + op: "Reshape" + input: "gradients/AddN_7" + input: "gradients/Reshape_6_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/Slice_grad/Shape" + op: "Shape" + input: "Slice" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/Slice_grad/stack" + op: "Pack" + input: "gradients/Slice_grad/Rank" + input: "gradients/Slice_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/Slice_grad/Reshape" + op: "Reshape" + input: "Slice/begin" + input: "gradients/Slice_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_grad/Shape_1" + op: "Shape" + input: "Reshape_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_grad/sub" + op: "Sub" + input: "gradients/Slice_grad/Shape_1" + input: "gradients/Slice_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_grad/sub_1" + op: "Sub" + input: "gradients/Slice_grad/sub" + input: "Slice/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_grad/Reshape_1" + op: "Reshape" + input: "gradients/Slice_grad/sub_1" + input: "gradients/Slice_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/Slice_grad/concat" + op: "ConcatV2" + input: "gradients/Slice_grad/Reshape" + input: "gradients/Slice_grad/Reshape_1" + input: "gradients/Slice_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_grad/Pad" + op: "Pad" + input: "gradients/Reshape_4_grad/Reshape" + input: "gradients/Slice_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_1_grad/Rank" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 2 + } + } + } +} +node { + name: "gradients/Slice_1_grad/Shape" + op: "Shape" + input: "Slice_1" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_1_grad/stack/1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/Slice_1_grad/stack" + op: "Pack" + input: "gradients/Slice_1_grad/Rank" + input: "gradients/Slice_1_grad/stack/1" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "gradients/Slice_1_grad/Reshape" + op: "Reshape" + input: "Slice_1/begin" + input: "gradients/Slice_1_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_1_grad/Shape_1" + op: "Shape" + input: "Reshape_3" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_1_grad/sub" + op: "Sub" + input: "gradients/Slice_1_grad/Shape_1" + input: "gradients/Slice_1_grad/Shape" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_1_grad/sub_1" + op: "Sub" + input: "gradients/Slice_1_grad/sub" + input: "Slice_1/begin" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_1_grad/Reshape_1" + op: "Reshape" + input: "gradients/Slice_1_grad/sub_1" + input: "gradients/Slice_1_grad/stack" + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_1_grad/concat/axis" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 1 + } + } + } +} +node { + name: "gradients/Slice_1_grad/concat" + op: "ConcatV2" + input: "gradients/Slice_1_grad/Reshape" + input: "gradients/Slice_1_grad/Reshape_1" + input: "gradients/Slice_1_grad/concat/axis" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "Tidx" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Slice_1_grad/Pad" + op: "Pad" + input: "gradients/Reshape_6_grad/Reshape" + input: "gradients/Slice_1_grad/concat" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tpaddings" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/AddN_8" + op: "AddN" + input: "gradients/Slice_grad/Pad" + input: "gradients/Slice_1_grad/Pad" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "_class" + value { + list { + s: "loc:@gradients/Slice_grad/Pad" + } + } + } +} +node { + name: "gradients/Reshape_3_grad/Shape" + op: "Shape" + input: "Reshape_2" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "out_type" + value { + type: DT_INT32 + } + } +} +node { + name: "gradients/Reshape_3_grad/Reshape" + op: "Reshape" + input: "gradients/AddN_8" + input: "gradients/Reshape_3_grad/Shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "strided_slice_10/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 0 + } + } + } +} +node { + name: "strided_slice_10/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_10/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_10" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_10/stack" + input: "strided_slice_10/stack_1" + input: "strided_slice_10/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "mul_5/y" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 8 + } + } + } +} +node { + name: "mul_5" + op: "Mul" + input: "strided_slice_10" + input: "mul_5/y" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "Reshape_9/shape/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: -1 + } + } + } +} +node { + name: "Reshape_9/shape" + op: "Pack" + input: "Reshape_9/shape/0" + input: "mul_5" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "Reshape_9" + op: "Reshape" + input: "gradients/Reshape_3_grad/Reshape" + input: "Reshape_9/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "ProdForceNorot" + op: "ProdForceNorot" + input: "Reshape_9" + input: "DescrptNorot:1" + input: "DescrptNorot:3" + input: "t_natoms" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "n_a_sel" + value { + i: 2 + } + } + attr { + key: "n_r_sel" + value { + i: 0 + } + } +} +node { + name: "strided_slice_11/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_11/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 2 + } + } + } +} +node { + name: "strided_slice_11/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_11" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_11/stack" + input: "strided_slice_11/stack_1" + input: "strided_slice_11/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "mul_6/x" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 3 + } + } + } +} +node { + name: "mul_6" + op: "Mul" + input: "mul_6/x" + input: "strided_slice_11" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "force_test/shape/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: -1 + } + } + } +} +node { + name: "force_test/shape" + op: "Pack" + input: "force_test/shape/0" + input: "mul_6" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "force_test" + op: "Reshape" + input: "ProdForceNorot" + input: "force_test/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "ProdVirialNorot" + op: "ProdVirialNorot" + input: "Reshape_9" + input: "DescrptNorot:1" + input: "DescrptNorot:2" + input: "DescrptNorot:3" + input: "t_natoms" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "n_a_sel" + value { + i: 2 + } + } + attr { + key: "n_r_sel" + value { + i: 0 + } + } +} +node { + name: "virial_test/shape" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 2 + } + } + tensor_content: "\377\377\377\377\t\000\000\000" + } + } + } +} +node { + name: "virial_test" + op: "Reshape" + input: "ProdVirialNorot" + input: "virial_test/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +node { + name: "strided_slice_12/stack" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_12/stack_1" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 2 + } + } + } +} +node { + name: "strided_slice_12/stack_2" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + dim { + size: 1 + } + } + int_val: 1 + } + } + } +} +node { + name: "strided_slice_12" + op: "StridedSlice" + input: "t_natoms" + input: "strided_slice_12/stack" + input: "strided_slice_12/stack_1" + input: "strided_slice_12/stack_2" + attr { + key: "Index" + value { + type: DT_INT32 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "begin_mask" + value { + i: 0 + } + } + attr { + key: "ellipsis_mask" + value { + i: 0 + } + } + attr { + key: "end_mask" + value { + i: 0 + } + } + attr { + key: "new_axis_mask" + value { + i: 0 + } + } + attr { + key: "shrink_axis_mask" + value { + i: 1 + } + } +} +node { + name: "mul_7/x" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: 9 + } + } + } +} +node { + name: "mul_7" + op: "Mul" + input: "mul_7/x" + input: "strided_slice_12" + attr { + key: "T" + value { + type: DT_INT32 + } + } +} +node { + name: "atom_virial_test/shape/0" + op: "Const" + attr { + key: "dtype" + value { + type: DT_INT32 + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_INT32 + tensor_shape { + } + int_val: -1 + } + } + } +} +node { + name: "atom_virial_test/shape" + op: "Pack" + input: "atom_virial_test/shape/0" + input: "mul_7" + attr { + key: "N" + value { + i: 2 + } + } + attr { + key: "T" + value { + type: DT_INT32 + } + } + attr { + key: "axis" + value { + i: 0 + } + } +} +node { + name: "atom_virial_test" + op: "Reshape" + input: "ProdVirialNorot:1" + input: "atom_virial_test/shape" + attr { + key: "T" + value { + type: DT_DOUBLE + } + } + attr { + key: "Tshape" + value { + type: DT_INT32 + } + } +} +library { +} diff --git a/source/tests/polar_se_a_tebd.json b/source/tests/polar_se_a_tebd.json new file mode 100644 index 0000000000..98de4b6694 --- /dev/null +++ b/source/tests/polar_se_a_tebd.json @@ -0,0 +1,68 @@ +{ + "_comment": " model parameters", + "model":{ + "type": "polar", + "type_map": ["O", "H"], + "type_embedding":{ + "neuron": [2,4,8], + "resnet_dt": false, + "seed": 1 + }, + "descriptor" :{ + "type": "se_a", + "sel": [46, 92], + "rcut_smth": 5.80, + "rcut": 6.00, + "neuron": [25, 50, 100], + "resnet_dt": false, + "axis_neuron": 16, + "seed": 1 + }, + "fitting_net": { + "type": "polar", + "sel_type": [0], + "fit_diag": false, + "neuron": [100, 100, 100], + "resnet_dt": true, + "seed": 1 + }, + "_comment": " that's all" + }, + + "learning_rate" :{ + "type": "exp", + "start_lr": 0.001, + "decay_steps": 5000, + "decay_rate": 0.95, + "_comment": "that's all" + }, + + "loss" : { + "type": "tensor", + "pref": 1.0, + "pref_atomic": 1.0, + "_comment": "that's all" + }, + + "_comment": " traing controls", + "systems": ["system"], + "set_prefix": "set", + "stop_batch": 1000000, + "batch_size": [1], + + "seed": 1, + + "_comment": " display and restart", + "_comment": " frequencies counted in batch", + "disp_file": "lcurve.out", + "disp_freq": 100, + "numb_test": 10, + "save_freq": 1000, + "save_ckpt": "model.ckpt", + "load_ckpt": "model.ckpt", + "disp_training":true, + "time_training":true, + + "_comment": "that's all" +} + diff --git a/source/tests/test_adjust_sel.py b/source/tests/test_adjust_sel.py index d16cffe6ce..3f3494f040 100644 --- a/source/tests/test_adjust_sel.py +++ b/source/tests/test_adjust_sel.py @@ -6,7 +6,7 @@ from deepmd.infer import DeepPot from deepmd.env import MODEL_VERSION # from deepmd.entrypoints.compress import compress -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.env import GLOBAL_NP_FLOAT_PRECISION if GLOBAL_NP_FLOAT_PRECISION == np.float32 : @@ -44,26 +44,26 @@ def _init_models(): with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT + " --skip-neighbor-stat") + ret = run_dp("dp train " + INPUT + " --skip-neighbor-stat") np.testing.assert_equal(ret, 0, 'DP train failed!') - ret = _subprocess_run("dp freeze -o " + frozen_model) + ret = run_dp("dp freeze -o " + frozen_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') jdata["training"]["numb_steps"] = 0 jdata["model"]["descriptor"]["sel"] = [2, 4] # equal to data with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT + " -f " + frozen_model + " --skip-neighbor-stat") + ret = run_dp("dp train " + INPUT + " -f " + frozen_model + " --skip-neighbor-stat") np.testing.assert_equal(ret, 0, 'DP model adjust sel failed!') - ret = _subprocess_run("dp freeze -o " + decreased_model) + ret = run_dp("dp freeze -o " + decreased_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') jdata["model"]["descriptor"]["sel"] = [300, 300] # equal to data with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT + " -f " + frozen_model + " --skip-neighbor-stat") + ret = run_dp("dp train " + INPUT + " -f " + frozen_model + " --skip-neighbor-stat") np.testing.assert_equal(ret, 0, 'DP model adjust sel failed!') - ret = _subprocess_run("dp freeze -o " + increased_model) + ret = run_dp("dp freeze -o " + increased_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') return INPUT, frozen_model, decreased_model, increased_model diff --git a/source/tests/test_argument_parser.py b/source/tests/test_argument_parser.py index e26a7d7a42..2f3fce9aa1 100644 --- a/source/tests/test_argument_parser.py +++ b/source/tests/test_argument_parser.py @@ -232,17 +232,57 @@ def test_parser_transfer(self): self.run_test(command="transfer", mapping=ARGS) - def test_parser_train(self): - """Test train subparser.""" + def test_parser_train_init_model(self): + """Test train init-model subparser.""" ARGS = { "INPUT": dict(type=str, value="INFILE"), "--init-model": dict(type=(str, type(None)), value="SYSTEM_DIR"), + "--output": dict(type=str, value="OUTPUT"), + } + + self.run_test(command="train", mapping=ARGS) + + def test_parser_train_restart(self): + """Test train restart subparser.""" + ARGS = { + "INPUT": dict(type=str, value="INFILE"), "--restart": dict(type=(str, type(None)), value="RESTART"), "--output": dict(type=str, value="OUTPUT"), } self.run_test(command="train", mapping=ARGS) + def test_parser_train_init_frz_model(self): + """Test train init-frz-model subparser.""" + ARGS = { + "INPUT": dict(type=str, value="INFILE"), + "--init-frz-model": dict(type=(str, type(None)), value="INIT_FRZ_MODEL"), + "--output": dict(type=str, value="OUTPUT"), + } + + self.run_test(command="train", mapping=ARGS) + + def test_parser_train_finetune(self): + """Test train finetune subparser.""" + ARGS = { + "INPUT": dict(type=str, value="INFILE"), + "--finetune": dict(type=(str, type(None)), value="FINETUNE"), + "--output": dict(type=str, value="OUTPUT"), + } + + self.run_test(command="train", mapping=ARGS) + + def test_parser_train_wrong_subcommand(self): + """Test train with multiple subparsers.""" + ARGS = { + "INPUT": dict(type=str, value="INFILE"), + "--init-model": dict(type=(str, type(None)), value="SYSTEM_DIR"), + "--restart": dict(type=(str, type(None)), value="RESTART"), + "--output": dict(type=str, value="OUTPUT"), + } + with self.assertRaises(SystemExit): + self.run_test(command="train", mapping=ARGS) + def test_parser_freeze(self): """Test freeze subparser.""" ARGS = { diff --git a/source/tests/test_auto_batch_size.py b/source/tests/test_auto_batch_size.py index f8aa0b8e60..2790c7d4d5 100644 --- a/source/tests/test_auto_batch_size.py +++ b/source/tests/test_auto_batch_size.py @@ -1,4 +1,5 @@ import unittest +import os import numpy as np @@ -11,7 +12,9 @@ def oom(self, batch_size, start_index): raise OutOfMemoryError return batch_size, np.zeros((batch_size, 2)) - def test_execute_oom(self): + @unittest.mock.patch('tensorflow.compat.v1.test.is_gpu_available') + def test_execute_oom_gpu(self, mock_is_gpu_available): + mock_is_gpu_available.return_value = True # initial batch size 256 = 128 * 2 auto_batch_size = AutoBatchSize(256, 2.) # no error - 128 @@ -34,7 +37,48 @@ def test_execute_oom(self): nb, result = auto_batch_size.execute(self.oom, 1, 2) self.assertEqual(nb, 256) self.assertEqual(result.shape, (256, 2)) - + + @unittest.mock.patch('tensorflow.compat.v1.test.is_gpu_available') + def test_execute_oom_cpu(self, mock_is_gpu_available): + mock_is_gpu_available.return_value = False + # initial batch size 256 = 128 * 2, nb is always 128 + auto_batch_size = AutoBatchSize(256, 2.) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + + @unittest.mock.patch.dict(os.environ, {"DP_INFER_BATCH_SIZE": "256"}, clear=True) + def test_execute_oom_environment_variables(self): + # DP_INFER_BATCH_SIZE = 256 = 128 * 2, nb is always 128 + auto_batch_size = AutoBatchSize(999, 2.) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + nb, result = auto_batch_size.execute(self.oom, 1, 2) + self.assertEqual(nb, 128) + self.assertEqual(result.shape, (128, 2)) + def test_execute_all(self): dd1 = np.zeros((10000, 2, 1)) auto_batch_size = AutoBatchSize(256, 2.) diff --git a/source/tests/test_class_arg.py b/source/tests/test_class_arg.py deleted file mode 100644 index e573dff0bd..0000000000 --- a/source/tests/test_class_arg.py +++ /dev/null @@ -1,87 +0,0 @@ -import os,sys -import numpy as np -import unittest - -from deepmd.common import ClassArg - -class TestClassArg (unittest.TestCase) : - def test_add (self) : - ca = ClassArg().add('test', int) - test_dict = {'test' : 10, - 'test1' : 20} - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test':10}) - - def test_add_multi (self) : - ca = ClassArg()\ - .add('test', int)\ - .add('test1', str) - test_dict = {'test' : 10, - 'test1' : 'foo'} - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test1':'foo', 'test':10}) - - def test_add_multi_types (self) : - ca = ClassArg()\ - .add('test', [str, list])\ - .add('test1', [str, list]) - test_dict = {'test' : [10,20], 'test1' : 10} - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test':[10,20], 'test1':'10'}) - - def test_add_type_cvt (self) : - ca = ClassArg().add('test', float) - test_dict = {'test' : '10'} - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test':10.0}) - - def test_add_wrong_type_cvt (self) : - ca = ClassArg().add('test', list) - test_dict = {'test' : 10} - with self.assertRaises(TypeError): - ca.parse(test_dict) - - def test_add_alias (self) : - ca = ClassArg().add('test', str, alias = ['test1', 'test2']) - test_dict = {'test2' : 'foo'} - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test': 'foo'}) - - def test_add_default (self) : - ca = ClassArg().add('test', str, alias = ['test1', 'test2'], default = 'bar') - test_dict = {'test3' : 'foo'} - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test': 'bar'}) - - def test_add_default_overwrite (self) : - ca = ClassArg().add('test', str, alias = ['test1', 'test2'], default = 'bar') - test_dict = {'test2' : 'foo'} - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test': 'foo'}) - - def test_add_must (self) : - ca = ClassArg().add('test', str, must = True) - test_dict = {'test2' : 'foo'} - with self.assertRaises(RuntimeError): - ca.parse(test_dict) - - def test_add_none (self) : - ca = ClassArg().add('test', int) - test_dict = {'test2' : 'foo'} - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test': None}) - - def test_multi_add (self) : - ca = ClassArg().add('test', int) - test_dict = {'test2' : 'foo'} - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test': None}) - ca.add('test2', str) - ca.parse(test_dict) - self.assertEqual(ca.get_dict(), {'test': None, 'test2':'foo'}) - - - - -if __name__ == '__main__': - unittest.main() diff --git a/source/tests/test_cluster.py b/source/tests/test_cluster.py index 01e128b401..d67b572bb1 100644 --- a/source/tests/test_cluster.py +++ b/source/tests/test_cluster.py @@ -1,6 +1,7 @@ import unittest from deepmd.cluster import local, slurm +from deepmd.env import tf from unittest import mock @@ -22,26 +23,40 @@ def returncode(self): class TestGPU(unittest.TestCase): + @mock.patch('tensorflow.compat.v1.test.is_built_with_cuda') @mock.patch('subprocess.Popen') - def test_none(self, mock_Popen): + def test_none(self, mock_Popen, mock_is_built_with_cuda): mock_Popen.return_value.__enter__.return_value = FakePopen(b'0', b'') + mock_is_built_with_cuda.return_value = True gpus = local.get_gpus() self.assertIsNone(gpus) + @mock.patch('tensorflow.compat.v1.test.is_built_with_cuda') @mock.patch('subprocess.Popen') - def test_valid(self, mock_Popen): + def test_valid(self, mock_Popen, mock_is_built_with_cuda): mock_Popen.return_value.__enter__.return_value = FakePopen(b'2', b'') + mock_is_built_with_cuda.return_value = True gpus = local.get_gpus() self.assertEqual(gpus, [0, 1]) + @mock.patch('tensorflow.compat.v1.test.is_built_with_cuda') @mock.patch('subprocess.Popen') - def test_error(self, mock_Popen): + def test_error(self, mock_Popen, mock_is_built_with_cuda): mock_Popen.return_value.__enter__.return_value = \ FakePopen(stderr=b'!', returncode=1) + mock_is_built_with_cuda.return_value = True with self.assertRaises(RuntimeError) as cm: _ = local.get_gpus() self.assertIn('Failed to detect', str(cm.exception)) + @mock.patch('tensorflow.compat.v1.test.is_built_with_rocm', create=True) + @mock.patch('tensorflow.compat.v1.test.is_built_with_cuda') + def test_cpu(self, mock_is_built_with_cuda, mock_is_built_with_rocm): + mock_is_built_with_cuda.return_value = False + mock_is_built_with_rocm.return_value = False + gpus = local.get_gpus() + self.assertIsNone(gpus) + class TestLocal(unittest.TestCase): @mock.patch('socket.gethostname') diff --git a/source/tests/test_deeppot_a.py b/source/tests/test_deeppot_a.py index da1c19587f..73e9f1d7e6 100644 --- a/source/tests/test_deeppot_a.py +++ b/source/tests/test_deeppot_a.py @@ -5,7 +5,7 @@ from infer.convert2pb import convert_pbtxt_to_pb from deepmd.infer import DeepPot from deepmd.env import MODEL_VERSION -from common import tests_path +from common import tests_path, run_dp from deepmd.env import GLOBAL_NP_FLOAT_PRECISION if GLOBAL_NP_FLOAT_PRECISION == np.float32 : @@ -322,3 +322,25 @@ def test_ase(self): np.testing.assert_almost_equal(ff.ravel(), self.expected_f.ravel(), default_places) expected_se = np.sum(self.expected_e.reshape([nframes, -1]), axis = 1) np.testing.assert_almost_equal(ee.ravel(), expected_se.ravel(), default_places) + + +class TestModelConvert(unittest.TestCase): + def setUp(self): + self.coords = np.array([12.83, 2.56, 2.18, + 12.09, 2.87, 2.74, + 00.25, 3.32, 1.68, + 3.36, 3.00, 1.81, + 3.51, 2.51, 2.60, + 4.27, 3.22, 1.56]) + self.atype = [0, 1, 1, 0, 1, 1] + self.box = np.array([13., 0., 0., 0., 13., 0., 0., 0., 13.]) + + def test_convert_012(self): + old_model = "deeppot.pb" + new_model = "deeppot.pbtxt" + convert_pbtxt_to_pb(str(tests_path / "infer" / "sea_012.pbtxt"), old_model) + run_dp(f"dp convert-from 0.12 -i {old_model} -o {new_model}") + dp = DeepPot(new_model) + _, _, _, _, _ = dp.eval(self.coords, self.box, self.atype, atomic=True) + os.remove(old_model) + os.remove(new_model) diff --git a/source/tests/test_descrpt_se_a_type.py b/source/tests/test_descrpt_se_a_type.py index f65338d0a4..f61b25f8c6 100644 --- a/source/tests/test_descrpt_se_a_type.py +++ b/source/tests/test_descrpt_se_a_type.py @@ -5,7 +5,7 @@ import pickle from common import Data,gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_descrpt_se_atten.py b/source/tests/test_descrpt_se_atten.py index 777ba0e6bc..b60b5de1c8 100644 --- a/source/tests/test_descrpt_se_atten.py +++ b/source/tests/test_descrpt_se_atten.py @@ -4,7 +4,7 @@ import pickle from common import Data, gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeAtten from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_dipole_se_a.py b/source/tests/test_dipole_se_a.py index 42a615300a..8f06efdfeb 100644 --- a/source/tests/test_dipole_se_a.py +++ b/source/tests/test_dipole_se_a.py @@ -4,7 +4,7 @@ from common import Data,gen_data, j_loader from common import finite_difference, strerch_box -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import DipoleFittingSeA from deepmd.model import DipoleModel diff --git a/source/tests/test_dipole_se_a_tebd.py b/source/tests/test_dipole_se_a_tebd.py new file mode 100644 index 0000000000..830528d007 --- /dev/null +++ b/source/tests/test_dipole_se_a_tebd.py @@ -0,0 +1,158 @@ +import dpdata, os, sys, unittest +import numpy as np +from deepmd.env import tf +from common import Data, gen_data, j_loader +from common import finite_difference, strerch_box + +from common import DataSystem +from deepmd.descriptor import DescrptSeA +from deepmd.fit import DipoleFittingSeA +from deepmd.utils.type_embed import TypeEmbedNet +from deepmd.model import DipoleModel +from deepmd.common import j_must_have +from packaging.version import parse as parse_version + +GLOBAL_ENER_FLOAT_PRECISION = tf.float64 +GLOBAL_TF_FLOAT_PRECISION = tf.float64 +GLOBAL_NP_FLOAT_PRECISION = np.float64 + + +@unittest.skipIf(parse_version(tf.__version__) < parse_version("1.15"), + f"The current tf version {tf.__version__} is too low to run the new testing model.") +class TestModel(tf.test.TestCase): + def setUp(self): + gen_data() + + def test_model(self): + jfile = 'polar_se_a_tebd.json' + jdata = j_loader(jfile) + + systems = j_must_have(jdata, 'systems') + set_pfx = j_must_have(jdata, 'set_prefix') + batch_size = j_must_have(jdata, 'batch_size') + test_size = j_must_have(jdata, 'numb_test') + batch_size = 1 + test_size = 1 + stop_batch = j_must_have(jdata, 'stop_batch') + rcut = j_must_have(jdata['model']['descriptor'], 'rcut') + + data = DataSystem(systems, set_pfx, batch_size, test_size, rcut, run_opt=None) + + test_data = data.get_test() + numb_test = 1 + + jdata['model']['descriptor'].pop('type', None) + descrpt = DescrptSeA(**jdata['model']['descriptor'], uniform_seed=True) + jdata['model']['fitting_net'].pop('type', None) + jdata['model']['fitting_net'].pop('fit_diag', None) + jdata['model']['fitting_net']['descrpt'] = descrpt + fitting = DipoleFittingSeA(**jdata['model']['fitting_net'], uniform_seed=True) + typeebd_param = jdata['model']['type_embedding'] + typeebd = TypeEmbedNet( + neuron=typeebd_param['neuron'], + resnet_dt=typeebd_param['resnet_dt'], + seed=typeebd_param['seed'], + uniform_seed=True) + model = DipoleModel(descrpt, fitting, typeebd) + + # model._compute_dstats([test_data['coord']], [test_data['box']], [test_data['type']], [test_data['natoms_vec']], [test_data['default_mesh']]) + input_data = {'coord': [test_data['coord']], + 'box': [test_data['box']], + 'type': [test_data['type']], + 'natoms_vec': [test_data['natoms_vec']], + 'default_mesh': [test_data['default_mesh']], + 'fparam': [test_data['fparam']], + } + model._compute_input_stat(input_data) + + t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') + t_energy = tf.placeholder(GLOBAL_ENER_FLOAT_PRECISION, [None], name='t_energy') + t_force = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_force') + t_virial = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_virial') + t_atom_ener = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_atom_ener') + t_coord = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='i_coord') + t_type = tf.placeholder(tf.int32, [None], name='i_type') + t_natoms = tf.placeholder(tf.int32, [model.ntypes + 2], name='i_natoms') + t_box = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None, 9], name='i_box') + t_mesh = tf.placeholder(tf.int32, [None], name='i_mesh') + is_training = tf.placeholder(tf.bool) + t_fparam = None + inputs_dict = {} + + model_pred \ + = model.build(t_coord, + t_type, + t_natoms, + t_box, + t_mesh, + inputs_dict, + suffix="dipole_se_a_tebd", + reuse=False) + dipole = model_pred['dipole'] + gdipole = model_pred['global_dipole'] + force = model_pred['force'] + virial = model_pred['virial'] + atom_virial = model_pred['atom_virial'] + + feed_dict_test = {t_prop_c: test_data['prop_c'], + t_coord: np.reshape(test_data['coord'][:numb_test, :], [-1]), + t_box: test_data['box'][:numb_test, :], + t_type: np.reshape(test_data['type'][:numb_test, :], [-1]), + t_natoms: test_data['natoms_vec'], + t_mesh: test_data['default_mesh'], + is_training: False} + + sess = self.test_session().__enter__() + sess.run(tf.global_variables_initializer()) + [p, gp] = sess.run([dipole, gdipole], feed_dict=feed_dict_test) + + p = p.reshape([-1]) + refp = [15.759189570481473, 9.56848733368029, 0.3494387894045414, + 1.3280752117673629, 10.285935424492124, -0.5847081785394377] + + places = 10 + np.testing.assert_almost_equal(p, refp, places) + + gp = gp.reshape([-1]) + refgp = np.array(refp).reshape(-1, 3).sum(0) + + places = 9 + np.testing.assert_almost_equal(gp, refgp, places) + + # make sure only one frame is used + feed_dict_single = {t_prop_c: test_data['prop_c'], + t_coord: np.reshape(test_data['coord'][:1, :], [-1]), + t_box: test_data['box'][:1, :], + t_type: np.reshape(test_data['type'][:1, :], [-1]), + t_natoms: test_data['natoms_vec'], + t_mesh: test_data['default_mesh'], + is_training: False} + + [pf, pv, pav] = sess.run([force, virial, atom_virial], feed_dict=feed_dict_single) + pf, pv = pf.reshape(-1), pv.reshape(-1) + spv = pav.reshape(1, 3, -1, 9).sum(2).reshape(-1) + + base_dict = feed_dict_single.copy() + coord0 = base_dict.pop(t_coord) + box0 = base_dict.pop(t_box) + + fdf = - finite_difference( + lambda coord: sess.run(gdipole, + feed_dict={**base_dict, + t_coord: coord, + t_box: box0}).reshape(-1), + test_data['coord'][:numb_test, :].reshape([-1])).reshape(-1) + fdv = - (finite_difference( + lambda box: sess.run(gdipole, + feed_dict={**base_dict, + t_coord: strerch_box(coord0, box0, box), + t_box: box}).reshape(-1), + test_data['box'][:numb_test, :]).reshape([-1, 3, 3]).transpose(0, 2, 1) + @ box0.reshape(3, 3)).reshape(-1) + + delta = 1e-5 + np.testing.assert_allclose(pf, fdf, delta) + np.testing.assert_allclose(pv, fdv, delta) + # make sure atomic virial sum to virial + places = 10 + np.testing.assert_almost_equal(pv, spv, places) diff --git a/source/tests/test_examples.py b/source/tests/test_examples.py index 61e1801345..babcd56992 100644 --- a/source/tests/test_examples.py +++ b/source/tests/test_examples.py @@ -23,6 +23,7 @@ p_examples / "nopbc" / "train" / "input.json", p_examples / "water_tensor" / "dipole" / "dipole_input.json", p_examples / "water_tensor" / "polar" / "polar_input.json", + p_examples / "water_multi_task" / "ener_dipole" / "input.json", p_examples / "fparam" / "train" / "input.json", p_examples / "fparam" / "train" / "input_aparam.json", ) diff --git a/source/tests/test_finetune_se_atten.py b/source/tests/test_finetune_se_atten.py new file mode 100644 index 0000000000..a3124c726c --- /dev/null +++ b/source/tests/test_finetune_se_atten.py @@ -0,0 +1,180 @@ +import os, sys, platform, shutil, dpdata, json +import numpy as np +import unittest +import subprocess as sp +from common import j_loader, tests_path, run_dp +from deepmd.utils.graph import get_tensor_by_name +from deepmd.utils.argcheck import normalize +from deepmd.utils.compat import update_deepmd_input +from deepmd.utils.data_system import DeepmdDataSystem +from deepmd.infer import DeepPotential + +from deepmd.env import GLOBAL_NP_FLOAT_PRECISION, tf +from packaging.version import parse as parse_version + +if GLOBAL_NP_FLOAT_PRECISION == np.float32: + default_places = 4 +else: + default_places = 10 + + +def _file_delete(file): + if os.path.isdir(file): + os.rmdir(file) + elif os.path.isfile(file): + os.remove(file) + + +def _subprocess_run(command): + popen = sp.Popen(command.split(), shell=False, stdout=sp.PIPE, stderr=sp.STDOUT) + for line in iter(popen.stdout.readline, b''): + if hasattr(line, 'decode'): + line = line.decode('utf-8') + line = line.rstrip() + print(line) + popen.wait() + return popen.returncode + + +def _init_models(): + data_file = str(tests_path / os.path.join("finetune", "data")) + data_file_mixed_type = str(tests_path / os.path.join("finetune", "data_mixed_type")) + pretrained_model = str(tests_path / "pretrained_model_se_atten.pb") + finetuned_model = str(tests_path / "finetuned_model_se_atten.pb") + finetuned_model_mixed_type = str(tests_path / "finetuned_model_se_atten_mixed_type.pb") + INPUT_PRE = str(tests_path / "input_pretrain_se_atten.json") + INPUT_FINETUNE = str(tests_path / "input_finetune_se_atten.json") + INPUT_FINETUNE_MIX = str(tests_path / "input_finetune_se_atten_mixed_type.json") + jdata_pre = j_loader(str(tests_path / os.path.join("finetune", "input_pretrain.json"))) + jdata_finetune = j_loader(str(tests_path / os.path.join("finetune", "input_finetune.json"))) + jdata_pre["training"]["training_data"]["systems"] = data_file + jdata_pre["training"]["validation_data"]["systems"] = data_file + jdata_finetune["training"]["training_data"]["systems"] = data_file + jdata_finetune["training"]["validation_data"]["systems"] = data_file + type_map_pre = jdata_pre["model"]["type_map"] + type_map_finetune = jdata_finetune["model"]["type_map"] + with open(INPUT_PRE, "w") as fp: + json.dump(jdata_pre, fp, indent=4) + with open(INPUT_FINETUNE, "w") as fp: + json.dump(jdata_finetune, fp, indent=4) + jdata_finetune["training"]["training_data"]["systems"] = data_file_mixed_type + jdata_finetune["training"]["validation_data"]["systems"] = data_file_mixed_type + with open(INPUT_FINETUNE_MIX, "w") as fp: + json.dump(jdata_finetune, fp, indent=4) + + ret = run_dp("dp train " + INPUT_PRE) + np.testing.assert_equal(ret, 0, 'DP train failed!') + ret = run_dp("dp freeze -o " + pretrained_model) + np.testing.assert_equal(ret, 0, 'DP freeze failed!') + ret = run_dp("dp train " + INPUT_FINETUNE + " -t " + pretrained_model) + np.testing.assert_equal(ret, 0, 'DP finetune failed!') + ret = run_dp("dp freeze -o " + finetuned_model) + np.testing.assert_equal(ret, 0, 'DP freeze failed!') + ret = run_dp("dp train " + INPUT_FINETUNE_MIX + " -t " + pretrained_model) + np.testing.assert_equal(ret, 0, 'DP finetune failed!') + ret = run_dp("dp freeze -o " + finetuned_model_mixed_type) + np.testing.assert_equal(ret, 0, 'DP freeze failed!') + + jdata_pre = update_deepmd_input(jdata_pre, warning=True, dump="input_v2_compat.json") + jdata_pre = normalize(jdata_pre) + rcut = jdata_pre['model']['descriptor']['rcut'] + type_map = jdata_pre['model']['type_map'] + data = DeepmdDataSystem( + systems=[data_file], + batch_size=1, + test_size=1, + rcut=rcut, + type_map=type_map, + trn_all_set=True + ) + data_requirement = {'energy': {'ndof': 1, + 'atomic': False, + 'must': False, + 'high_prec': True, + 'type_sel': None, + 'repeat': 1, + 'default': 0.0}} + data.add_dict(data_requirement) + return INPUT_PRE, INPUT_FINETUNE, INPUT_FINETUNE_MIX, \ + pretrained_model, finetuned_model, finetuned_model_mixed_type, type_map_pre, type_map_finetune, data + + +if not parse_version(tf.__version__) < parse_version("1.15"): + INPUT_PRE, INPUT_FINETUNE, INPUT_FINETUNE_MIX, \ + PRE_MODEL, FINETUNED_MODEL, FINETUNED_MODEL_MIX, PRE_MAP, FINETUNED_MAP, VALID_DATA = _init_models() + + +@unittest.skipIf(parse_version(tf.__version__) < parse_version("1.15"), + f"The current tf version {tf.__version__} is too low to run the new testing model.") +class TestFinetuneSeAtten(unittest.TestCase): + @classmethod + def setUpClass(self): + self.valid_data = VALID_DATA + + @classmethod + def tearDownClass(self): + _file_delete(INPUT_PRE) + _file_delete(INPUT_FINETUNE) + _file_delete(INPUT_FINETUNE_MIX) + _file_delete(PRE_MODEL) + _file_delete(FINETUNED_MODEL) + _file_delete(FINETUNED_MODEL_MIX) + _file_delete("out.json") + _file_delete(str(tests_path / "checkpoint")) + _file_delete("model.ckpt.meta") + _file_delete("model.ckpt.index") + _file_delete("model.ckpt.data-00000-of-00001") + _file_delete("model.ckpt-0.meta") + _file_delete("model.ckpt-0.index") + _file_delete("model.ckpt-0.data-00000-of-00001") + _file_delete("model.ckpt-1.meta") + _file_delete("model.ckpt-1.index") + _file_delete("model.ckpt-1.data-00000-of-00001") + _file_delete("input_v2_compat.json") + _file_delete("lcurve.out") + + def test_finetune_standard(self): + pretrained_bias = get_tensor_by_name(PRE_MODEL, 'fitting_attr/t_bias_atom_e') + finetuned_bias = get_tensor_by_name(FINETUNED_MODEL, 'fitting_attr/t_bias_atom_e') + sorter = np.argsort(PRE_MAP) + idx_type_map = sorter[np.searchsorted(PRE_MAP, FINETUNED_MAP, sorter=sorter)] + test_data = self.valid_data.get_test() + atom_nums = np.tile(np.bincount(test_data["type"][0])[idx_type_map], (4, 1)) + + dp = DeepPotential(PRE_MODEL) + energy = dp.eval(test_data["coord"], test_data["box"], test_data["type"][0])[0] + energy_diff = test_data["energy"] - energy + finetune_shift = finetuned_bias[idx_type_map] - pretrained_bias[idx_type_map] + ground_truth_shift = np.linalg.lstsq(atom_nums, energy_diff, rcond=None)[0].reshape(-1) + + dp_finetuned = DeepPotential(FINETUNED_MODEL) + energy_finetuned = dp_finetuned.eval(test_data["coord"], test_data["box"], test_data["type"][0])[0] + energy_diff_finetuned = test_data["energy"] - energy_finetuned + finetune_results = np.linalg.lstsq(atom_nums, energy_diff_finetuned, rcond=None)[0].reshape(-1) + + # check values + np.testing.assert_almost_equal(finetune_shift, ground_truth_shift, default_places) + np.testing.assert_almost_equal(finetune_results, 0.0, default_places) + + def test_finetune_mixed_type(self): + pretrained_bias = get_tensor_by_name(PRE_MODEL, 'fitting_attr/t_bias_atom_e') + finetuned_bias_mixed_type = get_tensor_by_name(FINETUNED_MODEL_MIX, 'fitting_attr/t_bias_atom_e') + sorter = np.argsort(PRE_MAP) + idx_type_map = sorter[np.searchsorted(PRE_MAP, FINETUNED_MAP, sorter=sorter)] + test_data = self.valid_data.get_test() + atom_nums = np.tile(np.bincount(test_data["type"][0])[idx_type_map], (4, 1)) + + dp = DeepPotential(PRE_MODEL) + energy = dp.eval(test_data["coord"], test_data["box"], test_data["type"][0])[0] + energy_diff = test_data["energy"] - energy + finetune_shift = finetuned_bias_mixed_type[idx_type_map] - pretrained_bias[idx_type_map] + ground_truth_shift = np.linalg.lstsq(atom_nums, energy_diff, rcond=None)[0].reshape(-1) + + dp_finetuned_mixed_type = DeepPotential(FINETUNED_MODEL_MIX) + energy_finetuned = dp_finetuned_mixed_type.eval(test_data["coord"], test_data["box"], test_data["type"][0])[0] + energy_diff_finetuned = test_data["energy"] - energy_finetuned + finetune_results = np.linalg.lstsq(atom_nums, energy_diff_finetuned, rcond=None)[0].reshape(-1) + + # check values + np.testing.assert_almost_equal(finetune_shift, ground_truth_shift, default_places) + np.testing.assert_almost_equal(finetune_results, 0.0, default_places) diff --git a/source/tests/test_fitting_ener_type.py b/source/tests/test_fitting_ener_type.py index 5ccb4797ab..0451460917 100644 --- a/source/tests/test_fitting_ener_type.py +++ b/source/tests/test_fitting_ener_type.py @@ -5,7 +5,7 @@ import pickle from common import Data,gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_init_frz_model_se_a.py b/source/tests/test_init_frz_model_se_a.py index cad93dbeca..1de2996524 100644 --- a/source/tests/test_init_frz_model_se_a.py +++ b/source/tests/test_init_frz_model_se_a.py @@ -2,7 +2,7 @@ import numpy as np import unittest import subprocess as sp -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.train.trainer import DPTrainer from deepmd.train.run_options import RunOptions from deepmd.utils.argcheck import normalize @@ -48,9 +48,9 @@ def _init_models(): jdata["training"]["save_ckpt"] = ckpt with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT) + ret = run_dp("dp train " + INPUT) np.testing.assert_equal(ret, 0, 'DP train failed!') - ret = _subprocess_run("dp freeze -c " + str(tests_path) + " -o " + frozen_model) + ret = run_dp("dp freeze -c " + str(tests_path) + " -o " + frozen_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') jdata = update_deepmd_input(jdata, warning=True, dump="input_v2_compat.json") diff --git a/source/tests/test_init_frz_model_se_a_type.py b/source/tests/test_init_frz_model_se_a_type.py index 2e7a693e3f..7c66922d6b 100644 --- a/source/tests/test_init_frz_model_se_a_type.py +++ b/source/tests/test_init_frz_model_se_a_type.py @@ -2,7 +2,7 @@ import numpy as np import unittest import subprocess as sp -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.train.trainer import DPTrainer from deepmd.train.run_options import RunOptions from deepmd.utils.argcheck import normalize @@ -52,9 +52,9 @@ def _init_models(): jdata['model']["type_embedding"] = type_embed with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT) + ret = run_dp("dp train " + INPUT) np.testing.assert_equal(ret, 0, 'DP train failed!') - ret = _subprocess_run("dp freeze -c " + str(tests_path) + " -o " + frozen_model) + ret = run_dp("dp freeze -c " + str(tests_path) + " -o " + frozen_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') jdata = update_deepmd_input(jdata, warning=True, dump="input_v2_compat.json") diff --git a/source/tests/test_init_frz_model_se_atten.py b/source/tests/test_init_frz_model_se_atten.py index 0decb022e9..d6b0b33260 100644 --- a/source/tests/test_init_frz_model_se_atten.py +++ b/source/tests/test_init_frz_model_se_atten.py @@ -2,7 +2,7 @@ import numpy as np import unittest import subprocess as sp -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.train.trainer import DPTrainer from deepmd.train.run_options import RunOptions from deepmd.utils.argcheck import normalize @@ -51,9 +51,9 @@ def _init_models(): jdata['model']["descriptor"]['sel'] = 120 with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT) + ret = run_dp("dp train " + INPUT) np.testing.assert_equal(ret, 0, 'DP train failed!') - ret = _subprocess_run("dp freeze -c " + str(tests_path) + " -o " + frozen_model) + ret = run_dp("dp freeze -c " + str(tests_path) + " -o " + frozen_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') jdata = update_deepmd_input(jdata, warning=True, dump="input_v2_compat.json") diff --git a/source/tests/test_init_frz_model_se_r.py b/source/tests/test_init_frz_model_se_r.py index f74a0ea222..20d27b99da 100644 --- a/source/tests/test_init_frz_model_se_r.py +++ b/source/tests/test_init_frz_model_se_r.py @@ -2,7 +2,7 @@ import numpy as np import unittest import subprocess as sp -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.train.trainer import DPTrainer from deepmd.train.run_options import RunOptions from deepmd.utils.argcheck import normalize @@ -56,9 +56,9 @@ def _init_models(): jdata["training"]["save_ckpt"] = ckpt with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT) + ret = run_dp("dp train " + INPUT) np.testing.assert_equal(ret, 0, 'DP train failed!') - ret = _subprocess_run("dp freeze -c " + str(tests_path) + " -o " + frozen_model) + ret = run_dp("dp freeze -c " + str(tests_path) + " -o " + frozen_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') jdata = update_deepmd_input(jdata, warning=True, dump="input_v2_compat.json") diff --git a/source/tests/test_lammps.py b/source/tests/test_lammps.py new file mode 100644 index 0000000000..098ab55d5d --- /dev/null +++ b/source/tests/test_lammps.py @@ -0,0 +1,22 @@ +import unittest +import os +import subprocess + +from pathlib import Path +from deepmd.utils.convert import convert_pbtxt_to_pb + +@unittest.skipIf(os.environ.get("CIBUILDWHEEL", "0") != "1", "Only test under cibuildwheel environment") +class TestLAMMPS(unittest.TestCase): + """Test LAMMPS in cibuildwheel environment.""" + @classmethod + def setUpClass(cls): + cls.work_dir = (Path(__file__).parent / "infer").absolute() + + convert_pbtxt_to_pb( + str(cls.work_dir / "deeppot.pbtxt"), + str(cls.work_dir / "deep_pot.pb") + ) + + def test_lmp(self): + in_file = (self.work_dir / "in.test").absolute() + subprocess.check_call(["lmp", "-in", str(in_file)], cwd=str(self.work_dir)) diff --git a/source/tests/test_mixed_prec_training.py b/source/tests/test_mixed_prec_training.py index 28a1d485f7..e51c64aaaf 100644 --- a/source/tests/test_mixed_prec_training.py +++ b/source/tests/test_mixed_prec_training.py @@ -6,7 +6,7 @@ from deepmd.infer import DeepPot # from deepmd.entrypoints.compress import compress -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.env import TF_VERSION @@ -43,7 +43,7 @@ def test_training(self): _TF_VERSION = Version(TF_VERSION) # check the TF_VERSION, when TF < 1.12, mixed precision is not allowed if _TF_VERSION >= Version('1.14.0'): - ret = _subprocess_run("dp train " + self.INPUT) + ret = run_dp("dp train " + self.INPUT) np.testing.assert_equal(ret, 0, 'DP train failed!') def tearDown(self): diff --git a/source/tests/test_model_compression_se_a.py b/source/tests/test_model_compression_se_a.py index 1c13a9d610..4db6e8a12f 100644 --- a/source/tests/test_model_compression_se_a.py +++ b/source/tests/test_model_compression_se_a.py @@ -6,7 +6,7 @@ from deepmd.infer import DeepPot from deepmd.env import MODEL_VERSION # from deepmd.entrypoints.compress import compress -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.env import GLOBAL_NP_FLOAT_PRECISION if GLOBAL_NP_FLOAT_PRECISION == np.float32 : @@ -41,11 +41,11 @@ def _init_models(): with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT) + ret = run_dp("dp train " + INPUT) np.testing.assert_equal(ret, 0, 'DP train failed!') - ret = _subprocess_run("dp freeze -o " + frozen_model) + ret = run_dp("dp freeze -o " + frozen_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') - ret = _subprocess_run("dp compress " + " -i " + frozen_model + " -o " + compressed_model) + ret = run_dp("dp compress " + " -i " + frozen_model + " -o " + compressed_model) np.testing.assert_equal(ret, 0, 'DP model compression failed!') return INPUT, frozen_model, compressed_model diff --git a/source/tests/test_model_compression_se_a_type_one_side_exclude_types.py b/source/tests/test_model_compression_se_a_type_one_side_exclude_types.py index b223742d2b..ab575283ab 100644 --- a/source/tests/test_model_compression_se_a_type_one_side_exclude_types.py +++ b/source/tests/test_model_compression_se_a_type_one_side_exclude_types.py @@ -6,7 +6,7 @@ from deepmd.infer import DeepPot from deepmd.env import MODEL_VERSION # from deepmd.entrypoints.compress import compress -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.env import GLOBAL_NP_FLOAT_PRECISION if GLOBAL_NP_FLOAT_PRECISION == np.float32 : @@ -43,11 +43,11 @@ def _init_models(): with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT) + ret = run_dp("dp train " + INPUT) np.testing.assert_equal(ret, 0, 'DP train failed!') - ret = _subprocess_run("dp freeze -o " + frozen_model) + ret = run_dp("dp freeze -o " + frozen_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') - ret = _subprocess_run("dp compress " + " -i " + frozen_model + " -o " + compressed_model) + ret = run_dp("dp compress " + " -i " + frozen_model + " -o " + compressed_model) np.testing.assert_equal(ret, 0, 'DP model compression failed!') return INPUT, frozen_model, compressed_model diff --git a/source/tests/test_model_compression_se_r.py b/source/tests/test_model_compression_se_r.py index 9b9218d175..9433c93017 100644 --- a/source/tests/test_model_compression_se_r.py +++ b/source/tests/test_model_compression_se_r.py @@ -6,7 +6,7 @@ from deepmd.infer import DeepPot from deepmd.env import MODEL_VERSION # from deepmd.entrypoints.compress import compress -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.env import GLOBAL_NP_FLOAT_PRECISION if GLOBAL_NP_FLOAT_PRECISION == np.float32 : @@ -49,11 +49,11 @@ def _init_models(): with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT) + ret = run_dp("dp train " + INPUT) np.testing.assert_equal(ret, 0, 'DP train failed!') - ret = _subprocess_run("dp freeze -o " + frozen_model) + ret = run_dp("dp freeze -o " + frozen_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') - ret = _subprocess_run("dp compress " + " -i " + frozen_model + " -o " + compressed_model) + ret = run_dp("dp compress " + " -i " + frozen_model + " -o " + compressed_model) np.testing.assert_equal(ret, 0, 'DP model compression failed!') return INPUT, frozen_model, compressed_model diff --git a/source/tests/test_model_compression_se_t.py b/source/tests/test_model_compression_se_t.py index 4c77a392c7..71e58fd212 100644 --- a/source/tests/test_model_compression_se_t.py +++ b/source/tests/test_model_compression_se_t.py @@ -6,7 +6,7 @@ from deepmd.infer import DeepPot from deepmd.env import MODEL_VERSION # from deepmd.entrypoints.compress import compress -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from deepmd.env import GLOBAL_NP_FLOAT_PRECISION if GLOBAL_NP_FLOAT_PRECISION == np.float32 : @@ -49,11 +49,11 @@ def _init_models(): with open(INPUT, "w") as fp: json.dump(jdata, fp, indent=4) - ret = _subprocess_run("dp train " + INPUT) + ret = run_dp("dp train " + INPUT) np.testing.assert_equal(ret, 0, 'DP train failed!') - ret = _subprocess_run("dp freeze -o " + frozen_model) + ret = run_dp("dp freeze -o " + frozen_model) np.testing.assert_equal(ret, 0, 'DP freeze failed!') - ret = _subprocess_run("dp compress " + " -i " + frozen_model + " -o " + compressed_model) + ret = run_dp("dp compress " + " -i " + frozen_model + " -o " + compressed_model) np.testing.assert_equal(ret, 0, 'DP model compression failed!') return INPUT, frozen_model, compressed_model diff --git a/source/tests/test_model_loc_frame.py b/source/tests/test_model_loc_frame.py index 5e0399fbb7..e37354778d 100644 --- a/source/tests/test_model_loc_frame.py +++ b/source/tests/test_model_loc_frame.py @@ -3,7 +3,7 @@ from deepmd.env import tf from common import Data,gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptLocFrame from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_model_multi.py b/source/tests/test_model_multi.py new file mode 100644 index 0000000000..a9a043d934 --- /dev/null +++ b/source/tests/test_model_multi.py @@ -0,0 +1,193 @@ +import dpdata, os, sys, unittest +import numpy as np +from deepmd.env import tf +from common import Data, gen_data, del_data, j_loader, finite_difference, strerch_box + +from common import DataSystem +from deepmd.descriptor import DescrptSeA +from deepmd.fit import EnerFitting, DipoleFittingSeA +from deepmd.model import MultiModel +from deepmd.common import j_must_have + +GLOBAL_ENER_FLOAT_PRECISION = tf.float64 +GLOBAL_TF_FLOAT_PRECISION = tf.float64 +GLOBAL_NP_FLOAT_PRECISION = np.float64 + + +class TestModel(tf.test.TestCase): + def setUp(self): + gen_data() + + def tearDown(self): + del_data() + + def test_model(self): + jfile = 'water_multi.json' + jdata = j_loader(jfile) + + systems = j_must_have(jdata, 'systems') + set_pfx = j_must_have(jdata, 'set_prefix') + batch_size = j_must_have(jdata, 'batch_size') + test_size = j_must_have(jdata, 'numb_test') + batch_size = 1 + test_size = 1 + stop_batch = j_must_have(jdata, 'stop_batch') + rcut = j_must_have(jdata['model']['descriptor'], 'rcut') + + data = DataSystem(systems, set_pfx, batch_size, test_size, rcut, run_opt=None) + + test_data = data.get_test() + numb_test = 1 + + jdata['model']['descriptor'].pop('type', None) + jdata['model']['descriptor']['multi_task'] = True + descrpt = DescrptSeA(**jdata['model']['descriptor'], uniform_seed=True) + fitting_dict = {} + fitting_type_dict = {} + for fitting_key in jdata['model']['fitting_net_dict']: + item_fitting_param = jdata['model']['fitting_net_dict'][fitting_key] + item_fitting_type = item_fitting_param.get('type', 'ener') + fitting_type_dict[fitting_key] = item_fitting_type + item_fitting_param.pop('type', None) + item_fitting_param.pop('fit_diag', None) + item_fitting_param['descrpt'] = descrpt + if item_fitting_type == 'ener': + fitting_dict[fitting_key] = EnerFitting(**item_fitting_param, uniform_seed=True) + elif item_fitting_type == 'dipole': + fitting_dict[fitting_key] = DipoleFittingSeA(**item_fitting_param, uniform_seed=True) + else: + RuntimeError('Test should not be here!') + model = MultiModel(descrpt, fitting_dict, fitting_type_dict) + + input_data = {'coord': [test_data['coord']], + 'box': [test_data['box']], + 'type': [test_data['type']], + 'natoms_vec': [test_data['natoms_vec']], + 'default_mesh': [test_data['default_mesh']] + } + for fitting_key in jdata['model']['fitting_net_dict']: + model._compute_input_stat(input_data, fitting_key=fitting_key) + model.descrpt.merge_input_stats(model.descrpt.stat_dict) + model.descrpt.bias_atom_e = data.compute_energy_shift() + + t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') + t_energy = tf.placeholder(GLOBAL_ENER_FLOAT_PRECISION, [None], name='t_energy') + t_force = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_force') + t_virial = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_virial') + t_atom_ener = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_atom_ener') + t_coord = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='i_coord') + t_type = tf.placeholder(tf.int32, [None], name='i_type') + t_natoms = tf.placeholder(tf.int32, [model.ntypes + 2], name='i_natoms') + t_box = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None, 9], name='i_box') + t_mesh = tf.placeholder(tf.int32, [None], name='i_mesh') + is_training = tf.placeholder(tf.bool) + t_fparam = None + + model_pred \ + = model.build(t_coord, + t_type, + t_natoms, + t_box, + t_mesh, + t_fparam, + suffix="multi", + reuse=False) + e_energy = model_pred['water_ener']['energy'] + e_force = model_pred['water_ener']['force'] + e_virial = model_pred['water_ener']['virial'] + e_atom_ener = model_pred['water_ener']['atom_ener'] + + d_dipole = model_pred['water_dipole']['dipole'] + d_gdipole = model_pred['water_dipole']['global_dipole'] + d_force = model_pred['water_dipole']['force'] + d_virial = model_pred['water_dipole']['virial'] + d_atom_virial = model_pred['water_dipole']['atom_virial'] + + feed_dict_test = {t_prop_c: test_data['prop_c'], + t_energy: test_data['energy'][:numb_test], + t_force: np.reshape(test_data['force'][:numb_test, :], [-1]), + t_virial: np.reshape(test_data['virial'][:numb_test, :], [-1]), + t_atom_ener: np.reshape(test_data['atom_ener'][:numb_test, :], [-1]), + t_coord: np.reshape(test_data['coord'][:numb_test, :], [-1]), + t_box: test_data['box'][:numb_test, :], + t_type: np.reshape(test_data['type'][:numb_test, :], [-1]), + t_natoms: test_data['natoms_vec'], + t_mesh: test_data['default_mesh'], + is_training: False} + sess = self.test_session().__enter__() + + # test water energy + sess.run(tf.global_variables_initializer()) + [e, f, v] = sess.run([e_energy, e_force, e_virial], + feed_dict=feed_dict_test) + e = e.reshape([-1]) + f = f.reshape([-1]) + v = v.reshape([-1]) + refe = [6.135449167779321300e+01] + reff = [7.799691562262310585e-02, 9.423098804815030483e-02, 3.790560997388224204e-03, 1.432522403799846578e-01, + 1.148392791403983204e-01, -1.321871172563671148e-02, -7.318966526325138000e-02, + 6.516069212737778116e-02, 5.406418483320515412e-04, 5.870713761026503247e-02, -1.605402669549013672e-01, + -5.089516979826595386e-03, -2.554593467731766654e-01, 3.092063507347833987e-02, + 1.510355029451411479e-02, 4.869271842355533952e-02, -1.446113274345035005e-01, + -1.126524434771078789e-03] + refv = [-6.076776685178300053e-01, 1.103174323630009418e-01, 1.984250991380156690e-02, 1.103174323630009557e-01, + -3.319759402259439551e-01, -6.007404107650986258e-03, 1.984250991380157036e-02, + -6.007404107650981921e-03, -1.200076017439753642e-03] + refe = np.reshape(refe, [-1]) + reff = np.reshape(reff, [-1]) + refv = np.reshape(refv, [-1]) + + places = 10 + np.testing.assert_almost_equal(e, refe, places) + np.testing.assert_almost_equal(f, reff, places) + np.testing.assert_almost_equal(v, refv, places) + + # test water dipole + [p, gp] = sess.run([d_dipole, d_gdipole], feed_dict=feed_dict_test) + p = p.reshape([-1]) + refp = [1.616802262298876514e+01, 9.809535439521079425e+00, 3.572312180768947854e-01, 1.336308874095981203e+00, + 1.057908563208963848e+01, -5.999602350098874881e-01] + places = 10 + np.testing.assert_almost_equal(p, refp, places) + gp = gp.reshape([-1]) + refgp = np.array(refp).reshape(-1, 3).sum(0) + places = 9 + np.testing.assert_almost_equal(gp, refgp, places) + + # test water dipole : make sure only one frame is used + feed_dict_single = {t_prop_c: test_data['prop_c'], + t_coord: np.reshape(test_data['coord'][:1, :], [-1]), + t_box: test_data['box'][:1, :], + t_type: np.reshape(test_data['type'][:1, :], [-1]), + t_natoms: test_data['natoms_vec'], + t_mesh: test_data['default_mesh'], + is_training: False} + + [pf, pv, pav] = sess.run([d_force, d_virial, d_atom_virial], feed_dict=feed_dict_single) + pf, pv = pf.reshape(-1), pv.reshape(-1) + spv = pav.reshape(1, 3, -1, 9).sum(2).reshape(-1) + + base_dict = feed_dict_single.copy() + coord0 = base_dict.pop(t_coord) + box0 = base_dict.pop(t_box) + + fdf = - finite_difference( + lambda coord: sess.run(d_gdipole, + feed_dict={**base_dict, + t_coord: coord, + t_box: box0}).reshape(-1), + test_data['coord'][:numb_test, :].reshape([-1])).reshape(-1) + fdv = - (finite_difference( + lambda box: sess.run(d_gdipole, + feed_dict={**base_dict, + t_coord: strerch_box(coord0, box0, box), + t_box: box}).reshape(-1), + test_data['box'][:numb_test, :]).reshape([-1, 3, 3]).transpose(0, 2, 1) + @ box0.reshape(3, 3)).reshape(-1) + + delta = 1e-5 + np.testing.assert_allclose(pf, fdf, delta) + np.testing.assert_allclose(pv, fdv, delta) + # make sure atomic virial sum to virial + places = 10 + np.testing.assert_almost_equal(pv, spv, places) diff --git a/source/tests/test_model_se_a.py b/source/tests/test_model_se_a.py index 0dce8f1b28..28caed4fd9 100644 --- a/source/tests/test_model_se_a.py +++ b/source/tests/test_model_se_a.py @@ -4,11 +4,12 @@ from deepmd.env import tf from common import Data, gen_data, del_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import EnerFitting from deepmd.model import EnerModel from deepmd.common import j_must_have +from deepmd.utils.type_embed import TypeEmbedNet GLOBAL_ENER_FLOAT_PRECISION = tf.float64 GLOBAL_TF_FLOAT_PRECISION = tf.float64 @@ -68,7 +69,7 @@ def test_model_atom_ener(self): 'default_mesh' : [test_data['default_mesh']] } model._compute_input_stat(input_data) - model.descrpt.bias_atom_e = data.compute_energy_shift() + model.fitting.bias_atom_e = np.array(set_atom_ener) t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') t_energy = tf.placeholder(GLOBAL_ENER_FLOAT_PRECISION, [None], name='t_energy') @@ -208,3 +209,102 @@ def test_model(self): np.testing.assert_almost_equal(e, refe, places) np.testing.assert_almost_equal(f, reff, places) np.testing.assert_almost_equal(v, refv, places) + + def test_model_atom_ener_type_embedding(self): + """Test atom ener with type embedding""" + jfile = 'water_se_a.json' + jdata = j_loader(jfile) + set_atom_ener = [0.02, 0.01] + jdata['model']['fitting_net']['atom_ener'] = set_atom_ener + jdata['model']['type_embeding'] = {"neuron": [2]} + + sys = dpdata.LabeledSystem() + sys.data['atom_names'] = ['foo', 'bar'] + sys.data['coords'] = np.array([0, 0, 0, 0, 0, 0]) + sys.data['atom_types'] = [0] + sys.data['cells'] = np.array([np.eye(3) * 30, np.eye(3) * 30]) + nframes = 2 + natoms = 1 + sys.data['coords'] = sys.data['coords'].reshape([nframes,natoms,3]) + sys.data['cells'] = sys.data['cells'].reshape([nframes,3,3]) + sys.data['energies'] = np.zeros([nframes,1]) + sys.data['forces'] = np.zeros([nframes,natoms,3]) + sys.to_deepmd_npy('system', prec=np.float64) + + systems = j_must_have(jdata, 'systems') + set_pfx = j_must_have(jdata, 'set_prefix') + batch_size = j_must_have(jdata, 'batch_size') + test_size = j_must_have(jdata, 'numb_test') + batch_size = 1 + test_size = 1 + stop_batch = j_must_have(jdata, 'stop_batch') + rcut = j_must_have (jdata['model']['descriptor'], 'rcut') + + data = DataSystem(systems, set_pfx, batch_size, test_size, rcut, run_opt = None) + test_data = data.get_test () + numb_test = 1 + + typeebd = TypeEmbedNet(**jdata['model']['type_embeding']) + jdata['model']['descriptor'].pop('type', None) + descrpt = DescrptSeA(**jdata['model']['descriptor'], uniform_seed=True) + jdata['model']['fitting_net']['descrpt'] = descrpt + fitting = EnerFitting(**jdata['model']['fitting_net'], uniform_seed=True) + model = EnerModel(descrpt, fitting, typeebd=typeebd) + + test_data['natoms_vec'] = [1, 1, 1, 0] + + input_data = {'coord' : [test_data['coord']], + 'box': [test_data['box']], + 'type': [test_data['type']], + 'natoms_vec' : [test_data['natoms_vec']], + 'default_mesh' : [test_data['default_mesh']] + } + model._compute_input_stat(input_data) + model.fitting.bias_atom_e = np.array(set_atom_ener) + + t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') + t_energy = tf.placeholder(GLOBAL_ENER_FLOAT_PRECISION, [None], name='t_energy') + t_coord = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='i_coord') + t_type = tf.placeholder(tf.int32, [None], name='i_type') + t_natoms = tf.placeholder(tf.int32, [model.ntypes+2], name='i_natoms') + t_box = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None, 9], name='i_box') + t_mesh = tf.placeholder(tf.int32, [None], name='i_mesh') + is_training = tf.placeholder(tf.bool) + t_fparam = None + + model_pred \ + = model.build (t_coord, + t_type, + t_natoms, + t_box, + t_mesh, + t_fparam, + suffix = "se_a_atom_ener_type_embbed_0", + reuse = False) + energy = model_pred['energy'] + force = model_pred['force'] + virial = model_pred['virial'] + + feed_dict_test = {t_prop_c: test_data['prop_c'], + t_energy: test_data['energy'] [:numb_test], + t_coord: np.reshape(test_data['coord'] [:numb_test, :], [-1]), + t_box: test_data['box'] [:numb_test, :], + t_type: np.reshape([0], [-1]), + t_natoms: [1, 1, 1, 0], + t_mesh: test_data['default_mesh'], + is_training: False + } + sess = self.test_session().__enter__() + sess.run(tf.global_variables_initializer()) + [e, f, v] = sess.run([energy, force, virial], + feed_dict = feed_dict_test) + self.assertAlmostEqual(e[0], set_atom_ener[0], places = 10) + + feed_dict_test[t_type] = np.reshape([1], [-1]) + feed_dict_test[t_natoms] = [1, 1, 0, 1] + [e, f, v] = sess.run([energy, force, virial], + feed_dict = feed_dict_test) + self.assertAlmostEqual(e[0], set_atom_ener[1], places = 10) + + + diff --git a/source/tests/test_model_se_a_aparam.py b/source/tests/test_model_se_a_aparam.py index f9a6817092..d2269ac642 100644 --- a/source/tests/test_model_se_a_aparam.py +++ b/source/tests/test_model_se_a_aparam.py @@ -3,7 +3,7 @@ from deepmd.env import tf from common import Data,gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_model_se_a_fparam.py b/source/tests/test_model_se_a_fparam.py index 469a5c429b..b940671b87 100644 --- a/source/tests/test_model_se_a_fparam.py +++ b/source/tests/test_model_se_a_fparam.py @@ -3,7 +3,7 @@ from deepmd.env import tf from common import Data,gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_model_se_a_srtab.py b/source/tests/test_model_se_a_srtab.py index acfe62ce1e..855503691d 100644 --- a/source/tests/test_model_se_a_srtab.py +++ b/source/tests/test_model_se_a_srtab.py @@ -3,7 +3,7 @@ from deepmd.env import tf from common import Data,gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_model_se_a_type.py b/source/tests/test_model_se_a_type.py index 6e80839d75..18f40eaa16 100644 --- a/source/tests/test_model_se_a_type.py +++ b/source/tests/test_model_se_a_type.py @@ -4,7 +4,7 @@ import pickle from common import Data,gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_model_se_atten.py b/source/tests/test_model_se_atten.py index d8bce857b0..e284186855 100644 --- a/source/tests/test_model_se_atten.py +++ b/source/tests/test_model_se_atten.py @@ -4,7 +4,7 @@ import pickle from common import Data, gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeAtten from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_model_se_r.py b/source/tests/test_model_se_r.py index 56052db8d3..52aad18fc5 100644 --- a/source/tests/test_model_se_r.py +++ b/source/tests/test_model_se_r.py @@ -3,7 +3,7 @@ from deepmd.env import tf from common import Data,gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeR from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_model_se_t.py b/source/tests/test_model_se_t.py index dead21c2d0..d33b9a6658 100644 --- a/source/tests/test_model_se_t.py +++ b/source/tests/test_model_se_t.py @@ -3,7 +3,7 @@ from deepmd.env import tf from common import Data,gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeT from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_neighbor_stat.py b/source/tests/test_neighbor_stat.py index 2c044c76a4..1b3ad9a650 100644 --- a/source/tests/test_neighbor_stat.py +++ b/source/tests/test_neighbor_stat.py @@ -8,15 +8,15 @@ def gen_sys(nframes): natoms = 1000 data = {} - X, Y, Z = np.mgrid[0:9:10j, 0:9:10j, 0:9:10j] + X, Y, Z = np.mgrid[0:2:3j, 0:2:3j, 0:2:3j] positions = np.vstack([X.ravel(), Y.ravel(), Z.ravel()]).T #+ 0.1 data['coords'] = np.repeat(positions[np.newaxis, :, :], nframes, axis=0) data['forces'] = np.random.random([nframes, natoms, 3]) - data['cells'] = np.array([10., 0., 0., 0., 10., 0., 0., 0., 10.]).reshape(1,3,3) + data['cells'] = np.array([3., 0., 0., 0., 3., 0., 0., 0., 3.]).reshape(1,3,3) data['energies'] = np.random.random([nframes, 1]) data['atom_names'] = ['TYPE'] - data['atom_numbs'] = [1000] - data['atom_types'] = np.repeat(0, 1000) + data['atom_numbs'] = [27] + data['atom_types'] = np.repeat(0, 27) return data @@ -25,7 +25,7 @@ def setUp(self): data0 = gen_sys(1) sys0 = dpdata.LabeledSystem() sys0.data = data0 - sys0.to_deepmd_npy('system_0', set_size = 10) + sys0.to_deepmd_npy('system_0', set_size = 1) def tearDown(self): shutil.rmtree('system_0') @@ -33,7 +33,7 @@ def tearDown(self): def test_neighbor_stat(self): # set rcut to 0. will cause a core dumped # TODO: check what is wrong - for rcut in (3., 6., 11.): + for rcut in (1., 2., 4.): with self.subTest(): rcut += 1e-3 # prevent numerical errors min_nbor_dist, max_nbor_size = neighbor_stat(system="system_0", rcut=rcut, type_map=["TYPE"]) diff --git a/source/tests/test_nvnmd_se_a.py b/source/tests/test_nvnmd_se_a.py index bc5cb34c98..7346975b63 100644 --- a/source/tests/test_nvnmd_se_a.py +++ b/source/tests/test_nvnmd_se_a.py @@ -5,7 +5,7 @@ import pickle from common import Data, gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import EnerFitting from deepmd.model import EnerModel diff --git a/source/tests/test_polar_se_a.py b/source/tests/test_polar_se_a.py index ee298bfb8b..fe7a5f2288 100644 --- a/source/tests/test_polar_se_a.py +++ b/source/tests/test_polar_se_a.py @@ -4,7 +4,7 @@ from common import Data,gen_data, j_loader from common import finite_difference, strerch_box -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import DescrptSeA from deepmd.fit import PolarFittingSeA from deepmd.model import PolarModel diff --git a/source/tests/test_polar_se_a_tebd.py b/source/tests/test_polar_se_a_tebd.py new file mode 100644 index 0000000000..a8348a8795 --- /dev/null +++ b/source/tests/test_polar_se_a_tebd.py @@ -0,0 +1,163 @@ +import dpdata, os, sys, unittest +import numpy as np +from deepmd.env import tf +from common import Data, gen_data, j_loader +from common import finite_difference, strerch_box + +from common import DataSystem +from deepmd.descriptor import DescrptSeA +from deepmd.fit import PolarFittingSeA +from deepmd.utils.type_embed import TypeEmbedNet +from deepmd.model import PolarModel +from deepmd.common import j_must_have +from packaging.version import parse as parse_version + +GLOBAL_ENER_FLOAT_PRECISION = tf.float64 +GLOBAL_TF_FLOAT_PRECISION = tf.float64 +GLOBAL_NP_FLOAT_PRECISION = np.float64 + + +@unittest.skipIf(parse_version(tf.__version__) < parse_version("1.15"), + f"The current tf version {tf.__version__} is too low to run the new testing model.") +class TestModel(tf.test.TestCase): + def setUp(self): + gen_data() + + def test_model(self): + jfile = 'polar_se_a_tebd.json' + jdata = j_loader(jfile) + + systems = j_must_have(jdata, 'systems') + set_pfx = j_must_have(jdata, 'set_prefix') + batch_size = j_must_have(jdata, 'batch_size') + test_size = j_must_have(jdata, 'numb_test') + batch_size = 1 + test_size = 1 + stop_batch = j_must_have(jdata, 'stop_batch') + rcut = j_must_have(jdata['model']['descriptor'], 'rcut') + + data = DataSystem(systems, set_pfx, batch_size, test_size, rcut, run_opt=None) + + test_data = data.get_test() + numb_test = 1 + + jdata['model']['descriptor'].pop('type', None) + jdata['model']['fitting_net'].pop('type', None) + descrpt = DescrptSeA(**jdata['model']['descriptor'], uniform_seed=True) + jdata['model']['fitting_net']['descrpt'] = descrpt + fitting = PolarFittingSeA(**jdata['model']['fitting_net'], uniform_seed=True) + typeebd_param = jdata['model']['type_embedding'] + typeebd = TypeEmbedNet( + neuron=typeebd_param['neuron'], + resnet_dt=typeebd_param['resnet_dt'], + seed=typeebd_param['seed'], + uniform_seed=True) + model = PolarModel(descrpt, fitting, typeebd) + + # model._compute_dstats([test_data['coord']], [test_data['box']], [test_data['type']], [test_data['natoms_vec']], [test_data['default_mesh']]) + input_data = {'coord': [test_data['coord']], + 'box': [test_data['box']], + 'type': [test_data['type']], + 'natoms_vec': [test_data['natoms_vec']], + 'default_mesh': [test_data['default_mesh']], + 'fparam': [test_data['fparam']], + } + model._compute_input_stat(input_data) + + t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') + t_energy = tf.placeholder(GLOBAL_ENER_FLOAT_PRECISION, [None], name='t_energy') + t_force = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_force') + t_virial = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_virial') + t_atom_ener = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_atom_ener') + t_coord = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='i_coord') + t_type = tf.placeholder(tf.int32, [None], name='i_type') + t_natoms = tf.placeholder(tf.int32, [model.ntypes + 2], name='i_natoms') + t_box = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None, 9], name='i_box') + t_mesh = tf.placeholder(tf.int32, [None], name='i_mesh') + is_training = tf.placeholder(tf.bool) + t_fparam = None + inputs_dict = {} + + model_pred \ + = model.build(t_coord, + t_type, + t_natoms, + t_box, + t_mesh, + inputs_dict, + suffix="polar_se_a_tebd", + reuse=False) + polar = model_pred['polar'] + gpolar = model_pred['global_polar'] + force = model_pred['force'] + virial = model_pred['virial'] + atom_virial = model_pred['atom_virial'] + + feed_dict_test = {t_prop_c: test_data['prop_c'], + t_coord: np.reshape(test_data['coord'][:numb_test, :], [-1]), + t_box: test_data['box'][:numb_test, :], + t_type: np.reshape(test_data['type'][:numb_test, :], [-1]), + t_natoms: test_data['natoms_vec'], + t_mesh: test_data['default_mesh'], + is_training: False} + + sess = self.test_session().__enter__() + sess.run(tf.global_variables_initializer()) + [p, gp] = sess.run([polar, gpolar], feed_dict=feed_dict_test) + + p = p.reshape([-1]) + refp = [2.9133718771953156e+01, 1.8731769782664504e+01, + 7.1105887944162027e-01, 1.8731769782664514e+01, + 1.2112482356986591e+01, 4.6145727469215880e-01, + 7.1105887944162083e-01, 4.6145727469215880e-01, + 1.7621311697004052e-02, 1.0344561330095343e+00, + 3.3008794894866171e+00, -1.9826409346695134e-01, + 3.3008794894866158e+00, 1.3546741456649618e+01, + -7.9755689451196410e-01, -1.9826409346695140e-01, + -7.9755689451196443e-01, 4.7023623761814869e-02] + places = 6 + np.testing.assert_almost_equal(p, refp, places) + + gp = gp.reshape([-1]) + refgp = np.array(refp).reshape(-1, 9).sum(0) + + places = 5 + np.testing.assert_almost_equal(gp, refgp, places) + + # make sure only one frame is used + feed_dict_single = {t_prop_c: test_data['prop_c'], + t_coord: np.reshape(test_data['coord'][:1, :], [-1]), + t_box: test_data['box'][:1, :], + t_type: np.reshape(test_data['type'][:1, :], [-1]), + t_natoms: test_data['natoms_vec'], + t_mesh: test_data['default_mesh'], + is_training: False} + + [pf, pv, pav] = sess.run([force, virial, atom_virial], feed_dict=feed_dict_single) + pf, pv = pf.reshape(-1), pv.reshape(-1) + spv = pav.reshape(1, 9, -1, 9).sum(2).reshape(-1) + + base_dict = feed_dict_single.copy() + coord0 = base_dict.pop(t_coord) + box0 = base_dict.pop(t_box) + + fdf = - finite_difference( + lambda coord: sess.run(gpolar, + feed_dict={**base_dict, + t_coord: coord, + t_box: box0}).reshape(-1), + test_data['coord'][:numb_test, :].reshape([-1])).reshape(-1) + fdv = - (finite_difference( + lambda box: sess.run(gpolar, + feed_dict={**base_dict, + t_coord: strerch_box(coord0, box0, box), + t_box: box}).reshape(-1), + test_data['box'][:numb_test, :]).reshape([-1, 3, 3]).transpose(0, 2, 1) + @ box0.reshape(3, 3)).reshape(-1) + + delta = 1e-4 + np.testing.assert_allclose(pf, fdf, delta) + np.testing.assert_allclose(pv, fdv, delta) + # make sure atomic virial sum to virial + places = 10 + np.testing.assert_almost_equal(pv, spv, places) diff --git a/source/tests/test_transfer.py b/source/tests/test_transfer.py index 7b5884b2b4..7322be71fd 100644 --- a/source/tests/test_transfer.py +++ b/source/tests/test_transfer.py @@ -5,7 +5,7 @@ from deepmd.env import tf from deepmd.infer import DeepPot -from common import j_loader, tests_path +from common import j_loader, tests_path, run_dp from infer.convert2pb import convert_pbtxt_to_pb from deepmd.entrypoints.transfer import load_graph, transform_graph @@ -37,7 +37,7 @@ def setUpClass(self): self.new_model = str(tests_path / "dp-new.pb") convert_pbtxt_to_pb(str(tests_path / os.path.join("infer","deeppot.pbtxt")), self.old_model) convert_pbtxt_to_pb(str(tests_path / os.path.join("infer","deeppot-1.pbtxt")), self.raw_model) - ret = _subprocess_run("dp transfer -O " + self.old_model + " -r " + self.raw_model + " -o " + self.new_model) + ret = run_dp("dp transfer -O " + self.old_model + " -r " + self.raw_model + " -o " + self.new_model) np.testing.assert_equal(ret, 0, 'DP transfer failed!') self.dp = DeepPot(self.new_model) diff --git a/source/tests/test_type_one_side.py b/source/tests/test_type_one_side.py index aa1548f637..c457b5dbeb 100644 --- a/source/tests/test_type_one_side.py +++ b/source/tests/test_type_one_side.py @@ -3,7 +3,7 @@ from deepmd.env import tf from common import gen_data, j_loader -from deepmd.utils.data_system import DataSystem +from common import DataSystem from deepmd.descriptor import Descriptor from deepmd.common import j_must_have @@ -113,7 +113,115 @@ def test_descriptor_one_side_exclude_types(self): feed_dict_test1[t_natoms] = new_natoms1 feed_dict_test2[t_type] = np.reshape(new_type2[:numb_test, :], [-1]) feed_dict_test2[t_natoms] = new_natoms2 - print(feed_dict_test1,feed_dict_test2) + + with self.test_session() as sess: + sess.run(tf.global_variables_initializer()) + [model_dout1] = sess.run([dout], + feed_dict = feed_dict_test1) + [model_dout2] = sess.run([dout], + feed_dict = feed_dict_test2) + [model_dout1_failed] = sess.run([dout_failed], + feed_dict = feed_dict_test1) + [model_dout2_failed] = sess.run([dout_failed], + feed_dict = feed_dict_test2) + model_dout1 = model_dout1.reshape([6, -1]) + model_dout2 = model_dout2.reshape([6, -1]) + model_dout1_failed = model_dout1_failed.reshape([6, -1]) + model_dout2_failed = model_dout2_failed.reshape([6, -1]) + + np.testing.assert_almost_equal(model_dout1[0], model_dout2[0], 10) + with self.assertRaises(AssertionError): + np.testing.assert_almost_equal(model_dout1_failed[0], model_dout2_failed[0], 10) + + + def test_se_r_one_side_exclude_types(self): + """se_r + """ + jfile = 'water_se_r.json' + jdata = j_loader(jfile) + + systems = j_must_have(jdata, 'systems') + set_pfx = j_must_have(jdata, 'set_prefix') + batch_size = j_must_have(jdata, 'batch_size') + test_size = j_must_have(jdata, 'numb_test') + batch_size = 1 + test_size = 1 + rcut = j_must_have (jdata['model']['descriptor'], 'rcut') + sel = j_must_have (jdata['model']['descriptor'], 'sel') + ntypes=len(sel) + + data = DataSystem(systems, set_pfx, batch_size, test_size, rcut, run_opt = None) + + test_data = data.get_test () + numb_test = 1 + + # set parameters + jdata['model']['descriptor']['neuron'] = [5, 5, 5] + jdata['model']['descriptor']['type_one_side'] = True + jdata['model']['descriptor']['exclude_types'] = [[0, 0]] + + t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') + t_coord = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='i_coord') + t_type = tf.placeholder(tf.int32, [None], name='i_type') + t_natoms = tf.placeholder(tf.int32, [ntypes+2], name='i_natoms') + t_box = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None, 9], name='i_box') + t_mesh = tf.placeholder(tf.int32, [None], name='i_mesh') + is_training = tf.placeholder(tf.bool) + + + # successful + descrpt = Descriptor(**jdata['model']['descriptor']) + dout \ + = descrpt.build( + t_coord, + t_type, + t_natoms, + t_box, + t_mesh, + {}, + reuse = False, + suffix = "_se_r_1side_exclude_types" + ) + # failed + descrpt_failed = Descriptor(**{**jdata['model']['descriptor'], "type_one_side": False}) + dout_failed \ + = descrpt_failed.build( + t_coord, + t_type, + t_natoms, + t_box, + t_mesh, + {}, + reuse = False, + suffix = "_se_r_1side_exclude_types_failed" + ) + + feed_dict_test1 = {t_prop_c: test_data['prop_c'], + t_coord: np.reshape(test_data['coord'] [:numb_test, :], [-1]), + t_box: test_data['box'] [:numb_test, :], + t_type: np.reshape(test_data['type'] [:numb_test, :], [-1]), + t_natoms: test_data['natoms_vec'], + t_mesh: test_data['default_mesh'], + is_training: False} + feed_dict_test2 = feed_dict_test1.copy() + # original type: 0 0 1 1 1 1 + # current: 0 1 1 1 1 1 + # current: 1 1 1 1 1 1 + new_natoms1 = test_data['natoms_vec'].copy() + new_natoms1[2] = 1 + new_natoms1[3] = 5 + new_type1 = test_data['type'].copy() + new_type1[:numb_test, 0] = 0 + new_type1[:numb_test, 1:6] = 1 + new_natoms2 = test_data['natoms_vec'].copy() + new_natoms2[2] = 0 + new_natoms2[3] = 6 + new_type2 = test_data['type'].copy() + new_type2[:numb_test] = 1 + feed_dict_test1[t_type] = np.reshape(new_type1[:numb_test, :], [-1]) + feed_dict_test1[t_natoms] = new_natoms1 + feed_dict_test2[t_type] = np.reshape(new_type2[:numb_test, :], [-1]) + feed_dict_test2[t_natoms] = new_natoms2 with self.test_session() as sess: sess.run(tf.global_variables_initializer()) diff --git a/source/tests/test_wfc.py b/source/tests/test_wfc.py deleted file mode 100644 index 80f9d48126..0000000000 --- a/source/tests/test_wfc.py +++ /dev/null @@ -1,97 +0,0 @@ -import dpdata,os,sys,unittest -import numpy as np -from deepmd.env import tf -from common import Data,gen_data, j_loader - -from deepmd.utils.data_system import DataSystem -from deepmd.descriptor import DescrptLocFrame -from deepmd.fit import WFCFitting -from deepmd.model import WFCModel -from deepmd.common import j_must_have - -GLOBAL_ENER_FLOAT_PRECISION = tf.float64 -GLOBAL_TF_FLOAT_PRECISION = tf.float64 -GLOBAL_NP_FLOAT_PRECISION = np.float64 - -class TestModel(tf.test.TestCase): - def setUp(self) : - gen_data() - - def test_model(self): - jfile = 'wfc.json' - jdata = j_loader(jfile) - - systems = j_must_have(jdata, 'systems') - set_pfx = j_must_have(jdata, 'set_prefix') - batch_size = j_must_have(jdata, 'batch_size') - test_size = j_must_have(jdata, 'numb_test') - batch_size = 1 - test_size = 1 - stop_batch = j_must_have(jdata, 'stop_batch') - rcut = j_must_have (jdata['model']['descriptor'], 'rcut') - - data = DataSystem(systems, set_pfx, batch_size, test_size, rcut, run_opt = None) - - test_data = data.get_test () - numb_test = 1 - - jdata['model']['descriptor'].pop('type', None) - jdata['model']['descriptor'].pop('_comment', None) - descrpt = DescrptLocFrame(**jdata['model']['descriptor']) - jdata['model']['fitting_net']['uniform_seed'] = True - fitting = WFCFitting(jdata['model']['fitting_net'], descrpt) - model = WFCModel(descrpt, fitting) - - input_data = {'coord' : [test_data['coord']], - 'box': [test_data['box']], - 'type': [test_data['type']], - 'natoms_vec' : [test_data['natoms_vec']], - 'default_mesh' : [test_data['default_mesh']], - 'fparam': [test_data['fparam']], - } - model._compute_input_stat(input_data) - - t_prop_c = tf.placeholder(tf.float32, [5], name='t_prop_c') - t_energy = tf.placeholder(GLOBAL_ENER_FLOAT_PRECISION, [None], name='t_energy') - t_force = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_force') - t_virial = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_virial') - t_atom_ener = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='t_atom_ener') - t_coord = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name='i_coord') - t_type = tf.placeholder(tf.int32, [None], name='i_type') - t_natoms = tf.placeholder(tf.int32, [model.ntypes+2], name='i_natoms') - t_box = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None, 9], name='i_box') - t_mesh = tf.placeholder(tf.int32, [None], name='i_mesh') - is_training = tf.placeholder(tf.bool) - t_fparam = None - - model_pred \ - = model.build (t_coord, - t_type, - t_natoms, - t_box, - t_mesh, - t_fparam, - suffix = "wfc", - reuse = False) - wfc = model_pred['wfc'] - - feed_dict_test = {t_prop_c: test_data['prop_c'], - t_coord: np.reshape(test_data['coord'] [:numb_test, :], [-1]), - t_box: test_data['box'] [:numb_test, :], - t_type: np.reshape(test_data['type'] [:numb_test, :], [-1]), - t_natoms: test_data['natoms_vec'], - t_mesh: test_data['default_mesh'], - is_training: False} - - sess = self.test_session().__enter__() - sess.run(tf.global_variables_initializer()) - [p] = sess.run([wfc], feed_dict = feed_dict_test) - - p = p.reshape([-1]) - refp = [-9.105016838228578990e-01,7.196284362034099935e-01,-9.548516928185298014e-02,2.764615027095288724e+00,2.661319598995644520e-01,7.579512949131941846e-02,-2.107409067376114997e+00,-1.299080016614967414e-01,-5.962778584850070285e-01,2.913899917663253514e-01,-1.226917174638697094e+00,1.829523069930876655e+00,1.015704024959750873e+00,-1.792333611099589386e-01,5.032898080485321834e-01,1.808561721292949453e-01,2.468863482075112081e+00,-2.566442546384765100e-01,-1.467453783795173994e-01,-1.822963931552128658e+00,5.843600156865462747e-01,-1.493875280832117403e+00,1.693322352814763398e-01,-1.877325443995481624e+00] - - places = 6 - np.testing.assert_almost_equal(p, refp, places) - - - diff --git a/source/tests/water_multi.json b/source/tests/water_multi.json new file mode 100644 index 0000000000..6202e8ebd2 --- /dev/null +++ b/source/tests/water_multi.json @@ -0,0 +1,80 @@ +{ + "_comment": " model parameters", + "model" : { + "descriptor" :{ + "type": "se_a", + "sel": [46, 92], + "rcut_smth": 5.80, + "rcut": 6.00, + "neuron": [25, 50, 100], + "resnet_dt": false, + "axis_neuron": 16, + "seed": 1 + }, + "fitting_net_dict" : { + "water_ener": { + "type": "ener", + "neuron": [ + 240, + 240, + 240 + ], + "resnet_dt": true, + "seed": 1 + }, + "water_dipole": { + "type": "dipole", + "sel_type": [0], + "fit_diag": false, + "neuron": [100, 100, 100], + "resnet_dt": true, + "seed": 1 + } + } + }, + "learning_rate" :{ + "type": "exp", + "start_lr": 0.001, + "decay_steps": 5000, + "decay_rate": 0.95, + "_comment": "that's all" + }, + + "loss_dict" : { + "water_ener": { + "type": "ener", + "start_pref_e": 0.02, + "limit_pref_e": 1, + "start_pref_f": 1000, + "limit_pref_f": 1, + "start_pref_v": 0, + "limit_pref_v": 0 + }, + "water_dipole": { + "type": "tensor", + "pref": 1.0, + "pref_atomic": 1.0 + } + }, + + "_comment": " traing controls", + "systems": ["system"], + "set_prefix": "set", + "stop_batch": 1000000, + "batch_size": 1, + "seed": 1, + + "disp_file": "lcurve.out", + "disp_freq": 100, + "numb_test": 1, + "save_freq": 1000, + "save_ckpt": "model.ckpt", + "load_ckpt": "model.ckpt", + "disp_training": true, + "time_training": true, + "profiling": false, + "profiling_file": "timeline.json", + + "_comment": "that's all" +} +