diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c8c9967 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,68 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-18.04 + strategy: + matrix: + include: + - cuda: 10.2.89 + gcc: 8.5.0 + nvcc: 10.2 + python: 3.8 + pytorch: 1.7.1 + - cuda: 11.2.2 + gcc: 10.3.0 + nvcc: 11.2 + python: 3.9 + pytorch: 1.8.0 # Cannot test with PyTorch 1.9, because of https://github.com/aiqm/torchani/issues/598 + + steps: + - name: Check out + uses: actions/checkout@v2 + + - name: Install CUDA Toolkit + uses: Jimver/cuda-toolkit@v0.2.4 + with: + cuda: ${{ matrix.cuda }} + + - name: Install Miniconda + uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: "" + auto-activate-base: true + miniforge-variant: Miniforge3 + + - name: Install dependencies + shell: bash -l {0} + run: | + sed -i -e "/cudatoolkit/c\ - cudatoolkit ${{ matrix.cuda }}" \ + -e "/gxx_linux-64/c\ - gxx_linux-64 ${{ matrix.gcc }}" \ + -e "/nvcc_linux-64/c\ - nvcc_linux-64 ${{ matrix.nvcc }}" \ + -e "/python/c\ - python ${{ matrix.python }}" \ + -e "/pytorch-gpu/c\ - pytorch-gpu ${{ matrix.pytorch }}" \ + environment.yml + conda env create -n nnpops -f environment.yml + + - name: Configure, compile, and install + shell: bash -l {0} + run: | + conda activate nnpops + mkdir build && cd build + cmake .. \ + -DTorch_DIR=$CONDA_PREFIX/lib/python${{ matrix.python }}/site-packages/torch/share/cmake/Torch \ + -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX + make install + + - name: Test + shell: bash -l {0} + run: | + conda activate nnpops + cd build + ctest --verbose --exclude-regex TestCuda diff --git a/CMakeLists.txt b/CMakeLists.txt index eac264e..e6f8a6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,8 +29,8 @@ foreach(TEST_PATH ${TEST_PATHS}) add_test(${TEST_NAME} ${TEST_NAME}) endforeach() -add_test(TestSymmetryFunctions pytest ${CMAKE_SOURCE_DIR}/src/pytorch/TestSymmetryFunctions.py) -add_test(TestBatchedNN pytest ${CMAKE_SOURCE_DIR}/src/pytorch/TestBatchedNN.py) +add_test(TestBatchedNN pytest -v ${CMAKE_SOURCE_DIR}/src/pytorch/TestBatchedNN.py) +add_test(TestSymmetryFunctions pytest -v ${CMAKE_SOURCE_DIR}/src/pytorch/TestSymmetryFunctions.py) install(TARGETS ${LIBRARY} DESTINATION ${Python_SITEARCH}/${NAME}) install(FILES src/pytorch/__init__.py diff --git a/README.md b/README.md index 9c25c92..541b72f 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ $ make install - Run the tests ```bash -$ ctest +$ ctest --verbose ``` ## Usage diff --git a/environment.yml b/environment.yml index 965011c..835aaaf 100644 --- a/environment.yml +++ b/environment.yml @@ -2,10 +2,11 @@ channels: - conda-forge dependencies: - cmake - - gxx_linux-64 <=10 + - cudatoolkit 11.2.2 + - gxx_linux-64 10.3.0 - make - mdtraj - - nvcc_linux-64 + - nvcc_linux-64 11.2 - torchani 2.2 - pytest - python 3.9 diff --git a/src/pytorch/TestBatchedNN.py b/src/pytorch/TestBatchedNN.py index bf4ab45..6cc6214 100644 --- a/src/pytorch/TestBatchedNN.py +++ b/src/pytorch/TestBatchedNN.py @@ -38,6 +38,9 @@ def test_import(): @pytest.mark.parametrize('molFile', ['1hvj', '1hvk', '2iuz', '3hkw', '3hky', '3lka', '3o99']) def test_compare_with_native(deviceString, molFile): + if deviceString == 'cuda' and not torch.cuda.is_available(): + pytest.skip('CUDA is not available') + from NNPOps.BatchedNN import TorchANIBatchedNN device = torch.device(deviceString) @@ -70,6 +73,9 @@ def test_compare_with_native(deviceString, molFile): @pytest.mark.parametrize('molFile', ['1hvj', '1hvk', '2iuz', '3hkw', '3hky', '3lka', '3o99']) def test_model_serialization(deviceString, molFile): + if deviceString == 'cuda' and not torch.cuda.is_available(): + pytest.skip('CUDA is not available') + from NNPOps.BatchedNN import TorchANIBatchedNN device = torch.device(deviceString) diff --git a/src/pytorch/TestSymmetryFunctions.py b/src/pytorch/TestSymmetryFunctions.py index b5b5e0b..fa51de0 100644 --- a/src/pytorch/TestSymmetryFunctions.py +++ b/src/pytorch/TestSymmetryFunctions.py @@ -38,6 +38,9 @@ def test_import(): @pytest.mark.parametrize('molFile', ['1hvj', '1hvk', '2iuz', '3hkw', '3hky', '3lka', '3o99']) def test_compare_with_native(deviceString, molFile): + if deviceString == 'cuda' and not torch.cuda.is_available(): + pytest.skip('CUDA is not available') + from NNPOps.SymmetryFunctions import TorchANISymmetryFunctions device = torch.device(deviceString) @@ -70,6 +73,9 @@ def test_compare_with_native(deviceString, molFile): @pytest.mark.parametrize('molFile', ['1hvj', '1hvk', '2iuz', '3hkw', '3hky', '3lka', '3o99']) def test_model_serialization(deviceString, molFile): + if deviceString == 'cuda' and not torch.cuda.is_available(): + pytest.skip('CUDA is not available') + from NNPOps.SymmetryFunctions import TorchANISymmetryFunctions device = torch.device(deviceString)