From a56aebc562725e024b4a448677e6718a9c5b96c4 Mon Sep 17 00:00:00 2001 From: Konstantin Malanchev Date: Thu, 13 Jun 2024 16:52:46 -0400 Subject: [PATCH 1/5] Docs: performance --- docs/_static/crossmatching-performance.png | Bin 0 -> 61012 bytes docs/index.rst | 1 + docs/performance.rst | 76 +++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 docs/_static/crossmatching-performance.png create mode 100644 docs/performance.rst diff --git a/docs/_static/crossmatching-performance.png b/docs/_static/crossmatching-performance.png new file mode 100644 index 0000000000000000000000000000000000000000..ee738d525cfc4455c73beac1a032163a9b27585b GIT binary patch literal 61012 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 literal 0 HcmV?d00001 diff --git a/docs/index.rst b/docs/index.rst index 03c5c061..c2e07a26 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -36,6 +36,7 @@ Learn more about contributing to this repository in our :doc:`Contribution Guide Installation Getting Started Tutorials + Performance .. toctree:: :hidden: diff --git a/docs/performance.rst b/docs/performance.rst new file mode 100644 index 00000000..a6cabccd --- /dev/null +++ b/docs/performance.rst @@ -0,0 +1,76 @@ +Performance +=========== + +LSDB is a high-performance package built to support the analysis of large-scale astronomical datasets. +One of the performance goals of LSDB is to add as little overhead over the input-output operations as possible. +We achieve this aim for catalog cross-matching, spatial and data filtering operations by using +the `HiPSCat `_ data format, +efficient algorithms, +and `Dask `_ framework for parallel computing. + +Here we demonstrate the results of the performance tests of LSDB for the cross-matching operations, +performed on `Bridges2 cluster at Pittsburgh Supercomputing Center `_ using single node with 128 cores and 256 GB of memory. + +Cross-matching performance overhead +----------------------------------- + +We compare I/O speed and cross-matching performance of LSDB on an example of cross-matching of +ZTF DR14 (metadata only, 1.2B rows, 60GB) +and Gaia DR3 (1.8B rows, 972GB) catalogs. +The cross-matching took 46 minutes and produced a catalog of 498GB. +While the cross-matching optimized reading of Gaia and didn't load southern part of the Gaia which doesn't overlap with ZTF, +we would judge the performance by the output size, which gives us 185MB/s of the cross-matching speed. + +We compare it to just copying both catalogs with `cp -r` command, which took 86 minutes and produced 1030GB of data, +which corresponds to 204MB/s of the copy speed. +These allow us to conclude that LSDB cross-matching overhead is 5-15% compared to the I/O operations. + +The details of this analysis are given in +`this note `_. + +LSDB's cross-matching algorithm performance versus other tools +-------------------------------------------------------------- + +We compare the performance of LSDB's default cross-matching algorithm with +`astropy`'s `match_coordinates_sky `_ +and `smatch `_ package. + +We use the same ZTF DR14 and Gaia DR3 catalogs as in the previous test, but we only use coordinate columns for the cross-matching. +With each algorithm, we perform the cross-matching of the catalogs within a 1 arcsecond radius, selecting the closest match. +To compare the performance on different scales, +we select subsets of the catalogs with cone search around an arbitrary point, +ranging the radius from 1 arcminute to 25 degrees. + +The analysis has the following steps: + +* Load the data from the HiPSCat format, selecting the subset of the data with ``lsdb.read_hipscat(PATH, columns=[RA_COL, DEC_COL]).cone_search(ra, dec, radius).compute()``. +* Perform the cross-matching with the selected algorithm + + * LSDB: ``ztf.crossmatch(gaia, radius_arcsec=1, n_neighbors=1).compute()`` + * Astropy analysis is two-step: + + * Initialize the ``SkyCoord`` objects for both catalogs + * Perform the cross-matching with ``match_coordinates_sky(ztf, gaia, nthneighbor=1)``, filter the results by 1-arcsencod radius, and compute distances + + * Smatch: ``smatch.match(ztf_ra, ztf_dec, 1/3600, gaia_ra, gaia_dec)``, and convert distances from cosines of the angles to arcseconds + +The results of the analysis are shown in the following plot: + +.. figure:: _static/crossmatching-performance.png + :class: no-scaled-link + :scale: 100 % + :align: center + :alt: Cross-matching performance comparison between LSDB, astropy, and smatch + +Some observations from the plot: + +* Construction of the ``SkyCoord`` objects in astropy is the most time-consuming step, on this step spherical coordinates are converted to Cartesian, so `match_coordinates_sky` has less work to do comparing to other algorithms. So if your analysis doesn't require the ``SkyCoord`` objects anywhere else, it would be more fair to add up the time of the `SkyCoord` objects construction and the `match_coordinates_sky` execution. +* All algorithms but LSDB have a nearly linear dependency on the number of rows in the input catalogs starting from a small number of rows. LSDB has a constant overhead associated with the graph construction and Dask overhead, which is negligible for large catalogs, where the time starts to grow linearly. +* LSDB is the only method allowing to parallelize the cross-matching operation, so we run it with 1, 4, 16, and 64 workers. +* 16 and 64-worker cases show the same performance, which shows the limits of the parallelization, at least with the hardware setup used in the analysis. +* Despite the fact that LSDB's crossmatching algorithm does more job converting spherical coordinates to Cartesian, it's getting faster than astropy's algorithm for the large catalogs, even with a single worker. This is probably due to the fact that LSDB utilises batching approach, which allows to grow less deep k-D trees for each partition of the data, and thus less time is spent on the tree traversal. + +Summarizing, the cross-matching approach implemented in LSDB is competitive with the existing tools and is more efficient for large catalogs, starting with roughly one million rows. +Also, LSDB allows to work with out-of-memory datasets, which is not possible with astropy and smatch, and not demonstrated in the analysis. + +The complete code of the analysis is available `here `_. From 5a8d04bb020b2da0da64bbeaab801a0d9a77883f Mon Sep 17 00:00:00 2001 From: Melissa DeLucchi <113376043+delucchi-cmu@users.noreply.github.com> Date: Fri, 14 Jun 2024 07:58:46 -0400 Subject: [PATCH 2/5] Update performance.rst Grammar-only --- docs/performance.rst | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/performance.rst b/docs/performance.rst index a6cabccd..afc0ee76 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -8,17 +8,18 @@ the `HiPSCat `_ data format, efficient algorithms, and `Dask `_ framework for parallel computing. -Here we demonstrate the results of the performance tests of LSDB for the cross-matching operations, -performed on `Bridges2 cluster at Pittsburgh Supercomputing Center `_ using single node with 128 cores and 256 GB of memory. +Here we demonstrate the results of the performance tests of LSDB for cross-matching operations, +performed on `Bridges2 cluster at Pittsburgh Supercomputing Center `_ +using a asingle node with 128 cores and 256 GB of memory. Cross-matching performance overhead ----------------------------------- -We compare I/O speed and cross-matching performance of LSDB on an example of cross-matching of +We compare I/O speed and cross-matching performance of LSDB on an example cross-matching of ZTF DR14 (metadata only, 1.2B rows, 60GB) and Gaia DR3 (1.8B rows, 972GB) catalogs. The cross-matching took 46 minutes and produced a catalog of 498GB. -While the cross-matching optimized reading of Gaia and didn't load southern part of the Gaia which doesn't overlap with ZTF, +While the cross-matching optimized reading of Gaia (and didn't load the southern part of Gaia which doesn't overlap with ZTF), we would judge the performance by the output size, which gives us 185MB/s of the cross-matching speed. We compare it to just copying both catalogs with `cp -r` command, which took 86 minutes and produced 1030GB of data, @@ -38,8 +39,8 @@ and `smatch `_ package. We use the same ZTF DR14 and Gaia DR3 catalogs as in the previous test, but we only use coordinate columns for the cross-matching. With each algorithm, we perform the cross-matching of the catalogs within a 1 arcsecond radius, selecting the closest match. To compare the performance on different scales, -we select subsets of the catalogs with cone search around an arbitrary point, -ranging the radius from 1 arcminute to 25 degrees. +we select subsets of the catalogs with a cone search around an arbitrary point, +increasing the radius from 1 arcminute to 25 degrees. The analysis has the following steps: @@ -64,13 +65,13 @@ The results of the analysis are shown in the following plot: Some observations from the plot: -* Construction of the ``SkyCoord`` objects in astropy is the most time-consuming step, on this step spherical coordinates are converted to Cartesian, so `match_coordinates_sky` has less work to do comparing to other algorithms. So if your analysis doesn't require the ``SkyCoord`` objects anywhere else, it would be more fair to add up the time of the `SkyCoord` objects construction and the `match_coordinates_sky` execution. +* Construction of the ``SkyCoord`` objects in astropy is the most time-consuming step; in this step spherical coordinates are converted to Cartesian, so `match_coordinates_sky` has less work to do comparing to other algorithms. So if your analysis doesn't require the ``SkyCoord`` objects anywhere else, it would be more fair to add up the time of the `SkyCoord` objects construction and the `match_coordinates_sky` execution. * All algorithms but LSDB have a nearly linear dependency on the number of rows in the input catalogs starting from a small number of rows. LSDB has a constant overhead associated with the graph construction and Dask overhead, which is negligible for large catalogs, where the time starts to grow linearly. * LSDB is the only method allowing to parallelize the cross-matching operation, so we run it with 1, 4, 16, and 64 workers. * 16 and 64-worker cases show the same performance, which shows the limits of the parallelization, at least with the hardware setup used in the analysis. -* Despite the fact that LSDB's crossmatching algorithm does more job converting spherical coordinates to Cartesian, it's getting faster than astropy's algorithm for the large catalogs, even with a single worker. This is probably due to the fact that LSDB utilises batching approach, which allows to grow less deep k-D trees for each partition of the data, and thus less time is spent on the tree traversal. +* Despite the fact that LSDB's crossmatching algorithm does similar work converting spherical coordinates to Cartesian, it's getting faster than astropy's algorithm for larger catalogs, even with a single worker. This is probably due to the fact that LSDB utilises a batching approach, which constructs shallower k-D trees for each partition of the data, and thus less time is spent on the tree traversal. Summarizing, the cross-matching approach implemented in LSDB is competitive with the existing tools and is more efficient for large catalogs, starting with roughly one million rows. -Also, LSDB allows to work with out-of-memory datasets, which is not possible with astropy and smatch, and not demonstrated in the analysis. +Also, LSDB allows work with out-of-memory datasets, which is not possible with astropy and smatch, and not demonstrated in the analysis. The complete code of the analysis is available `here `_. From 04c2c81befb03a154a1bf32b9bb91a32115bdf98 Mon Sep 17 00:00:00 2001 From: Konstantin Malanchev Date: Fri, 14 Jun 2024 08:13:44 -0400 Subject: [PATCH 3/5] fix rst style --- docs/performance.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/performance.rst b/docs/performance.rst index afc0ee76..96ec2114 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -65,7 +65,7 @@ The results of the analysis are shown in the following plot: Some observations from the plot: -* Construction of the ``SkyCoord`` objects in astropy is the most time-consuming step; in this step spherical coordinates are converted to Cartesian, so `match_coordinates_sky` has less work to do comparing to other algorithms. So if your analysis doesn't require the ``SkyCoord`` objects anywhere else, it would be more fair to add up the time of the `SkyCoord` objects construction and the `match_coordinates_sky` execution. +* Construction of the ``SkyCoord`` objects in astropy is the most time-consuming step; in this step spherical coordinates are converted to Cartesian, so ``match_coordinates_sky()`` has less work to do comparing to other algorithms. So if your analysis doesn't require the ``SkyCoord`` objects anywhere else, it would be more fair to add up the time of the ``SkyCoord`` objects construction and the ``match_coordinates_sky()`` execution. * All algorithms but LSDB have a nearly linear dependency on the number of rows in the input catalogs starting from a small number of rows. LSDB has a constant overhead associated with the graph construction and Dask overhead, which is negligible for large catalogs, where the time starts to grow linearly. * LSDB is the only method allowing to parallelize the cross-matching operation, so we run it with 1, 4, 16, and 64 workers. * 16 and 64-worker cases show the same performance, which shows the limits of the parallelization, at least with the hardware setup used in the analysis. From a9aa44ec5da31c3f782d0490e4256dfbbaa370ca Mon Sep 17 00:00:00 2001 From: Konstantin Malanchev Date: Fri, 14 Jun 2024 13:11:54 -0400 Subject: [PATCH 4/5] kdtree --- docs/performance.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/performance.rst b/docs/performance.rst index 96ec2114..b40406cd 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -35,6 +35,7 @@ LSDB's cross-matching algorithm performance versus other tools We compare the performance of LSDB's default cross-matching algorithm with `astropy`'s `match_coordinates_sky `_ and `smatch `_ package. +All three approaches use scipy's k-D tree implementation to find the nearest neighbor on a 3-D unit sphere. We use the same ZTF DR14 and Gaia DR3 catalogs as in the previous test, but we only use coordinate columns for the cross-matching. With each algorithm, we perform the cross-matching of the catalogs within a 1 arcsecond radius, selecting the closest match. From 13581e5de0245daf99131f1b31006f1b85b9c6e0 Mon Sep 17 00:00:00 2001 From: Konstantin Malanchev Date: Fri, 14 Jun 2024 16:53:26 -0400 Subject: [PATCH 5/5] Reword gaia-ztf overheads --- docs/performance.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/performance.rst b/docs/performance.rst index b40406cd..5be43d29 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -19,10 +19,9 @@ We compare I/O speed and cross-matching performance of LSDB on an example cross- ZTF DR14 (metadata only, 1.2B rows, 60GB) and Gaia DR3 (1.8B rows, 972GB) catalogs. The cross-matching took 46 minutes and produced a catalog of 498GB. -While the cross-matching optimized reading of Gaia (and didn't load the southern part of Gaia which doesn't overlap with ZTF), -we would judge the performance by the output size, which gives us 185MB/s of the cross-matching speed. +LSDB would read more data than it would write, so to get a lower boundary estimate we would use the output size, which gives us 185MB/s of the cross-matching speed. -We compare it to just copying both catalogs with `cp -r` command, which took 86 minutes and produced 1030GB of data, +We compare it to just copying both catalogs with ``cp -r`` command, which took 86 minutes and produced 1030GB of data, which corresponds to 204MB/s of the copy speed. These allow us to conclude that LSDB cross-matching overhead is 5-15% compared to the I/O operations. @@ -33,7 +32,7 @@ LSDB's cross-matching algorithm performance versus other tools -------------------------------------------------------------- We compare the performance of LSDB's default cross-matching algorithm with -`astropy`'s `match_coordinates_sky `_ +astropy's `match_coordinates_sky `_ and `smatch `_ package. All three approaches use scipy's k-D tree implementation to find the nearest neighbor on a 3-D unit sphere.