From cf1b05af6146ffcb9b8c02cee317fa2114c9590c Mon Sep 17 00:00:00 2001 From: Niklas Schmelzle Date: Tue, 28 Feb 2023 11:30:39 -0500 Subject: [PATCH 1/4] layout zeta precompute optimization with some extra code compare with old implementation --- src/algorithms/path_sgd_layout.cpp | 37 +++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/algorithms/path_sgd_layout.cpp b/src/algorithms/path_sgd_layout.cpp index 1c4bf19d..c50bd1e5 100644 --- a/src/algorithms/path_sgd_layout.cpp +++ b/src/algorithms/path_sgd_layout.cpp @@ -83,8 +83,11 @@ namespace odgi { iter_with_max_learning_rate, eps); - // cache zipf zetas for our full path space (heavy, but one-off) - std::vector zetas((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); + // cache zipf zetas for our full path space + auto start_zeta = std::chrono::high_resolution_clock::now(); + /* + // reference zeta computation + std::vector zetas_ref((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); uint64_t last_quantized_i = 0; #pragma omp parallel for schedule(static,1) for (uint64_t i = 1; i < space+1; ++i) { @@ -97,11 +100,39 @@ namespace odgi { if (quantized_i != last_quantized_i){ dirtyzipf::dirty_zipfian_int_distribution::param_type z_p(1, compressed_space, theta); - zetas[quantized_i] = z_p.zeta(); + zetas_ref[quantized_i] = z_p.zeta(); last_quantized_i = quantized_i; } } + */ + // fast zeta computation + std::vector zetas((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); + double zeta_tmp = 0.0; + for (uint64_t i = 1; i < space + 1; i++) { + zeta_tmp += dirtyzipf::fast_precise_pow(1.0 / i, theta); + if (i <= space_max) { + zetas[i] = zeta_tmp; + } + if (i >= space_max && (i - space_max) % space_quantization_step == 0) { + zetas[space_max + 1 + (i - space_max) / space_quantization_step] = zeta_tmp; + } + } + auto end_zeta = std::chrono::high_resolution_clock::now(); + uint32_t duration_zeta_ms = std::chrono::duration_cast(end_zeta - start_zeta).count(); + std::cout << "zeta precomputation took " << duration_zeta_ms << "ms" << std::endl; + + + /* + for (int i = 1; i < zetas.size(); i++) { + if (zetas[i] != zetas_ref[i]) { + std::cout << "WARNING[" << i << "]: " << zetas[i] << " vs " << zetas_ref[i] << std::endl; + } + } + + std::cout << zetas[zetas.size() - 1] << std::endl; + return; + */ // how many term updates we make std::atomic term_updates; From 90148a5f1c79e2ef820b9369f546fffe7109b5ba Mon Sep 17 00:00:00 2001 From: Niklas Schmelzle Date: Tue, 28 Feb 2023 11:36:56 -0500 Subject: [PATCH 2/4] clean up of zeta code in layout --- src/algorithms/path_sgd_layout.cpp | 38 ------------------------------ 1 file changed, 38 deletions(-) diff --git a/src/algorithms/path_sgd_layout.cpp b/src/algorithms/path_sgd_layout.cpp index c50bd1e5..e4de7cff 100644 --- a/src/algorithms/path_sgd_layout.cpp +++ b/src/algorithms/path_sgd_layout.cpp @@ -84,29 +84,6 @@ namespace odgi { eps); // cache zipf zetas for our full path space - auto start_zeta = std::chrono::high_resolution_clock::now(); - /* - // reference zeta computation - std::vector zetas_ref((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); - uint64_t last_quantized_i = 0; -#pragma omp parallel for schedule(static,1) - for (uint64_t i = 1; i < space+1; ++i) { - uint64_t quantized_i = i; - uint64_t compressed_space = i; - if (i > space_max){ - quantized_i = space_max + (i - space_max) / space_quantization_step + 1; - compressed_space = space_max + ((i - space_max) / space_quantization_step) * space_quantization_step; - } - - if (quantized_i != last_quantized_i){ - dirtyzipf::dirty_zipfian_int_distribution::param_type z_p(1, compressed_space, theta); - zetas_ref[quantized_i] = z_p.zeta(); - - last_quantized_i = quantized_i; - } - } - */ - // fast zeta computation std::vector zetas((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); double zeta_tmp = 0.0; for (uint64_t i = 1; i < space + 1; i++) { @@ -118,21 +95,6 @@ namespace odgi { zetas[space_max + 1 + (i - space_max) / space_quantization_step] = zeta_tmp; } } - auto end_zeta = std::chrono::high_resolution_clock::now(); - uint32_t duration_zeta_ms = std::chrono::duration_cast(end_zeta - start_zeta).count(); - std::cout << "zeta precomputation took " << duration_zeta_ms << "ms" << std::endl; - - - /* - for (int i = 1; i < zetas.size(); i++) { - if (zetas[i] != zetas_ref[i]) { - std::cout << "WARNING[" << i << "]: " << zetas[i] << " vs " << zetas_ref[i] << std::endl; - } - } - - std::cout << zetas[zetas.size() - 1] << std::endl; - return; - */ // how many term updates we make std::atomic term_updates; From 0de7406f8b89789487166800b148c7349f325c4d Mon Sep 17 00:00:00 2001 From: Niklas Schmelzle Date: Tue, 28 Feb 2023 12:08:03 -0500 Subject: [PATCH 3/4] sort zeta precompute optimizations with reference implementation for comparison --- src/algorithms/path_sgd.cpp | 43 +++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/algorithms/path_sgd.cpp b/src/algorithms/path_sgd.cpp index 45f2d2c3..604f30a3 100644 --- a/src/algorithms/path_sgd.cpp +++ b/src/algorithms/path_sgd.cpp @@ -121,12 +121,18 @@ namespace odgi { iter_with_max_learning_rate, eps); - // cache zipf zetas for our full path space (heavy, but one-off) + // cache zipf zetas for our full path space if (progress) { std::cerr << "[odgi::path_linear_sgd] calculating zetas for " << (space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1) << " zipf distributions" << std::endl; } - - std::vector zetas((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); + std::cout << "space: " << space << std::endl; + std::cout << "space_max: " << space_max << std::endl; + std::cout << "space_quantization_step: " << space_quantization_step << std::endl; + + auto start_zeta = std::chrono::high_resolution_clock::now(); + /* + // reference zeta computation + std::vector zetas_ref((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); uint64_t last_quantized_i = 0; #pragma omp parallel for schedule(static,1) for (uint64_t i = 1; i < space+1; ++i) { @@ -139,11 +145,40 @@ namespace odgi { if (quantized_i != last_quantized_i){ dirtyzipf::dirty_zipfian_int_distribution::param_type z_p(1, compressed_space, theta); - zetas[quantized_i] = z_p.zeta(); + zetas_ref[quantized_i] = z_p.zeta(); last_quantized_i = quantized_i; } } + */ + // fast zeta computation + std::vector zetas((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); + double zeta_tmp = 0.0; + for (uint64_t i = 1; i < space + 1; i++) { + zeta_tmp += dirtyzipf::fast_precise_pow(1.0 / i, theta); + if (i <= space_max) { + zetas[i] = zeta_tmp; + } + if (i >= space_max && (i - space_max) % space_quantization_step == 0) { + zetas[space_max + 1 + (i - space_max) / space_quantization_step] = zeta_tmp; + } + } + auto end_zeta = std::chrono::high_resolution_clock::now(); + uint32_t duration_zeta_ms = std::chrono::duration_cast(end_zeta - start_zeta).count(); + std::cout << "zeta precomputation took " << duration_zeta_ms << "ms" << std::endl; + + + /* + for (int i = 1; i < zetas.size(); i++) { + if (zetas[i] != zetas_ref[i]) { + std::cout << "WARNING[" << i << "]: " << zetas[i] << " vs " << zetas_ref[i] << std::endl; + } + } + + std::cout << zetas[zetas.size() - 1] << std::endl; + std::vector X_tmp(X.size()); + return X_tmp; + */ // how many term updates we make std::atomic term_updates; From dc812334b8b8cc8b66a9ae5627aba02f05ed6683 Mon Sep 17 00:00:00 2001 From: Niklas Schmelzle Date: Tue, 28 Feb 2023 12:10:19 -0500 Subject: [PATCH 4/4] sort zeta precompute clean up --- src/algorithms/path_sgd.cpp | 43 ------------------------------------- 1 file changed, 43 deletions(-) diff --git a/src/algorithms/path_sgd.cpp b/src/algorithms/path_sgd.cpp index 604f30a3..11d68a84 100644 --- a/src/algorithms/path_sgd.cpp +++ b/src/algorithms/path_sgd.cpp @@ -125,33 +125,6 @@ namespace odgi { if (progress) { std::cerr << "[odgi::path_linear_sgd] calculating zetas for " << (space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1) << " zipf distributions" << std::endl; } - std::cout << "space: " << space << std::endl; - std::cout << "space_max: " << space_max << std::endl; - std::cout << "space_quantization_step: " << space_quantization_step << std::endl; - - auto start_zeta = std::chrono::high_resolution_clock::now(); - /* - // reference zeta computation - std::vector zetas_ref((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); - uint64_t last_quantized_i = 0; -#pragma omp parallel for schedule(static,1) - for (uint64_t i = 1; i < space+1; ++i) { - uint64_t quantized_i = i; - uint64_t compressed_space = i; - if (i > space_max){ - quantized_i = space_max + (i - space_max) / space_quantization_step + 1; - compressed_space = space_max + ((i - space_max) / space_quantization_step) * space_quantization_step; - } - - if (quantized_i != last_quantized_i){ - dirtyzipf::dirty_zipfian_int_distribution::param_type z_p(1, compressed_space, theta); - zetas_ref[quantized_i] = z_p.zeta(); - - last_quantized_i = quantized_i; - } - } - */ - // fast zeta computation std::vector zetas((space <= space_max ? space : space_max + (space - space_max) / space_quantization_step + 1)+1); double zeta_tmp = 0.0; for (uint64_t i = 1; i < space + 1; i++) { @@ -163,22 +136,6 @@ namespace odgi { zetas[space_max + 1 + (i - space_max) / space_quantization_step] = zeta_tmp; } } - auto end_zeta = std::chrono::high_resolution_clock::now(); - uint32_t duration_zeta_ms = std::chrono::duration_cast(end_zeta - start_zeta).count(); - std::cout << "zeta precomputation took " << duration_zeta_ms << "ms" << std::endl; - - - /* - for (int i = 1; i < zetas.size(); i++) { - if (zetas[i] != zetas_ref[i]) { - std::cout << "WARNING[" << i << "]: " << zetas[i] << " vs " << zetas_ref[i] << std::endl; - } - } - - std::cout << zetas[zetas.size() - 1] << std::endl; - std::vector X_tmp(X.size()); - return X_tmp; - */ // how many term updates we make std::atomic term_updates;