alan-turing-institute / PeriPy

Code base for PeriPy, a lightweight, open-source and high-performance package for peridynamic simulations written in Python - a collaboration between Exeter, Cambridge & Turing
MIT License
46 stars 14 forks source link

Feature/open cl integrator bb #72

Closed bb515 closed 4 years ago

gmingas commented 4 years ago

I ran the tests locally and 4 of them failed, see log below, you might not be seeing those in Travis as it fails to run due to the pyopencl issue:

(base) MAC-ATI0385:Probabilistic-Peridynamics gmingas$ pytest peridynamics/test/
========================================================================================================= test session starts ==========================================================================================================
platform darwin -- Python 3.6.7, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: /Users/gmingas/projects/Probabilistic-Peridynamics
plugins: cov-2.8.1
collected 156 items                                                                                                                                                                                                                    

peridynamics/test/test_cl_euler.py ..FF                                                                                                                                                                                          [  2%]
peridynamics/test/test_cl_peridynamics.py ...                                                                                                                                                                                    [  4%]
peridynamics/test/test_cl_utilities.py .....                                                                                                                                                                                     [  7%]
peridynamics/test/test_integrators.py ....                                                                                                                                                                                       [ 10%]
peridynamics/test/test_model.py ............................................................................................................                                                                                     [ 79%]
peridynamics/test/test_neighbour_list.py ......                                                                                                                                                                                  [ 83%]
peridynamics/test/test_peridynamics.py ......FF                                                                                                                                                                                  [ 88%]
peridynamics/test/test_regression.py ....s..s                                                                                                                                                                                    [ 93%]
peridynamics/test/test_spatial.py ......                                                                                                                                                                                         [ 97%]
peridynamics/test/test_utilities.py ....                                                                                                                                                                                         [100%]

=============================================================================================================== FAILURES ===============================================================================================================
___________________________________________________________________________________________ TestUpdateDisplacement.test_update_displacement3 ___________________________________________________________________________________________

self = <peridynamics.test.test_cl_euler.TestUpdateDisplacement object at 0x7fd20080b7f0>, context = <pyopencl.Context at 0x7fd1aa42c460 on <pyopencl.Device 'AMD Radeon Pro 560X Compute Engine' on 'Apple' at 0x1021c00>>
queue = <pyopencl._cl.CommandQueue object at 0x7fd2007d67d8>, program = <pyopencl.Program object at 0x7fd200843550>

    @context_available
    def test_update_displacement3(self, context, queue, program):
        """Test displacement update with displacement boundary conditions."""
        u = np.zeros(3)
        nnodes = 1
        force = np.array([1.0, 2.0, 3.0])
        bc_types = np.array([1, 1, 0])
        bc_values = np.array([0.0, 0.0, 0.0])
        displacement_bc_scale = 1.0
        dt = 2.0

        # Set buffers
        # Read only
        bc_types_d = cl.Buffer(
            context, mf.READ_ONLY | mf.COPY_HOST_PTR,
            hostbuf=bc_types)
        bc_values_d = cl.Buffer(
            context, mf.READ_ONLY | mf.COPY_HOST_PTR,
            hostbuf=bc_values)
        force_d = cl.Buffer(
            context, mf.READ_WRITE | mf.COPY_HOST_PTR,
            hostbuf=force)
        u_d = cl.Buffer(
            context, mf.READ_WRITE | mf.COPY_HOST_PTR,
            hostbuf=u)

        # Build kernels
        update_displacement_kernel = program.update_displacement

        update_displacement_kernel(
            queue, (3 * nnodes,), None,
            force_d, u_d, bc_types_d, bc_values_d,
            np.float64(displacement_bc_scale), np.float64(dt))
        cl.enqueue_copy(queue, u, u_d)

        u_expected = np.array([0, 0, 6.0])
>       assert np.all(u == u_expected)
E       assert False
E        +  where False = <function all at 0x7fd1c01f11e0>(array([0., 4., 0.]) == array([0., 0., 6.])
E        +    where <function all at 0x7fd1c01f11e0> = np.all
E           Use -v to get the full diff)

peridynamics/test/test_cl_euler.py:146: AssertionError
___________________________________________________________________________________________ TestUpdateDisplacement.test_update_displacement4 ___________________________________________________________________________________________

self = <peridynamics.test.test_cl_euler.TestUpdateDisplacement object at 0x7fd200821320>, context = <pyopencl.Context at 0x7fd1aa42c460 on <pyopencl.Device 'AMD Radeon Pro 560X Compute Engine' on 'Apple' at 0x1021c00>>
queue = <pyopencl._cl.CommandQueue object at 0x7fd2007d67d8>, program = <pyopencl.Program object at 0x7fd200843550>

    @context_available
    def test_update_displacement4(self, context, queue, program):
        """Test displacement update with displacement B.C. scale."""
        u = np.zeros(3)
        nnodes = 1
        force = np.array([1.0, 2.0, 3.0])
        bc_types = np.array([1, 1, 0])
        bc_values = np.array([2.0, 2.0, 0.0])
        displacement_bc_scale = 0.5
        dt = 2.0

        # Set buffers
        # Read only
        bc_types_d = cl.Buffer(
            context, mf.READ_ONLY | mf.COPY_HOST_PTR,
            hostbuf=bc_types)
        bc_values_d = cl.Buffer(
            context, mf.READ_ONLY | mf.COPY_HOST_PTR,
            hostbuf=bc_values)
        force_d = cl.Buffer(
            context, mf.READ_WRITE | mf.COPY_HOST_PTR,
            hostbuf=force)
        u_d = cl.Buffer(
            context, mf.READ_WRITE | mf.COPY_HOST_PTR,
            hostbuf=u)

        # Build kernels
        update_displacement_kernel = program.update_displacement

        update_displacement_kernel(
            queue, (3 * nnodes,), None,
            force_d, u_d, bc_types_d, bc_values_d,
            np.float64(displacement_bc_scale), np.float64(dt))
        cl.enqueue_copy(queue, u, u_d)
        u_expected = np.array([1.0, 1.0, 6.0])
>       assert np.all(u == u_expected)
E       assert False
E        +  where False = <function all at 0x7fd1c01f11e0>(array([1., 4., 0.]) == array([1., 1., 6.])
E        +    where <function all at 0x7fd1c01f11e0> = np.all
E           Use -v to get the full diff)

peridynamics/test/test_cl_euler.py:183: AssertionError
___________________________________________________________________________________________ TestUpdateDisplacement.test_update_displacement3 ___________________________________________________________________________________________

self = <peridynamics.test.test_peridynamics.TestUpdateDisplacement object at 0x7fd1d09ef160>

    def test_update_displacement3(self):
        """Test displacement update with displacement boundary conditions."""
        nnodes = 3
        u = np.zeros((nnodes, 3))
        f = np.array([
            [1.0, 2.0, 3.0],
            [1.0, 2.0, 3.0],
            [1.0, 2.0, 3.0]])
        bc_types = np.array([
            [1, 1, 0],
            [1, 1, 0],
            [1, 1, 0]])
        bc_values = np.zeros((nnodes, 3))
        bc_scale = 1.0
        dt = 2.0
>       update_displacement(u, bc_values, bc_types, f, bc_scale, dt)

peridynamics/test/test_peridynamics.py:179: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

>   int[:, :] bc_types, double[:, :] force,
E   ValueError: Buffer dtype mismatch, expected 'int' but got 'long'

peridynamics/peridynamics.pyx:160: ValueError
___________________________________________________________________________________________ TestUpdateDisplacement.test_update_displacement4 ___________________________________________________________________________________________

self = <peridynamics.test.test_peridynamics.TestUpdateDisplacement object at 0x7fd1d09ef630>

    def test_update_displacement4(self):
        """Test displacement update with displacement B.C. scale."""
        nnodes = 3
        u = np.zeros((nnodes, 3))
        f = np.array([[1.0, 2.0, 3.0],
                      [1.0, 2.0, 3.0],
                      [1.0, 2.0, 3.0]])
        bc_types = np.array([[1, 1, 0],
                             [1, 1, 0],
                             [1, 1, 0]])
        bc_values = np.array([[2.0, 2.0, 0.0],
                              [2.0, 2.0, 0.0],
                              [2.0, 2.0, 0.0]])
        bc_scale = 0.5
        dt = 2.0
>       update_displacement(u, bc_values, bc_types, f, bc_scale, dt)

peridynamics/test/test_peridynamics.py:200: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

>   int[:, :] bc_types, double[:, :] force,
E   ValueError: Buffer dtype mismatch, expected 'int' but got 'long'

peridynamics/peridynamics.pyx:160: ValueError
======================================================================================================= short test summary info ========================================================================================================
FAILED peridynamics/test/test_cl_euler.py::TestUpdateDisplacement::test_update_displacement3 - assert False
FAILED peridynamics/test/test_cl_euler.py::TestUpdateDisplacement::test_update_displacement4 - assert False
FAILED peridynamics/test/test_peridynamics.py::TestUpdateDisplacement::test_update_displacement3 - ValueError: Buffer dtype mismatch, expected 'int' but got 'long'
FAILED peridynamics/test/test_peridynamics.py::TestUpdateDisplacement::test_update_displacement4 - ValueError: Buffer dtype mismatch, expected 'int' but got 'long'
============================================================================================== 4 failed, 150 passed, 2 skipped in 24.19s ===============================================================================================
gmingas commented 4 years ago

Regarding the Travis build, I can see that the error message when building pyopencl reads:

In file included from src/wrap_constants.cpp:30:0: src/wrap_cl.hpp:57:10: fatal error: CL/cl.h: No such file or directory

include <CL/cl.h>

^~~~~ compilation terminated. error: command 'gcc' failed with exit status 1

This is odd as it used to work before and I cannot see what change led to this. I found the following online, where it is recommended that you should either install pyopencl using conda (instead of pip) or that you could use pip install --upgrade pip setuptools wheel, although these do not work for everyone apparently. Also, you could try rolling back to the previous version of setup.py (removing hdf5) and any other files related to the setup, just in case. https://github.com/libtangle/qcgpu/issues/6 https://github.com/pydata/bottleneck/issues/281#issuecomment-560030902

gmingas commented 4 years ago

I tried a few things in this branch, the miniconda and pyopencl installations worked but I now get another error which seems to indicate that the hardware devices cannot be detected. @bb515 Take a look and let me know what you think.

gmingas commented 4 years ago

Running the examples (both 1 and 2) gives me the following error locally:

Traceback (most recent call last): File "example.py", line 11, in from pstats import SortKey, Stats ImportError: cannot import name 'SortKey'

bb515 commented 4 years ago

I ran the tests locally and 4 of them failed, see log below, you might not be seeing those in Travis as it fails to run due to the pyopencl issue:

Possibly fixed in this commit https://github.com/alan-turing-institute/Probabilistic-Peridynamics/pull/72/commits/0e8d8bf8279c0e2998d41f3fbe0989e3f9258a33 The tests originally being performed on a CPU, and not checked with a GPU. The dtype of the arrays used in the tests have been changed to be compatible with a GPU. The following dtypes were changed... In the opencl cases, 'int' was changed to 'intc', 'float' was changed to 'float64' In the cython case, 'int' dtypes were changed to 'int32'.

I have done the tests on a GPU now and they all seem to be working fine. Please re-run the tests on your local machine and let me know if this issue persists.

bb515 commented 4 years ago

Running the examples (both 1 and 2) gives me the following error locally:

Traceback (most recent call last): File "example.py", line 11, in from pstats import SortKey, Stats ImportError: cannot import name 'SortKey'

What version of python are you using? The readme says that this package requires Python 3.7+ This might be the issue: https://stackoverflow.com/questions/53490248/python-cprofile-error-importing-sortkey-from-pstats

bb515 commented 4 years ago

Regarding the Travis build, I can see that the error message when building pyopencl reads:

In file included from src/wrap_constants.cpp:30:0: src/wrap_cl.hpp:57:10: fatal error: CL/cl.h: No such file or directory

include <CL/cl.h>

^~~~~ compilation terminated. error: command 'gcc' failed with exit status 1

This is odd as it used to work before and I cannot see what change led to this. I found the following online, where it is recommended that you should either install pyopencl using conda (instead of pip) or that you could use pip install --upgrade pip setuptools wheel, although these do not work for everyone apparently. Also, you could try rolling back to the previous version of setup.py (removing hdf5) and any other files related to the setup, just in case. libtangle/qcgpu#6 pydata/bottleneck#281 (comment)

I have pushed a branch that is identical to the master branch here which results in the same build error. It seems that simply running the tests on the master branch again results in the same error, unless the act of pushing a clone of the branch from my laptop has broken the code in some way.

I will investigate by making the same changes you have made on fix_travis_setup, and open an issue.,

gmingas commented 4 years ago

Running the examples (both 1 and 2) gives me the following error locally:

Traceback (most recent call last): File "example.py", line 11, in from pstats import SortKey, Stats ImportError: cannot import name 'SortKey'

What version of python are you using? The readme says that this package requires Python 3.7+ This might be the issue: https://stackoverflow.com/questions/53490248/python-cprofile-error-importing-sortkey-from-pstats

True, we actually fixed this with Jim a couple of months ago by requiring python 3.7+

gmingas commented 4 years ago

@bb515 One other possibility for the errors in travis is some upstream change that broke the build, e.g. some newer version of pyopencl causes the issue, in which case it might work if you explicitly use an older version of the package in your travis script.

bb515 commented 4 years ago

@bb515 One other possibility for the errors in travis is some upstream change that broke the build, e.g. some newer version of pyopencl causes the issue, in which case it might work if you explicitly use an older version of the package in your travis script.

Yes, this was the issue. Working with 'pip install pyopencl==2020.1' but not working with 'pip install pyopencl==2020.2'. We can investigate why this is later, but for now I will explicitly install the 2020.1 version. Closing issue.

codecov-commenter commented 4 years ago

Codecov Report

Merging #72 into develop will decrease coverage by 8.91%. The diff coverage is 89.18%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop      #72      +/-   ##
===========================================
- Coverage    99.14%   90.22%   -8.92%     
===========================================
  Files            6        6              
  Lines          233      788     +555     
===========================================
+ Hits           231      711     +480     
- Misses           2       77      +75     
Impacted Files Coverage Δ
peridynamics/__init__.py 100.00% <ø> (ø)
peridynamics/model.py 87.10% <85.26%> (-12.90%) :arrow_down:
peridynamics/cl/utilities.py 91.66% <92.00%> (-3.58%) :arrow_down:
peridynamics/integrators.py 96.00% <95.89%> (-4.00%) :arrow_down:
peridynamics/cl/__init__.py 100.00% <100.00%> (ø)
peridynamics/utilities.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update b69f82a...e900aa2. Read the comment docs.

gmingas commented 4 years ago

Should the last part of examples/example2/example.py be cleaned (i.e. the commented lines)?

gmingas commented 4 years ago

@bb515 Also, one more thing: In the README.md, it help new users a lot to have an overview of the package and its capabilities in the first section (before Building and Installation). This should be a few sentences about what problems this package addresses (with some example applications and a note that many of those are computationally intensive and slow without using a gpu, etc) and then a list of bullet points with the main features: Supported pperidynamics systems, input file formats, supported integrators, boundary options, CPU/GPU options and anything else you think is important to know.

And then a copy of the example code you have in the docstring of the Model class which can serve as a front page demo (no need to make the code complete, just include the main/default workflow and simplify as much as possible).

gmingas commented 4 years ago

I think it has now shaped up very well, great work @bb515