From 9cfdbbb8feba37bdfeca89e7058cde31edce00f0 Mon Sep 17 00:00:00 2001 From: Mikhail Goncharov Date: Thu, 30 Jul 2020 09:20:19 +0200 Subject: [PATCH 1/3] fix git clenup --- scripts/phabtalk/apply_patch2.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/phabtalk/apply_patch2.py b/scripts/phabtalk/apply_patch2.py index 9565c42..6b5c284 100755 --- a/scripts/phabtalk/apply_patch2.py +++ b/scripts/phabtalk/apply_patch2.py @@ -74,6 +74,7 @@ class ApplyPatch: else: logging.info('repository exist, will reuse') self.repo = Repo(path) # type: Repo + # TODO: set origin url to fork os.chdir(path) logging.info(f'working dir {os.getcwd()}') @@ -109,7 +110,7 @@ class ApplyPatch: self._create_branch(base_revision) logging.info('git reset, git cleanup...') self.repo.git.reset('--hard') - self.repo.git.clean('-fdx') + self.repo.git.clean('-ffxdq') logging.info('Analyzing {}'.format(diff_to_str(revision_id))) if len(dependencies) > 0: logging.info('This diff depends on: {}'.format(diff_list_to_str(dependencies))) @@ -147,7 +148,7 @@ class ApplyPatch: self.repo.git.fetch('--all') self.repo.git.checkout('master') self.repo.git.reset('--hard') - self.repo.git.clean('-fdx') + self.repo.git.clean('-ffxdq') if 'upstream' not in self.repo.remotes: self.repo.create_remote('upstream', url=LLVM_GITHUB_URL) self.repo.remotes.upstream.fetch() From d75dcdd2fbba0549fc379ba77fa1f0c094edd368 Mon Sep 17 00:00:00 2001 From: Mikhail Goncharov Date: Thu, 30 Jul 2020 09:27:05 +0200 Subject: [PATCH 2/3] cleanup before checking out master --- scripts/phabtalk/apply_patch2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/phabtalk/apply_patch2.py b/scripts/phabtalk/apply_patch2.py index 6b5c284..042a029 100755 --- a/scripts/phabtalk/apply_patch2.py +++ b/scripts/phabtalk/apply_patch2.py @@ -145,10 +145,10 @@ class ApplyPatch: return logging.info('Syncing local, origin and upstream...') + self.repo.git.clean('-ffxdq') self.repo.git.fetch('--all') self.repo.git.checkout('master') self.repo.git.reset('--hard') - self.repo.git.clean('-ffxdq') if 'upstream' not in self.repo.remotes: self.repo.create_remote('upstream', url=LLVM_GITHUB_URL) self.repo.remotes.upstream.fetch() From cb41bb38ddcce8846397533b270454546ed65d8b Mon Sep 17 00:00:00 2001 From: Mikhail Goncharov Date: Thu, 30 Jul 2020 09:32:50 +0200 Subject: [PATCH 3/3] reset before checking out master --- README.md | 4 +- docs/playbooks.md | 26 +- kubernetes/windows_agent_create.sh | 5 +- scripts/buildkite/analyze_jobs.ipynb | 667 +++++++++++++++++++-- scripts/buildkite/build_master_pipeline.py | 2 +- scripts/phabtalk/apply_patch2.py | 2 +- 6 files changed, 642 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index ecae6fc..fc97aa9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This repository contains the configuration files for the pre-merge checks for the LLVM project. This github project contains the documentation and the server configuration cluster of build machines that are used to check all incoming commits to the LLVM project. # User documentation -See [docs/user_doc.md](docs/user_doc.md) +If you are interested in a high-level overview and how to best use the tool see [docs/user_doc.md](docs/user_doc.md) # Cluster overview @@ -31,7 +31,7 @@ On the Jenkins side: There is no backup of the credentials. If you need to change it, generate a new one and update it in Jenkins and Phabricator. # Additional Information -* [Playbooks](docs/playbooks.md) for installing/upgrading +* [Playbooks](docs/playbooks.md) for installing/upgrading agents and testing changes. * [User documentation](docs/user_doc.md) * [Log of the service operations](https://github.com/google/llvm-premerge-checks/wiki/LLVM-pre-merge-tests-operations-blog) diff --git a/docs/playbooks.md b/docs/playbooks.md index d955ba7..1b2165d 100644 --- a/docs/playbooks.md +++ b/docs/playbooks.md @@ -139,7 +139,7 @@ To spawn a new windows agent: 1. Add a task to start agent when machine restarts (make sure to pass correct parameters). ``` git clone https://github.com/google/llvm-premerge-checks.git C:\llvm-premerge-checks -schtasks.exe /create /tn "Start Buildkite agent" /ru SYSTEM /SC ONSTART /DELAY 0005:00 /tr "powershell -command 'C:\llvm-premerge-checks\scripts\windows_agent_start_buildkite.ps1'" +schtasks.exe /create /tn "Start Buildkite agent" /ru SYSTEM /SC ONSTART /DELAY 0005:00 /tr "powershell -command 'C:\llvm-premerge-checks\scripts\windows_agent_start_buildkite.ps1 -workdir c:\ws'" ``` ### Jenkins @@ -174,6 +174,18 @@ Within a container set environment variables similar to [pipeline](https://githu Additionally set `WORKSPACE`, `PHID` and `DIFF_ID` parameters. Set `CONDUIT_TOKEN` with your personal one from `https://reviews.llvm.org/settings/user//page/apitokens/`. +## Custom environment variables for debugging + +Buildkite pipelines have a number of custom environment variables one can set to change their behavior to debug issues +or test changes. The best way is to look on pipeline generators (e.g. build_master_pipeline) + +## Testing changes before merging + +It's recommended to test even small changes before committing them to the `master` branch. + +1. create a branch with your changes, e.g. "my-feature" and push it to origin. +1. manually create a buildkite build in the pipeline you are updating and specify environment variable + `scripts_branch="my-feature"` (see other ) # Phabricator integration @@ -203,14 +215,4 @@ We have these build plans in Harbormaster: * [Plan 4](https://reviews.llvm.org/harbormaster/plan/4/) Builds for everyone * [Plan 3](https://reviews.llvm.org/harbormaster/plan/3/) Builds for beta testers -You can *disable* a build plan to stop it from building. - -## Per user Opt in/out - -You can also on a per-user bases opt in/out to premerge testing. -* To opt-in to pre-merge beta testing, add yourself to this project: -https://reviews.llvm.org/project/view/78/ -* To opt-out of pre-merge testing entirely, add yourself to this project: -https://reviews.llvm.org/project/view/83/ - -These projects are checked in the Herald rules above. +You can *disable* a build plan to stop it from building. \ No newline at end of file diff --git a/kubernetes/windows_agent_create.sh b/kubernetes/windows_agent_create.sh index d34e425..eca813e 100755 --- a/kubernetes/windows_agent_create.sh +++ b/kubernetes/windows_agent_create.sh @@ -28,8 +28,7 @@ NAME=$1 gcloud beta compute instances create "${NAME}" \ --project="${GCP_PROJECT}" \ --zone="${GCP_ZONE}" \ - --machine-type=n1-standard-32 \ - --local-ssd=device-name=local-ssd-0 \ + --machine-type=n2d-standard-16 \ --image=windows-server-2019-dc-for-containers-v20200714 \ --image-project=windows-cloud \ - --boot-disk-size=100GB + --boot-disk-size=200GB --boot-disk-type=pd-ssd diff --git a/scripts/buildkite/analyze_jobs.ipynb b/scripts/buildkite/analyze_jobs.ipynb index e37a76c..b277dd5 100644 --- a/scripts/buildkite/analyze_jobs.ipynb +++ b/scripts/buildkite/analyze_jobs.ipynb @@ -23,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 724, "metadata": {}, "outputs": [], "source": [ @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 725, "metadata": {}, "outputs": [], "source": [ @@ -51,11 +51,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 726, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "loaded 13566 entries\n" + ] + } + ], "source": [ "if os.path.exists(cache_file):\n", " with open(cache_file) as f:\n", @@ -65,11 +73,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 727, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "loading page 1\n", + "loading page 2\n", + "loading page 3\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/723 is running , skipping\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/721 is running , skipping\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/719 is running , skipping\n", + "loading page 4\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/717 is running , skipping\n", + "https://buildkite.com/llvm-project/llvm-master-build/builds/715 is running , skipping\n", + "loading page 5\n", + "loading page 6\n", + "loading page 7\n", + "loading page 8\n", + "loading page 9\n", + "loading page 10\n", + "13706 jobs in total\n", + "saved 13706 entries\n" + ] + } + ], "source": [ "# load new jobs from Buildkite API\n", + "max_pages = 2000\n", "if True:\n", " existing = set()\n", " for j in builds:\n", @@ -80,7 +113,7 @@ "# existing = set()\n", " page = 1\n", " stop = False\n", - " while not stop:\n", + " while page <= max_pages:\n", " print('loading page', page)\n", " re = requests.get('https://api.buildkite.com/v2/organizations/llvm-project/builds',\n", " params={'page': page},\n", @@ -94,14 +127,15 @@ " break\n", " for j in x:\n", " if j['id'] in existing:\n", - " print('found existing job', j['id'])\n", - " stop = True\n", - " break\n", - " # TODO: skip running jobs \n", - " if (j['state'] == 'running') or (j['state'] == 'scheduled'):\n", - " print(j['web_url'], 'is', j['state'], ', skipping')\n", - " continue\n", - " builds.append(j)\n", + "# print('found existing job', j['id'])\n", + " # load some more pages as some of them might be running before and wasn't added. \n", + " max_pages = min(page + 5, max_pages)\n", + " else:\n", + " # skip running jobs \n", + " if (j['state'] == 'running') or (j['state'] == 'scheduled'):\n", + " print(j['web_url'], 'is', j['state'], ', skipping')\n", + " continue\n", + " builds.append(j)\n", " page += 1\n", " print(len(builds), 'jobs in total') \n", " with open(cache_file, 'w') as f:\n", @@ -111,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 728, "metadata": {}, "outputs": [], "source": [ @@ -138,7 +172,13 @@ "}\n", "\n", "sec = np.timedelta64(1, 's')\n", + "\n", "for b in builds:\n", + " env = b['env']\n", + " if 'ph_windows_agents' not in env:\n", + " continue\n", + " if 'scripts_branch' not in env:\n", + " continue\n", " d['id'].append(b['id'])\n", " d['number'].append(b['number'])\n", " d['pipeline'].append(b['pipeline']['slug'])\n", @@ -169,73 +209,610 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 729, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array(['llvm-master-build'], dtype=object)" + ] + }, + "execution_count": 729, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "jobs.pipeline.unique()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 730, "metadata": {}, - "outputs": [], + "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", + "
pipelinenamestep_keystateexit_statusagent_idagent_namerunnable_atstarted_atwait_durationfinished_atrun_duration
0llvm-master-build:seedling: setupNonepassed0f20d42d3-31cb-4e46-a3d6-699877e7b283premerge-debian-77f64f444-fm624-12020-07-27 18:10:162020-07-27 18:15:44.928328.9282020-07-27 18:15:47.7972.869
1llvm-master-build:windows: build and test windowswindowspassed0c9e48cee-e909-45b2-aa23-0d7335786499we32n1b2020-07-27 18:15:472020-07-28 01:36:57.68726470.6872020-07-28 02:26:08.7502951.063
2llvm-master-build:seedling: setupNonepassed0f20d42d3-31cb-4e46-a3d6-699877e7b283premerge-debian-77f64f444-fm624-12020-07-27 18:10:152020-07-27 18:15:34.989319.9892020-07-27 18:15:37.7212.732
3llvm-master-build:windows: build and test windowswindowspassed0d4d0a0a4-255b-4fdd-8aba-abb00ba0bf34we16c2b2020-07-27 18:15:372020-07-28 03:13:59.99632302.9962020-07-28 04:14:12.5213612.525
4llvm-master-build:seedling: setupNonepassed0f20d42d3-31cb-4e46-a3d6-699877e7b283premerge-debian-77f64f444-fm624-12020-07-27 18:10:142020-07-27 18:15:25.094311.0942020-07-27 18:15:27.9182.824
.......................................
189llvm-master-build:windows: build and test windowswindowspassed042f6f98d-15bd-4ad4-ac48-8626a752a154w16c2-12020-07-29 18:22:312020-07-29 20:23:50.6867279.6862020-07-29 21:23:50.2713599.585
190llvm-master-build:seedling: setupNonepassed0db5829eb-04bf-4700-9bec-423258de4a7dpremerge-debian-77f64f444-vxgx4-12020-07-29 18:21:472020-07-29 18:22:09.24322.2432020-07-29 18:22:12.3213.078
191llvm-master-build:windows: build and test windowswindowspassed042f6f98d-15bd-4ad4-ac48-8626a752a154w16c2-12020-07-29 18:22:122020-07-29 19:24:00.3453708.3452020-07-29 20:23:45.9673585.622
192llvm-master-build:seedling: setupNonepassed0db5829eb-04bf-4700-9bec-423258de4a7dpremerge-debian-77f64f444-vxgx4-12020-07-29 18:21:452020-07-29 18:21:49.1904.1902020-07-29 18:21:52.8623.672
193llvm-master-build:windows: build and test windowswindowspassed042f6f98d-15bd-4ad4-ac48-8626a752a154w16c2-12020-07-29 18:21:522020-07-29 18:21:54.8572.8572020-07-29 19:23:58.4713723.614
\n", + "

194 rows × 12 columns

\n", + "
" + ], + "text/plain": [ + " pipeline name step_key state \\\n", + "0 llvm-master-build :seedling: setup None passed \n", + "1 llvm-master-build :windows: build and test windows windows passed \n", + "2 llvm-master-build :seedling: setup None passed \n", + "3 llvm-master-build :windows: build and test windows windows passed \n", + "4 llvm-master-build :seedling: setup None passed \n", + ".. ... ... ... ... \n", + "189 llvm-master-build :windows: build and test windows windows passed \n", + "190 llvm-master-build :seedling: setup None passed \n", + "191 llvm-master-build :windows: build and test windows windows passed \n", + "192 llvm-master-build :seedling: setup None passed \n", + "193 llvm-master-build :windows: build and test windows windows passed \n", + "\n", + " exit_status agent_id \\\n", + "0 0 f20d42d3-31cb-4e46-a3d6-699877e7b283 \n", + "1 0 c9e48cee-e909-45b2-aa23-0d7335786499 \n", + "2 0 f20d42d3-31cb-4e46-a3d6-699877e7b283 \n", + "3 0 d4d0a0a4-255b-4fdd-8aba-abb00ba0bf34 \n", + "4 0 f20d42d3-31cb-4e46-a3d6-699877e7b283 \n", + ".. ... ... \n", + "189 0 42f6f98d-15bd-4ad4-ac48-8626a752a154 \n", + "190 0 db5829eb-04bf-4700-9bec-423258de4a7d \n", + "191 0 42f6f98d-15bd-4ad4-ac48-8626a752a154 \n", + "192 0 db5829eb-04bf-4700-9bec-423258de4a7d \n", + "193 0 42f6f98d-15bd-4ad4-ac48-8626a752a154 \n", + "\n", + " agent_name runnable_at \\\n", + "0 premerge-debian-77f64f444-fm624-1 2020-07-27 18:10:16 \n", + "1 we32n1b 2020-07-27 18:15:47 \n", + "2 premerge-debian-77f64f444-fm624-1 2020-07-27 18:10:15 \n", + "3 we16c2b 2020-07-27 18:15:37 \n", + "4 premerge-debian-77f64f444-fm624-1 2020-07-27 18:10:14 \n", + ".. ... ... \n", + "189 w16c2-1 2020-07-29 18:22:31 \n", + "190 premerge-debian-77f64f444-vxgx4-1 2020-07-29 18:21:47 \n", + "191 w16c2-1 2020-07-29 18:22:12 \n", + "192 premerge-debian-77f64f444-vxgx4-1 2020-07-29 18:21:45 \n", + "193 w16c2-1 2020-07-29 18:21:52 \n", + "\n", + " started_at wait_duration finished_at \\\n", + "0 2020-07-27 18:15:44.928 328.928 2020-07-27 18:15:47.797 \n", + "1 2020-07-28 01:36:57.687 26470.687 2020-07-28 02:26:08.750 \n", + "2 2020-07-27 18:15:34.989 319.989 2020-07-27 18:15:37.721 \n", + "3 2020-07-28 03:13:59.996 32302.996 2020-07-28 04:14:12.521 \n", + "4 2020-07-27 18:15:25.094 311.094 2020-07-27 18:15:27.918 \n", + ".. ... ... ... \n", + "189 2020-07-29 20:23:50.686 7279.686 2020-07-29 21:23:50.271 \n", + "190 2020-07-29 18:22:09.243 22.243 2020-07-29 18:22:12.321 \n", + "191 2020-07-29 19:24:00.345 3708.345 2020-07-29 20:23:45.967 \n", + "192 2020-07-29 18:21:49.190 4.190 2020-07-29 18:21:52.862 \n", + "193 2020-07-29 18:21:54.857 2.857 2020-07-29 19:23:58.471 \n", + "\n", + " run_duration \n", + "0 2.869 \n", + "1 2951.063 \n", + "2 2.732 \n", + "3 3612.525 \n", + "4 2.824 \n", + ".. ... \n", + "189 3599.585 \n", + "190 3.078 \n", + "191 3585.622 \n", + "192 3.672 \n", + "193 3723.614 \n", + "\n", + "[194 rows x 12 columns]" + ] + }, + "execution_count": 730, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "jobs" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 731, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/google/home/goncharov/etc/merge-checks/venv/lib/python3.7/site-packages/ipykernel_launcher.py:1: UserWarning: Boolean Series key will be reindexed to match DataFrame index.\n", + " \"\"\"Entry point for launching an IPython kernel.\n" + ] + } + ], "source": [ - "ds = jobs[jobs['pipeline'] == 'premerge-checks'][jobs['step_key'] == 'windows'][jobs['state']=='passed'][~jobs['agent_name'].str.startswith('buildkite-')][jobs['started_at'] > np.datetime64('2020-01-22')]" + "ds = jobs[jobs['pipeline'] == 'llvm-master-build'][jobs['step_key'] == 'windows'][jobs['state']=='passed'][~jobs['agent_name'].str.startswith('buildkite-')][jobs['started_at'] > np.datetime64('2020-01-22')]\n", + "ds = ds.drop_duplicates()\n", + "# remove one slowest run (repo checkout)\n", + "# t = ds.loc[ds.groupby([\"agent_name\"])[\"run_duration\"].idxmax()]\n", + "# ds = pd.concat([ds, t]).drop_duplicates(keep=False)" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 732, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/google/home/goncharov/etc/merge-checks/venv/lib/python3.7/site-packages/seaborn/categorical.py:2971: UserWarning: The `split` parameter has been renamed to `dodge`.\n", + " warnings.warn(msg, UserWarning)\n" + ] + }, + { + "data": { + "text/plain": [ + "(0.0, 5877.15505)" + ] + }, + "execution_count": 732, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ - " fig, ax = plt.subplots(figsize=(10,10)) # size of the plot (width, height)\n", + "fig, ax = plt.subplots(figsize=(10,10)) # size of the plot (width, height)\n", "\n", - " sns.swarmplot(\n", - " ax=ax,\n", - " x='run_duration',\n", - " y='agent_name',\n", - " split=True,\n", - " data=ds)" + "sns.swarmplot(\n", + " ax=ax,\n", + " x='run_duration',\n", + " y='agent_name',\n", + " split=True,\n", + " data=ds)\n", + "\n", + "plt.xlim(0, None)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 733, "metadata": { "scrolled": false }, - "outputs": [], + "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", + "
medianmeanstdcount_nonzero
run_durationrun_durationrun_durationrun_duration
agent_name
we16n1a4982.73805013.848800396.9260505.0
we16n1b4692.79304707.102222121.6241499.0
w16n2-13846.20903881.80960081.6577425.0
we16c2a3779.31103858.373400183.8226025.0
we16c2b3593.52003615.01620066.46000510.0
w16c2-13585.62203612.09280063.1206885.0
we16n1c3068.64403085.9271001412.88808610.0
we32n1b2964.45202964.17830059.21571210.0
we32n1a2880.91803031.068800428.1105685.0
we16c2c2366.51552377.4419001005.84782610.0
we32n1c2289.96052275.634700629.38680410.0
w642282.68602282.76980033.4819775.0
\n", + "
" + ], + "text/plain": [ + " median mean std count_nonzero\n", + " run_duration run_duration run_duration run_duration\n", + "agent_name \n", + "we16n1a 4982.7380 5013.848800 396.926050 5.0\n", + "we16n1b 4692.7930 4707.102222 121.624149 9.0\n", + "w16n2-1 3846.2090 3881.809600 81.657742 5.0\n", + "we16c2a 3779.3110 3858.373400 183.822602 5.0\n", + "we16c2b 3593.5200 3615.016200 66.460005 10.0\n", + "w16c2-1 3585.6220 3612.092800 63.120688 5.0\n", + "we16n1c 3068.6440 3085.927100 1412.888086 10.0\n", + "we32n1b 2964.4520 2964.178300 59.215712 10.0\n", + "we32n1a 2880.9180 3031.068800 428.110568 5.0\n", + "we16c2c 2366.5155 2377.441900 1005.847826 10.0\n", + "we32n1c 2289.9605 2275.634700 629.386804 10.0\n", + "w64 2282.6860 2282.769800 33.481977 5.0" + ] + }, + "execution_count": 733, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "t = pd.pivot_table(ds, values=['run_duration'], index=['agent_name'],\n", " aggfunc=[np.median, np.mean, np.std, np.count_nonzero])\n", "t = t.reindex(t.sort_values(by=('median', 'run_duration'), ascending=False).index)\n", "t" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```\n", + "// TODO: try with w64 w/o AV (temporary disabled)\n", + "w1 - 16 - non ssd 100 + ssd\n", + "w1a - 16 - non ssd 100 + ssd - AV (temp)\n", + "w4a - 16 - non ssd 100 + ssd - AV\n", + "w16-1 - 16 - non sdd 200 + ssd\n", + "w32-1 - 32 - non ssd 100 + ssd\n", + "w32-2 - 32 - non ssd 100 + ssd - AV\n", + "w32-2d - 32 - non ssd 200 + ssd\n", + "w64 - 64 - ssd 200 + ssd \n", + "w64a - 64 - ssd 200 + ssd - AV (temp)\n", + "wh63-3 - 64 low ram - non ssd 100 + ssd - AV\n", + "\n", + "buildkite-windows-16n1-exp\n", + "gcloud beta compute instances create \"${NAME}\" \\\n", + " --project=\"${GCP_PROJECT}\" \\\n", + " --zone=\"${GCP_ZONE}\" \\\n", + " --machine-type=n1-standard-16 \\\n", + " --local-ssd=device-name=local-ssd-0 \\\n", + " --image=windows-server-2019-dc-for-containers-v20200714 \\\n", + " --image-project=windows-cloud \\\n", + " --boot-disk-size=200GB --boot-disk-type=pd-ssd\n", + "\n", + "buildkite-32-experimental-1\n", + "gcloud beta compute instances create \"${NAME}\" \\\n", + " --project=\"${GCP_PROJECT}\" \\\n", + " --zone=\"${GCP_ZONE}\" \\\n", + " --machine-type=n1-standard-32 \\\n", + " --local-ssd=device-name=local-ssd-0 \\\n", + " --image=windows-server-2019-dc-for-containers-v20200714 \\\n", + " --image-project=windows-cloud \\\n", + " --boot-disk-size=200GB --boot-disk-type=pd-ssd\n", + "\n", + " \n", + "buildkite-16c2-exp\n", + "gcloud beta compute instances create \"${NAME}\" \\\n", + " --project=\"${GCP_PROJECT}\" \\\n", + " --zone=\"${GCP_ZONE}\" \\\n", + " --machine-type=c2-standard-16 \\\n", + " --local-ssd=device-name=local-ssd-0 \\\n", + " --local-ssd=interface=SCSI \\\n", + " --image=windows-server-2019-dc-for-containers-v20200714 \\\n", + " --image-project=windows-cloud \\\n", + " --boot-disk-size=200GB --boot-disk-type=pd-ssd\n", + " \n", + "...a: as is D:/ is a workdir (ealy run with full cache build)\n", + "...b: C:/ws as a workdir, no cache\n", + "```\n" + ] } ], "metadata": { diff --git a/scripts/buildkite/build_master_pipeline.py b/scripts/buildkite/build_master_pipeline.py index cdc1ce6..f46c82e 100755 --- a/scripts/buildkite/build_master_pipeline.py +++ b/scripts/buildkite/build_master_pipeline.py @@ -23,7 +23,7 @@ if __name__ == '__main__': no_cache = os.getenv('ph_no_cache') is not None filter_output = '--filter-output' if os.getenv('ph_no_filter_output') is None else '' projects = os.getenv('ph_projects', 'clang;clang-tools-extra;libc;libcxx;libcxxabi;lld;libunwind;mlir;openmp;polly') - log_level = os.getenv('ph_log_level', 'WARNING') + log_level = os.getenv('C', 'WARNING') notify_emails = list(filter(None, os.getenv('ph_notify_emails', '').split(','))) steps = [] linux_agents = {'queue': f'{queue_prefix}linux'} diff --git a/scripts/phabtalk/apply_patch2.py b/scripts/phabtalk/apply_patch2.py index 042a029..73d4ddd 100755 --- a/scripts/phabtalk/apply_patch2.py +++ b/scripts/phabtalk/apply_patch2.py @@ -146,9 +146,9 @@ class ApplyPatch: logging.info('Syncing local, origin and upstream...') self.repo.git.clean('-ffxdq') + self.repo.git.reset('--hard') self.repo.git.fetch('--all') self.repo.git.checkout('master') - self.repo.git.reset('--hard') if 'upstream' not in self.repo.remotes: self.repo.create_remote('upstream', url=LLVM_GITHUB_URL) self.repo.remotes.upstream.fetch()