Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cosym target: faster numpy operations #1639

Merged
merged 11 commits into from
Mar 30, 2021
Merged

Cosym target: faster numpy operations #1639

merged 11 commits into from
Mar 30, 2021

Conversation

rjgildea
Copy link
Contributor

Significant speedup of computation of cosym target functional, gradients and curvatures.

  • Use np.square(x) instead of np.power(x, 2)

  • Avoid explicit loops over number of dimensions

  • Functional now ~10x quicker

  • Gradients ~20x quicker

  • Curvatures ~4x quicker

For a real dials.cosym example, 44 datasets in P3121, this change cut about 25s off the total runtime:

real	1m18.899s
user	1m4.166s
sys	0m2.899s

real	0m52.221s
user	0m39.257s
sys	0m2.973s

rjgildea and others added 9 commits March 29, 2021 09:18
This is much faster and give ~6-fold speedup to target.compute_functional()
(based on Rij matrix of size 400x400).
Remove the need for one tmp variable, pre-declare another and re-use
by passing this as the `out=` parameter to np operations.
Remove need for explicit loop over number of dimensions
Avoid doubly nested loop over number of dimensions.
@rjgildea
Copy link
Contributor Author

@dwpaley it would be interesting to hear what performance impact this has on your use case.

@codecov
Copy link

codecov bot commented Mar 29, 2021

Codecov Report

Merging #1639 (4f9112a) into main (7cfb6ec) will decrease coverage by 0.01%.
The diff coverage is 100.00%.

❗ Current head 4f9112a differs from pull request most recent head f9b854d. Consider uploading reports for the commit f9b854d to get more accurate results

@@            Coverage Diff             @@
##             main    #1639      +/-   ##
==========================================
- Coverage   66.63%   66.62%   -0.02%     
==========================================
  Files         616      616              
  Lines       68949    68926      -23     
  Branches     9601     9593       -8     
==========================================
- Hits        45943    45920      -23     
  Misses      21070    21070              
  Partials     1936     1936              

Copy link
Member

@benjaminhwilliams benjaminhwilliams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen the algebra, so I can't check the consistency of the code with the desired arithmetic, but I presume that's not at question here. Changes look good and improve clarity, with a nice performance improvement. I have one small suggestion (affects two places). I haven't tested my suggestion though, so YMMV. Otherwise, LGTM.

algorithms/symmetry/cosym/target.py Outdated Show resolved Hide resolved
algorithms/symmetry/cosym/target.py Outdated Show resolved Hide resolved
ndevenish and others added 2 commits March 30, 2021 11:11
Co-authored-by: Ben Williams <benjaminhwilliams@users.noreply.github.com>
for i in range(self.dim):
grad[i * NN : (i + 1) * NN] = np.matmul(wrij_matrix, coords[i])
grad[i] = np.matmul(wrij_matrix, coords[i])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

matmul can also take stacks of matrices and would interpret it as such if coords dimensions is > 2. I think
grad = np.matmul(wrij_matrix, coords) should also work

Maybe for future considerations

@rjgildea rjgildea merged commit 1c8b68c into main Mar 30, 2021
@rjgildea rjgildea deleted the cosym-target-performance branch March 30, 2021 11:24
ndevenish pushed a commit that referenced this pull request Mar 31, 2021
Significant speedup of computation of cosym target functional, gradients and curvatures.

* Use np.square(x) instead of np.power(x, 2)
* Avoid explicit loops over number of dimensions

* Functional now ~10x quicker
* Gradients ~20x quicker
* Curvatures ~4x quicker
DiamondLightSource-build-server added a commit that referenced this pull request Mar 31, 2021
Features
--------

- ``dials.cosym``: Significantly faster via improved computation of functional, gradients and curvatures (#1639)
- ``dials.integrate``: Added parameter ``valid_foreground_threshold=``, to require a minimum fraction of valid pixels before profile fitting is attempted (#1640)

Bugfixes
--------

- ``dials.cosym``: Cache cases where Rij is undefined, rather than recalculating each time. This can have significant performance benefits when handling large numbers of sparse data sets. (#1634)
- ``dials.cosym``: Fix factor of 2 error when calculating target weights (#1635)
- ``dials.cosym``: Fix broken ``engine=scipy`` option (#1636)
- ``dials.integrate``: Reject reflections with a high number of invalid pixels, which were being integrated since 3.4.0. This restores better merging statistics, and prevents many reflections being incorrect profiled as zero-intensity. (#1640)
DiamondLightSource-build-server added a commit that referenced this pull request Apr 1, 2021
Features
--------

- ``dials.cosym``: Significantly faster via improved computation of functional, gradients and curvatures (#1639)
- ``dials.integrate``: Added parameter ``valid_foreground_threshold=``, to require a minimum fraction of valid pixels before profile fitting is attempted (#1640)

Bugfixes
--------

- ``dials.cosym``: Cache cases where Rij is undefined, rather than recalculating each time. This can have significant performance benefits when handling large numbers of sparse data sets. (#1634)
- ``dials.cosym``: Fix factor of 2 error when calculating target weights (#1635)
- ``dials.cosym``: Fix broken ``engine=scipy`` option (#1636)
- ``dials.integrate``: Reject reflections with a high number of invalid pixels, which were being integrated since 3.4.0. This restores better merging statistics, and prevents many reflections being incorrect profiled as zero-intensity. (#1640)
DiamondLightSource-build-server added a commit that referenced this pull request Apr 1, 2021
Features
--------

- ``dials.cosym``: Significantly faster via improved computation of functional, gradients and curvatures (#1639)
- ``dials.integrate``: Added parameter ``valid_foreground_threshold=``, to require a minimum fraction of valid pixels before profile fitting is attempted (#1640)

Bugfixes
--------

- ``dials.cosym``: Cache cases where Rij is undefined, rather than recalculating each time. This can have significant performance benefits when handling large numbers of sparse data sets. (#1634)
- ``dials.cosym``: Fix factor of 2 error when calculating target weights (#1635)
- ``dials.cosym``: Fix broken ``engine=scipy`` option (#1636)
- ``dials.integrate``: Reject reflections with a high number of invalid pixels, which were being integrated since 3.4.0. This restores better merging statistics, and prevents many reflections being incorrect profiled as zero-intensity. (#1640)
- Fix rare crash in symmetry calculations when no resolution limit could be calculated (#1641)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants