From 302761d6af99a70563c54f3ccff17b55cebcca73 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 28 Jun 2024 23:47:02 +0200 Subject: [PATCH] updated single file measurements --- notebooks/2.1_Single-file.ipynb | 906 +++++++++++++++++++++++++++++--- src/time_profiler.py | 3 +- 2 files changed, 830 insertions(+), 79 deletions(-) diff --git a/notebooks/2.1_Single-file.ipynb b/notebooks/2.1_Single-file.ipynb index 8789f17..e2cff51 100644 --- a/notebooks/2.1_Single-file.ipynb +++ b/notebooks/2.1_Single-file.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "48f3f61b-839b-4ae2-9635-3b81e805ca67", "metadata": {}, "outputs": [], @@ -25,7 +25,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "99d4efd9-9672-4590-ac41-a6013b3d8e22", "metadata": {}, "outputs": [], @@ -50,7 +50,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "87efdb93-f8c3-4fba-953a-5fa6e2bae407", "metadata": {}, "outputs": [], @@ -58,10 +58,10 @@ "file_name = \"90322FC2-4027-0E47-92E4-22307EC8EAD2.root\"\n", "file_locations = {\n", " \"depot\": \"/depot/cms/users/dkondra/\",\n", - " # \"work\": \"/work/projects/purdue-af/\",\n", - " # \"eos_fuse\": \"/eos/purdue/store/data/Run2016B/SingleMuon/NANOAOD/02Apr2020_ver2-v1/20000/\",\n", - " # \"xrootd\": \"root://eos.cms.rcac.purdue.edu:1094//store/data/Run2016B/SingleMuon/NANOAOD/02Apr2020_ver2-v1/20000/\",\n", - " # \"xcache\": \"root://cms-xcache.rcac.purdue.edu:1094//store/data/Run2016B/SingleMuon/NANOAOD/02Apr2020_ver2-v1/20000/\"\n", + " \"work\": \"/work/projects/purdue-af/\",\n", + " \"eos_fuse\": \"/eos/purdue/store/data/Run2016B/SingleMuon/NANOAOD/02Apr2020_ver2-v1/20000/\",\n", + " \"xrootd\": \"root://eos.cms.rcac.purdue.edu:1094//store/data/Run2016B/SingleMuon/NANOAOD/02Apr2020_ver2-v1/20000/\",\n", + " \"xcache\": \"root://cms-xcache.rcac.purdue.edu:1094//store/data/Run2016B/SingleMuon/NANOAOD/02Apr2020_ver2-v1/20000/\"\n", "}\n", "\n", "column_presets = {\n", @@ -70,29 +70,29 @@ " # \"method\": \"n_columns\",\n", " # \"values\": 100000\n", " # },\n", - " \"50pct\": {\n", - " \"method\": \"collections\",\n", - " \"values\": [\"Jet\", \"Photon\", \"Tau\", \"Electron\", \"Muon\"]\n", - " },\n", - " # \"10pct\": {\n", + " # \"50pct\": {\n", " # \"method\": \"collections\",\n", - " # \"values\": [\"Muon\"]\n", + " # \"values\": [\"Jet\", \"Photon\", \"Tau\", \"Electron\", \"Muon\"]\n", " # },\n", - " # \"5pct\": {\n", - " # \"method\": \"column_list\",\n", - " # \"values\": [\n", - " # \"run\", \"luminosityBlock\", \"HLT_IsoMu24\", \"PV_npvsGood\", \"fixedGridRhoFastjetAll\",\n", - " # \"Muon_pt\", \"Muon_eta\", \"Muon_phi\", \"Muon_mass\", \"Muon_charge\", \"Muon_pfRelIso04_all\", \"Muon_mediumId\", \"Muon_ptErr\",\n", - " # \"Electron_pt\", \"Electron_eta\", \"Electron_mvaFall17V2Iso_WP90\",\n", - " # \"Jet_pt\", \"Jet_eta\", \"Jet_phi\", \"Jet_mass\",\n", - " # ]\n", - " # }\n", + " \"10pct\": {\n", + " \"method\": \"collections\",\n", + " \"values\": [\"Muon\"]\n", + " },\n", + " \"5pct\": {\n", + " \"method\": \"column_list\",\n", + " \"values\": [\n", + " \"run\", \"luminosityBlock\", \"HLT_IsoMu24\", \"PV_npvsGood\", \"fixedGridRhoFastjetAll\",\n", + " \"Muon_pt\", \"Muon_eta\", \"Muon_phi\", \"Muon_mass\", \"Muon_charge\", \"Muon_pfRelIso04_all\", \"Muon_mediumId\", \"Muon_ptErr\",\n", + " \"Electron_pt\", \"Electron_eta\", \"Electron_mvaFall17V2Iso_WP90\",\n", + " \"Jet_pt\", \"Jet_eta\", \"Jet_phi\", \"Jet_mass\",\n", + " ]\n", + " }\n", "}" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "b437563d-da50-4bda-829b-eeb4218b03f2", "metadata": {}, "outputs": [], @@ -101,85 +101,846 @@ " recreate_dir(save_dir)\n", "\n", " iconf = 0\n", + " repeat = 3\n", "\n", " for f_label, file_loc in file_locations.items():\n", " for c_label, column_setup in column_presets.items():\n", - " config = copy.deepcopy(default_config)\n", - "\n", - " config[\"data-access\"][\"files\"] = [f\"{file_loc}/{file_name}\"]\n", - " config[\"processor\"][\"columns\"] = column_setup\n", - "\n", - " # Custom labels to save to output dataframe\n", - " config[\"custom_labels\"] = {\n", - " \"file_location\": f_label,\n", - " \"column_setup\": c_label\n", - " }\n", - "\n", - " config_name = f'config2p1_{iconf}_{f_label}_{c_label}.yaml'\n", - " \n", - " with open(f'{save_dir}/{config_name}', 'w') as file:\n", - " yaml.dump(config, file, default_flow_style=False)\n", - "\n", - " iconf += 1\n", + " for irep in range(repeat):\n", + " config = copy.deepcopy(default_config)\n", + " \n", + " config[\"data-access\"][\"files\"] = [f\"{file_loc}/{file_name}\"]\n", + " config[\"processor\"][\"columns\"] = column_setup\n", + " \n", + " # Custom labels to save to output dataframe\n", + " config[\"custom_labels\"] = {\n", + " \"file_location\": f_label,\n", + " \"column_setup\": c_label\n", + " }\n", + " \n", + " unique_label = f\"2p1_{f_label}_{c_label}_{irep}\"\n", + " \n", + " config[\"unique_label\"] = unique_label\n", + " config_name = f'config_{unique_label}.yaml'\n", + " \n", + " with open(f'{save_dir}/{config_name}', 'w') as file:\n", + " yaml.dump(config, file, default_flow_style=False)\n", + " \n", + " iconf += 1\n", "\n", " print(f'Saved {iconf} config files to {save_dir}')" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "574dea64-da4b-4fba-b610-1dfc734ec077", "metadata": {}, "outputs": [], "source": [ - "# warning: all YAML files will be deleted fron this directory before proceeding\n", - "config_path = \"./configs_2.1\"" + "# warning: all YAML files will be deleted from config directory before proceeding\n", + "config_path = \"./configs_2.1\"\n", + "output_path = \"./outputs_2.1\"" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "8633cf12-d9d9-4201-8969-e40868ee2e65", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Directory ./configs_2.1 already exists, will clean all files from it.\n", + "Saved 30 config files to ./configs_2.1\n" + ] + } + ], "source": [ "generate_configs(config_path)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "d0ed6b4f-1ce8-4731-87e7-57da3b4abced", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Directory ./outputs_2.1 already exists, will clean all files from it.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 30/30 [17:30<00:00, 35.01s/it]\n" + ] + } + ], "source": [ - "# report = run_benchmark(config_path)\n", - "import cProfile\n", - "cProfile.run('run_benchmark(config_path)', 'profile_output.prof')" + "report = run_benchmark(config_path, output_path)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, + "id": "461346ea-e348-4dbf-bbb3-4420247166aa", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
n_filesn_columns_readn_eventsloaded_columnsworker_operation_timeexecutorn_workerscompressed_bytesuncompressed_bytestime:run_processortime:waittime:decompresscolumn_setupfile_location
0150154321550True0sequential1265594188112903146730.4599310.03056324.06138810pctdepot
1150154321550True0sequential1265594188112903146730.5063490.03106824.12822810pctdepot
2150154321550True0sequential1265594188112903146730.4621170.03079224.09752210pctdepot
3150154321550True0sequential1265594188112903146730.5133770.03053824.04835010pcteos_fuse
4150154321550True0sequential1265594188112903146730.4420810.03083324.08073010pcteos_fuse
5150154321550True0sequential1265594188112903146730.5330580.03070324.07665810pcteos_fuse
6150154321550True0sequential1265594188112903146734.8931340.03074724.20137310pctwork
7150154321550True0sequential1265594188112903146730.5394640.03059624.14010210pctwork
8150154321550True0sequential1265594188112903146730.5691130.03050724.16418510pctwork
9150154321550True0sequential1265594188112903146732.9279190.32001524.19859710pctxcache
10150154321550True0sequential1265594188112903146733.0328400.31636224.16884910pctxcache
11150154321550True0sequential1265594188112903146733.0515790.58223624.13211610pctxcache
12150154321550True0sequential12655941881129031467104.77227172.21338124.16407010pctxrootd
13150154321550True0sequential1265594188112903146762.81157530.29116324.13210910pctxrootd
14150154321550True0sequential1265594188112903146755.18022723.01428124.13168510pctxrootd
1512061728620True0sequential117548891252175309016.6488960.01054813.2573225pctdepot
1612061728620True0sequential117548891252175309016.2398490.01068213.2303325pctdepot
1712061728620True0sequential117548891252175309016.2747370.01065413.2359205pctdepot
1812061728620True0sequential117548891252175309016.1943980.01059513.2205225pcteos_fuse
1912061728620True0sequential117548891252175309016.2175560.01069913.2400245pcteos_fuse
2012061728620True0sequential117548891252175309016.1414980.01058213.2362675pcteos_fuse
2112061728620True0sequential117548891252175309016.2056290.01078013.2846105pctwork
2212061728620True0sequential117548891252175309016.1788970.01070413.2673685pctwork
2312061728620True0sequential117548891252175309016.3418410.01081813.3273475pctwork
2412061728620True0sequential117548891252175309017.0736310.22674413.2673855pctxcache
2512061728620True0sequential117548891252175309017.1487250.20183013.2626595pctxcache
2612061728620True0sequential117548891252175309017.1893370.21666513.2827495pctxcache
2712061728620True0sequential117548891252175309069.02672052.12725713.2727055pctxrootd
2812061728620True0sequential117548891252175309060.01388943.19848413.2592635pctxrootd
2912061728620True0sequential117548891252175309072.99948356.16232913.2681135pctxrootd
\n", + "
" + ], + "text/plain": [ + " n_files n_columns_read n_events loaded_columns worker_operation_time \\\n", + "0 1 50 154321550 True 0 \n", + "1 1 50 154321550 True 0 \n", + "2 1 50 154321550 True 0 \n", + "3 1 50 154321550 True 0 \n", + "4 1 50 154321550 True 0 \n", + "5 1 50 154321550 True 0 \n", + "6 1 50 154321550 True 0 \n", + "7 1 50 154321550 True 0 \n", + "8 1 50 154321550 True 0 \n", + "9 1 50 154321550 True 0 \n", + "10 1 50 154321550 True 0 \n", + "11 1 50 154321550 True 0 \n", + "12 1 50 154321550 True 0 \n", + "13 1 50 154321550 True 0 \n", + "14 1 50 154321550 True 0 \n", + "15 1 20 61728620 True 0 \n", + "16 1 20 61728620 True 0 \n", + "17 1 20 61728620 True 0 \n", + "18 1 20 61728620 True 0 \n", + "19 1 20 61728620 True 0 \n", + "20 1 20 61728620 True 0 \n", + "21 1 20 61728620 True 0 \n", + "22 1 20 61728620 True 0 \n", + "23 1 20 61728620 True 0 \n", + "24 1 20 61728620 True 0 \n", + "25 1 20 61728620 True 0 \n", + "26 1 20 61728620 True 0 \n", + "27 1 20 61728620 True 0 \n", + "28 1 20 61728620 True 0 \n", + "29 1 20 61728620 True 0 \n", + "\n", + " executor n_workers compressed_bytes uncompressed_bytes \\\n", + "0 sequential 1 265594188 1129031467 \n", + "1 sequential 1 265594188 1129031467 \n", + "2 sequential 1 265594188 1129031467 \n", + "3 sequential 1 265594188 1129031467 \n", + "4 sequential 1 265594188 1129031467 \n", + "5 sequential 1 265594188 1129031467 \n", + "6 sequential 1 265594188 1129031467 \n", + "7 sequential 1 265594188 1129031467 \n", + "8 sequential 1 265594188 1129031467 \n", + "9 sequential 1 265594188 1129031467 \n", + "10 sequential 1 265594188 1129031467 \n", + "11 sequential 1 265594188 1129031467 \n", + "12 sequential 1 265594188 1129031467 \n", + "13 sequential 1 265594188 1129031467 \n", + "14 sequential 1 265594188 1129031467 \n", + "15 sequential 1 175488912 521753090 \n", + "16 sequential 1 175488912 521753090 \n", + "17 sequential 1 175488912 521753090 \n", + "18 sequential 1 175488912 521753090 \n", + "19 sequential 1 175488912 521753090 \n", + "20 sequential 1 175488912 521753090 \n", + "21 sequential 1 175488912 521753090 \n", + "22 sequential 1 175488912 521753090 \n", + "23 sequential 1 175488912 521753090 \n", + "24 sequential 1 175488912 521753090 \n", + "25 sequential 1 175488912 521753090 \n", + "26 sequential 1 175488912 521753090 \n", + "27 sequential 1 175488912 521753090 \n", + "28 sequential 1 175488912 521753090 \n", + "29 sequential 1 175488912 521753090 \n", + "\n", + " time:run_processor time:wait time:decompress column_setup file_location \n", + "0 30.459931 0.030563 24.061388 10pct depot \n", + "1 30.506349 0.031068 24.128228 10pct depot \n", + "2 30.462117 0.030792 24.097522 10pct depot \n", + "3 30.513377 0.030538 24.048350 10pct eos_fuse \n", + "4 30.442081 0.030833 24.080730 10pct eos_fuse \n", + "5 30.533058 0.030703 24.076658 10pct eos_fuse \n", + "6 34.893134 0.030747 24.201373 10pct work \n", + "7 30.539464 0.030596 24.140102 10pct work \n", + "8 30.569113 0.030507 24.164185 10pct work \n", + "9 32.927919 0.320015 24.198597 10pct xcache \n", + "10 33.032840 0.316362 24.168849 10pct xcache \n", + "11 33.051579 0.582236 24.132116 10pct xcache \n", + "12 104.772271 72.213381 24.164070 10pct xrootd \n", + "13 62.811575 30.291163 24.132109 10pct xrootd \n", + "14 55.180227 23.014281 24.131685 10pct xrootd \n", + "15 16.648896 0.010548 13.257322 5pct depot \n", + "16 16.239849 0.010682 13.230332 5pct depot \n", + "17 16.274737 0.010654 13.235920 5pct depot \n", + "18 16.194398 0.010595 13.220522 5pct eos_fuse \n", + "19 16.217556 0.010699 13.240024 5pct eos_fuse \n", + "20 16.141498 0.010582 13.236267 5pct eos_fuse \n", + "21 16.205629 0.010780 13.284610 5pct work \n", + "22 16.178897 0.010704 13.267368 5pct work \n", + "23 16.341841 0.010818 13.327347 5pct work \n", + "24 17.073631 0.226744 13.267385 5pct xcache \n", + "25 17.148725 0.201830 13.262659 5pct xcache \n", + "26 17.189337 0.216665 13.282749 5pct xcache \n", + "27 69.026720 52.127257 13.272705 5pct xrootd \n", + "28 60.013889 43.198484 13.259263 5pct xrootd \n", + "29 72.999483 56.162329 13.268113 5pct xrootd " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "report.sort_values(by=['column_setup', 'file_location']).reset_index(drop=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, "id": "c0a788da-d160-4c81-95ea-150ef4d9a85e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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rlw5+Pr64sSJE5gzZw4++OADAI8OX40cORLBwcGoUqUKqlSpguDgYNjZ2aFHjx4Grp6IiIiMgVGHnYULF+Lzzz/H4MGDER8fDw8PDwwcOBCTJk1Slhk/fjxSU1MxePBgJCQkoHHjxggNDYWDg4MBKyciIiJjoRERMXQRhpaUlAQnJyckJibC0dHR0OUQEREZXEpGFnwm7QIAnJvaBnZWxtc/kt+/30Y9ZoeIiIjoRTHsEBERkaox7BAREZGqMewQERGRqjHsEBERkaox7BAREZGqMewQERGRqjHsEBERkaox7BAREZGqMewQERGRqjHsEBERkaoZ340uiIiI6IV1WLgfd5PTC7y+9rFbZ/rPCoeZRvNC9ZRysMaWYa++0GsUFMMOET23+KQ0xD/HTtTVwRqujjaFWBER/dfd5HTEJaXp5bWep70bI4YdInpuq4/cxPywy/lefkTLKhgV4F2IFRHRk5hpAFeH5/+yoRVRQo6rg3WBe3bik9OglWcvV5gYdojoufVsXA4BPm7K87TMbHRZcggAsGGQH2wszXWWd3WwLtL6iOhfrg42OPxpy+deLyUjCz6TdgEAwsf5w86qYJHhleAwvfUwFRTDDhE9N1dHG53DUikZWcrPPh6OBd4pEhEVBp6NRURERKrGsENERESqxrBDREREqsawQ0RERKrGsENERESqxrBDREREqsawQ0RERKrGsENERESqxrBDREREqsawQ0RERKrGsENERESqxrBDREREqsawQ0RERKrGsENERESqxrBDREREqsawQ0RERKrGsENERESqxrBDREREqmZh6AKIyPA6LNyPu8npBV5fK6L87D8rHGYazQvVU8rBGluGvfpCr0FElINhh4hwNzkdcUlpenmt+BcITUREhYFhh4gUZhrA1cHmudfTiighx9XBusA9O/HJadDKs5cjInoeDDtEpHB1sMHhT1s+93opGVnwmbQLABA+zh92VgXbtbwSHKa3HiYiohwcoExERESqxrBDREREqsbDWERERGqWdBsIcnr+9cQawIpHP0/3ADQFPPkgbSEAl4Ktqyfs2SEiIiJVY9ghIiIiVWPYISIiIlVj2CEiIiJVY9ghIiIiVWPYISIiIlXjqedE9C+eokpEKsSeHSIiIlI1hh0iIiJSNYYdIiIiUrUCj9mJiYnB9evXkZKSglKlSsHX1xfW1tb6rI2IiIjohT1X2Llx4waWLFmCtWvXIiYmBiKizLOyssJrr72GAQMGoHPnzjAzY6cRERERGV6+E8mIESNQs2ZNXL58GVOnTsXZs2eRmJiIjIwMxMXFYfv27Xj11Vfx+eefo1atWoiMjCzMuomIiIjyJd89O1ZWVrh69SpKlSqVa56rqytef/11vP7665g8eTK2b9+OGzduoGHDhnotloiIiOh55TvszJo1K98v2r59+wIVQ0RERKRvBRpYk5qaipSUFOX5jRs3MG/ePOzatUtvhRERERHpQ4HCTseOHfHDDz8AAO7fv4/GjRtj9uzZ6NSpExYvXqzXAm/fvo333nsPLi4usLOzQ506dRAVFaXMFxEEBQXBw8MDtra28Pf3x9mzZ/VaAxHpihdnnNF6KY9z2vLKvHPa8jrzzmi9EC/OhiuWiF56BTr1/Pjx45g7dy4AYMOGDXBzc8OJEyewceNGTJo0CR999JFeiktISEDTpk3RokUL7NixA66urrh69SqcnZ2VZWbOnIk5c+Zg5cqV8Pb2xrRp0xAQEICLFy/CwcFBL3UQka7VWS0xP7tznvO6ZAblmjbCfCNGWW4s5KqIiPJWoLCTkpKiBInQ0FAEBgbCzMwMr7zyCm7cuKG34r788kt4enpixYoVyjQvLy/lZxHBvHnzMHHiRAQGBgIAQkJC4ObmhjVr1mDgwIF5vm56ejrS0/+9d09SUpLeaiZ6GfS0CEOAedSzF/x/rpr7hVcMEdEzFOgwVuXKlfHLL78gJiYGu3btQuvWrQEA8fHxcHR01Ftxv/32Gxo0aICuXbvC1dUVdevWxfLly5X50dHRiIuLU7YPANbW1mjevDkOHjz4xNedMWMGnJyclIenp6feaiZ6Gbhq7qOG2fV8Pxh2iMiQChR2Jk2ahLFjx8LLywuNGzeGn58fgEe9PHXr1tVbcdeuXcPixYtRpUoV7Nq1C4MGDcLw4cOV8UJxcXEAADc3N5313NzclHl5mTBhAhITE5VHTEyM3momIiIi41Kgw1hdunTBq6++itjYWNSuXVuZ3rJlS7z99tt6K06r1aJBgwYIDg4GANStWxdnz57F4sWL0atXL2U5jUajs56I5Jr2OGtra97agoiI6CVR4Hs6uLu7o27dujq3hWjUqBGqVauml8IAoHTp0vDx8dGZVr16ddy8eVOpAUCuXpz4+PhcvT1ERET0csp32Bk0aFC+D/f89NNPWL16dYGLytG0aVNcvHhRZ9qlS5dQvvyj01wrVKgAd3d37N69W5mfkZGBiIgINGnS5IW3T0RERKYv34exSpUqhRo1aqBJkyZ466230KBBA3h4eMDGxgYJCQk4d+4c9u/fj3Xr1qFMmTJYtmzZCxc3atQoNGnSBMHBwejWrRuOHj2KZcuWKa+t0WgwcuRIBAcHo0qVKqhSpQqCg4NhZ2eHHj16vPD2iYiIyPTlO+z873//w7Bhw/Ddd99hyZIlOHPmjM58BwcHtGrVCt9++63O2VEvomHDhti8eTMmTJiAqVOnokKFCpg3bx569uypLDN+/HikpqZi8ODBSEhIQOPGjREaGspr7BARERGA5xyg7OrqigkTJmDChAm4f/8+bty4gdTUVJQsWRKVKlV66qDggnrzzTfx5ptvPnG+RqNBUFAQgoKC9L5tIiIiMn0FOhsLAJydnXWuZExERERkjAp8NhYRERGRKWDYISIiIlVj2CEiIiJVY9ghIiIiVStw2MnKysLvv/+OpUuXIjk5GQBw584dPHjwQG/FEREREb2oAp2NdePGDbRt2xY3b95Eeno6AgIC4ODggJkzZyItLQ1LlizRd51EREREBVKgnp0RI0agQYMGSEhIgK2trTL97bffRlhYmN6KIyIiInpRBerZ2b9/Pw4cOAArKyud6eXLl8ft27f1UhgRERGRPhSoZ0er1SI7OzvX9Fu3bvE2DURERGRUChR2AgICMG/ePOW5RqPBgwcPMHnyZLRv315ftRERERG9sAIdxpo7dy5atGgBHx8fpKWloUePHrh8+TJKliyJtWvX6rtGIiIiogIrUNjx8PDAyZMnsXbtWhw/fhxarRb9+vVDz549dQYsExERERlagW8Eamtriw8++AAffPCBPushIiIi0qsCh53bt2/jwIEDiI+Ph1ar1Zk3fPjwFy6MiIiISB8KFHZWrFiBQYMGwcrKCi4uLtBoNMo8jUbDsENERERGo0BhZ9KkSZg0aRImTJgAMzPeXouIiIiMV4GSSkpKCt59910GHSIiIjJ6BUor/fr1w88//6zvWoiIiIj0rkCHsWbMmIE333wTO3fuRM2aNWFpaakzf86cOXopjoiIiOhFFSjsBAcHY9euXahatSoA5BqgTERERGQsChR25syZg++//x59+vTRczlERERE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/v37K/Nv3LhhqNIkKytLRES++OILpcYc+/fvl4CAAPH29paIiAhDlGc02Lb1g2276JhS22bYMSGP7wwPHDggP//8s5w4cUL5Zb906ZKUKFFC3njjDTlz5oxotVrp2LGjfPXVV4YqOZe8duirV6+Wdu3aya+//ir29vayaNEiZd727dtl+PDhcuvWLb3WkfMH47fffpOFCxfK7du3pUaNGlKvXj2pU6eO2NnZSZMmTcTLy0t8fHykYcOG0rRpU3n48KFe69CXn376SSpXrizR0dFSoUIF+fDDD5XP+vfff5e+ffsWyQ49Z5uP/0FOTU0VEZGFCxdK+fLl5c6dOzrrhISEiEajETc3N9m5c2eh12iM2Lb1h227cJh622bYMUHjxo0TT09P8fDwkAoVKoifn5/s379fRB7tFN3c3KR27dpSo0YN8fHxkYyMDANX/MjjO8P169fL6dOnRUQkLi5OSpQoIRqNRr799ltlmdTUVGnXrp289957hfJt9tixY1KyZElZuXKliDz6Bt28eXPRaDQyc+ZM2bJli6xatUrWrFkjGzdulIsXL+q9hueVlZWV52eRkJAgTZo0EQsLC+ndu7eI/LtT+vjjj+X111+Xe/fuFUmNV65ckdDQUBF59P/82muvSXp6uvz+++9SuXJlWb58uSQlJSnLHz58WPz9/WXkyJFy9erVIqnRWLFt6wfbduEw5bbNsGNivv32W3FxcZG9e/fKP//8I9u2bZNu3bpJpUqV5PDhwyIicvPmTQkODpYvv/xS6SLWd1fx83q8EX/yySfi5eUl06dPl/v374uIyLZt26R48eLSo0cP2bJli/z6668SEBAgNWvWVGrX507x0qVLMmvWLBk/fryI/NsdGxsbK/Xr15dGjRrl+pZiSPHx8TrPDx8+LN98842sX79e/vnnHxER+frrr8XHx0d69Ogh8fHxcuzYMfn444/FyclJTp06VWS19ujRQywsLOTTTz8Vc3NzWbFihTJvyJAh4ubmJkuWLJFr165JZmamTJgwQXr06CEJCQlFVqMxYtvWD7btwmPKbZthx4RotVoZPHiw9O3bV2d6VFSUvPHGG9KrV688u2INvTN83P/+9z9xcXGRo0ePKl2gOcLDw8XX11e8vLykUaNG0qVLF+Wba84O60VptVr5+++/xdPTU6ytraVPnz7KvJxvp3FxcVK/fn0p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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import matplotlib.pyplot as plt\n", "\n", - "report[\"MB/s (compressed)\"] = report.compressed_bytes/report.run_processor/(1024*1024)\n", + "report[\"MB/s (compressed)\"] = report.compressed_bytes/report['time:run_processor']/(1024*1024)\n", + "report[\"column_setup\"] = report[\"column_setup\"].apply(lambda x: x.replace('pct', '% of the file'))\n", + "\n", + "measurements = [\"time:run_processor\", \"time:decompress\", \"time:wait\", \"MB/s (compressed)\"]\n", + "other_cols = [c for c in report.columns if c not in measurements]\n", + "\n", + "agg = {}\n", + "for c in report.columns:\n", + " if c in measurements:\n", + " agg[c] = ['mean', 'std']\n", + "\n", + "aggregated = report.groupby(other_cols).agg(agg)\n", + "\n", + "\n", + "# Reset the index to make it easier to plot\n", + "aggregated_reset = aggregated.reset_index()\n", + " \n", + "\n", + "# Plotting\n", + "fig, ax = plt.subplots()\n", + "\n", + "# Heights of the bars\n", + "decompress = aggregated_reset[('time:decompress', 'mean')]\n", + "wait = aggregated_reset[('time:wait', 'mean')]\n", + "run_processor = aggregated_reset[('time:run_processor', 'mean')]\n", + "\n", + "# Error bars\n", + "run_processor_err = aggregated_reset[('time:run_processor', 'std')]\n", + "\n", + "# Positions for bars\n", + "x = aggregated_reset[['file_location', 'column_setup']].reset_index(drop=True)\n", + "\n", + "bar_width = 1\n", "\n", - "report_by_column_setup = report.groupby('column_setup')\n", + "group_pos = 0\n", + "step = 1.25\n", + "group_gap = 1\n", + "mult = group_mult = 0\n", + "\n", + "for col in x.column_setup.unique():\n", + " for fl in x.file_location.unique():\n", + " loc = (x.column_setup==col) & (x.file_location==fl)\n", + " x.loc[loc, \"position\"] = group_pos + step * mult\n", + " mult += 1\n", + " group_pos += group_gap\n", + " \n", + "\n", + "# Plot the stacked bars\n", + "p1 = ax.bar(x.position, decompress, bar_width,label='time:decompress', color='tab:red', )\n", + "p2 = ax.bar(x.position, wait, bar_width, bottom=decompress, label='time:wait', color='tab:orange', )\n", + "p3 = ax.bar(x.position, run_processor, bar_width, yerr=run_processor_err, label='time:run_processor', \n", + " facecolor='none', linewidth=2, edgecolor='tab:blue', ecolor='tab:blue', capsize=4)\n", + "\n", + "# Adding labels and title\n", + "# ax.set_xlabel('File location and fraction of the size')\n", + "ax.set_xticks(x.position, x.file_location)\n", + "ax.set_ylabel('Time (s)')\n", + "ax.set_ylim(0,110)\n", + "ax.set_title('')\n", + "ax.legend()\n", + "plt.xticks(rotation=45)\n", + "\n", + "ax2 = ax.secondary_xaxis('bottom')\n", + "ax2_labels = x.groupby(\"column_setup\").mean(numeric_only=True).reset_index()\n", + "ax2.set_xticks(ax2_labels.position, ax2_labels.column_setup)\n", + "ax2.spines['bottom'].set_position(('outward', 50))\n", + "ax2.spines['bottom'].set_visible(False)\n", + "ax2.tick_params(which='both', length=0)\n", "\n", - "plt.figure(figsize=(8, 6))\n", - "for col_setup, group in report_by_column_setup:\n", - " plt.plot(group.n_workers, group[\"MB/s (compressed)\"], label=col_setup)\n", "\n", - "plt.xlabel('# workers')\n", - "plt.ylabel('MB/s')\n", - "plt.legend()\n", - "plt.xlim(0, report.n_workers.max()+5)\n", - "plt.ylim(0, report['MB/s (compressed)'].max() + 5)\n", "plt.show()" ] }, @@ -190,10 +951,10 @@ "metadata": {}, "outputs": [], "source": [ - "report[\"event_rate\"] = report.n_events / report.run_processor / report.n_columns_read\n", - "report[\"data_rate_comp\"] = report.compressed_bytes / report.run_processor\n", - "report[\"data_rate_uncomp\"] = report.uncompressed_bytes / report.run_processor\n", - "report[[\"column_setup\", \"n_workers\", \"event_rate\", \"data_rate_comp\", \"data_rate_uncomp\"]]" + "# report[\"event_rate\"] = report.n_events / report.run_processor / report.n_columns_read\n", + "# report[\"data_rate_comp\"] = report.compressed_bytes / report.run_processor\n", + "# report[\"data_rate_uncomp\"] = report.uncompressed_bytes / report.run_processor\n", + "# report[[\"column_setup\", \"n_workers\", \"event_rate\", \"data_rate_comp\", \"data_rate_uncomp\"]]" ] }, { @@ -203,18 +964,7 @@ "metadata": {}, "outputs": [], "source": [ - "report.compressed_bytes / report.n_events * report.n_columns_read" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19cd6bd7-6180-4aac-9ab7-6799cf1450dc", - "metadata": {}, - "outputs": [], - "source": [ - "import uproot\n", - "uproot.__version__" + "# report.compressed_bytes / report.n_events * report.n_columns_read" ] }, { diff --git a/src/time_profiler.py b/src/time_profiler.py index 6d85c71..d84769f 100644 --- a/src/time_profiler.py +++ b/src/time_profiler.py @@ -58,7 +58,8 @@ def wrapper(*args, **kwargs): for k,v in stats.stats.items(): # Actual function name is long => will use alias for nicer looking output extra_funcs = { - "decompress": "" + "decompress": "", + "wait": "" } for alias, extra_func in extra_funcs.items(): if k[2] == extra_func: