-
Notifications
You must be signed in to change notification settings - Fork 645
Pnm mesh datapipes #1512
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
Open
coreyjadams
wants to merge
36
commits into
NVIDIA:main
Choose a base branch
from
coreyjadams:pnm_mesh_datapipes
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Pnm mesh datapipes #1512
Changes from 15 commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
2b1f535
Adding mesh datapipe temporarily
coreyjadams 132d72a
first, very early, draft of mesh-based datapipe
coreyjadams 8987172
Update datapipes for physicsnemo mesh: now can read and transform sur…
coreyjadams aeb8c06
Add a functionally working - but not yet cxonverging - xaero recipe
coreyjadams 6459144
Add functional physicsnemo mesh pipeline
coreyjadams 5821b15
Update README
coreyjadams 0da2cd1
Snapshotting training recipe
coreyjadams f5cb9bc
Merge branch 'NVIDIA:main' into pnm_mesh_datapipes
coreyjadams 42740e8
Remove Ahmed dataset with physicsnemo mesh, it's not needed.
coreyjadams beb2da0
Simplify and consolidate, or remove statistics work for this example.
coreyjadams 36d3365
Remove inspect_data, and ensure readme is updated
coreyjadams f7e77be
Remove AGENT.md
coreyjadams 6977270
Training recipe is basically complete
coreyjadams 5db9027
Merge branch 'main' into pnm_mesh_datapipes
coreyjadams bb9e995
Merge branch 'main' into pnm_mesh_datapipes
coreyjadams 0c5d58e
Merge branch 'main' into pnm_mesh_datapipes
coreyjadams b669aa7
Update physicsnemo/datapipes/readers/mesh.py
coreyjadams e8ef574
Update physicsnemo/datapipes/transforms/mesh/transforms.py
coreyjadams 5493428
Update physicsnemo/datapipes/readers/mesh.py
coreyjadams 70e806b
Addressing some PR comments.
coreyjadams 0c21bb1
make sure rotations are flexible, add docstrings
coreyjadams 1277d3d
Update distribution handling per PR review.
coreyjadams c8370d2
Merge branch 'NVIDIA:main' into pnm_mesh_datapipes
coreyjadams 492892a
Merge branch 'NVIDIA:main' into pnm_mesh_datapipes
coreyjadams 93b10d1
This commit enablers the datapipes to be reproducible
coreyjadams 4a13b3e
Add testing for the datapipes
coreyjadams d7d2e01
Add missing rng updates
coreyjadams 1fea170
Update training python codes
coreyjadams 53069e2
Add geotransolver configs with obscured paths
coreyjadams aa8cced
Remove shift suv configs for now
coreyjadams c5b8e6d
Merge branch 'main' into pnm_mesh_datapipes
coreyjadams 7b79c58
Adding configs for flare and geotransolver with a flare backend.
coreyjadams d77b582
Update README.md
coreyjadams 6189fe5
Add datapipes.md. Describes some of the computational design of the d…
coreyjadams 957d6c3
Update datapipes to use non-blocking stream syncs when streams are ac…
coreyjadams 019e46b
Fix cuda memory access errors arising from incorrect fake tensor ops.…
coreyjadams File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
examples/cfd/external_aerodynamics/unified_external_aero_recipe/.gitignore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| *.err | ||
| *.out | ||
| outputs/ | ||
| stats/ | ||
| checkpoints/ | ||
| *.mdlus | ||
| *.tfevents* | ||
| *.parquet |
433 changes: 433 additions & 0 deletions
433
examples/cfd/external_aerodynamics/unified_external_aero_recipe/README.md
Large diffs are not rendered by default.
Oops, something went wrong.
82 changes: 82 additions & 0 deletions
82
...d/external_aerodynamics/unified_external_aero_recipe/conf/dataset/drivaer_ml_surface.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES. | ||
| # SPDX-FileCopyrightText: All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # DrivaerML surface dataset | ||
| # Point cloud mesh (no cells). Fields live in point_data. | ||
|
|
||
| name: drivaer_ml_surface | ||
|
|
||
| train_datadir: /lustre/fsw/portfolios/coreai/projects/coreai_modulus_cae//datasets/drivaer_aws/drivaer_data_pnm_mesh/train/ | ||
| val_datadir: /lustre/fsw/portfolios/coreai/projects/coreai_modulus_cae//datasets/drivaer_aws/drivaer_data_pnm_mesh/val/ | ||
|
|
||
| metadata: | ||
| U_inf: [30.0, 0.0, 0.0] # freestream velocity | ||
| p_inf: 0.0 # reference pressure, drivaerml is gauge pressure | ||
| rho_inf: 1.225 # freestream density | ||
| nu: 1 | ||
| L_ref: 5.0 # reference length [m] | ||
|
|
||
| pipeline: | ||
| reader: | ||
| _target_: ${dp:MeshReader} | ||
| path: ${train_datadir} | ||
| pattern: "**/boundary*.vtp.pmsh" | ||
| augmentations: | ||
| - _target_: ${dp:RandomRotateMesh} | ||
| axes: ["z"] | ||
| transform_point_data: true | ||
| transform_global_data: true | ||
| - _target_: ${dp:RandomTranslateMesh} | ||
| max_offset: [1.0, 1.0, 0.0] | ||
| transforms: | ||
| - _target_: ${dp:DropMeshFields} | ||
| global_data: [TimeValue] | ||
| - _target_: ${dp:CenterMesh} | ||
| use_area_weighting: false | ||
| - _target_: ${dp:NonDimensionalizeByMetadata} | ||
| fields: | ||
| pMeanTrim: pressure | ||
| wallShearStressMeanTrim: stress | ||
| section: point_data | ||
| - _target_: ${dp:RenameMeshFields} | ||
| point_data: | ||
| pMeanTrim: pressure | ||
| wallShearStressMeanTrim: wss | ||
| - _target_: ${dp:NormalizeMeshFields} | ||
| section: point_data | ||
| fields: | ||
| wss: {type: vector, mean: [0.0, 0.0, 0.0], std: 0.00313} | ||
| # - _target_: ${dp:ComputeSurfaceNormals} | ||
| # store_as: point_data | ||
| # field_name: normals | ||
| - _target_: ${dp:SubsampleMesh} | ||
| n_points: ${sampling_resolution} | ||
| - _target_: ${dp:MeshToTensorDict} | ||
| - _target_: ${dp:RestructureTensorDict} | ||
| groups: | ||
| input: | ||
| points: points | ||
| # normals: point_data.normals | ||
| U_inf: global_data.U_inf | ||
| output: | ||
| pressure: point_data.pressure | ||
| wss: point_data.wss | ||
|
|
||
| targets: | ||
| pressure: scalar | ||
| wss: vector | ||
|
|
||
| metrics: [l1, l2, mae] |
82 changes: 82 additions & 0 deletions
82
...cfd/external_aerodynamics/unified_external_aero_recipe/conf/dataset/shift_suv_estate.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES. | ||
| # SPDX-FileCopyrightText: All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # SHIFT SUV Estate surface dataset | ||
| # Triangulated surface mesh. Fields live in cell_data. | ||
|
|
||
| name: shift_suv_estate | ||
|
|
||
| train_datadir: /lustre/fsw/portfolios/coreai/projects/coreai_modulus_cae/datasets/shift_suv_pnm_mesh/SUV/estate/train/ | ||
| val_datadir: /lustre/fsw/portfolios/coreai/projects/coreai_modulus_cae/datasets/shift_suv_pnm_mesh/SUV/estate/val/ | ||
| test_datadir: /lustre/fsw/portfolios/coreai/projects/coreai_modulus_cae/datasets/shift_suv_pnm_mesh/SUV/estate/test/ | ||
|
|
||
| metadata: | ||
| U_inf: [30.0, 0.0, 0.0] # freestream velocity | ||
| p_inf: 101325 # reference pressure (gauge) | ||
| rho_inf: 1.225 # freestream density | ||
| nu: 1.5e-5 # kinematic viscosity | ||
| L_ref: 5.0 # reference length [m] | ||
|
|
||
| pipeline: | ||
| reader: | ||
| _target_: ${dp:MeshReader} | ||
| path: ${train_datadir} | ||
| pattern: "**/merged_surfaces.vtp.pmsh" | ||
| augmentations: | ||
| - _target_: ${dp:RandomRotateMesh} | ||
| axes: ["z"] | ||
| transform_cell_data: true | ||
| transform_global_data: true | ||
| - _target_: ${dp:RandomTranslateMesh} | ||
| max_offset: [1.0, 1.0, 0.0] | ||
| transforms: | ||
| - _target_: ${dp:CenterMesh} | ||
| use_area_weighting: true | ||
| - _target_: ${dp:NonDimensionalizeByMetadata} | ||
| fields: | ||
| pressure_average: pressure | ||
| wall_shear_stress_average: stress | ||
| section: cell_data | ||
| - _target_: ${dp:RenameMeshFields} | ||
| cell_data: | ||
| pressure_average: pressure | ||
| wall_shear_stress_average: wss | ||
| - _target_: ${dp:NormalizeMeshFields} | ||
| section: cell_data | ||
| fields: | ||
| wss: {type: vector, mean: [0.0, 0.0, 0.0], std: 0.00183} | ||
| - _target_: ${dp:ComputeSurfaceNormals} | ||
| store_as: cell_data | ||
| field_name: normals | ||
| - _target_: ${dp:SubsampleMesh} | ||
| n_cells: ${sampling_resolution} | ||
| - _target_: ${dp:MeshToTensorDict} | ||
| - _target_: ${dp:ComputeCellCentroids} | ||
| - _target_: ${dp:RestructureTensorDict} | ||
| groups: | ||
| input: | ||
| points: cell_centroids | ||
| normals: cell_data.normals | ||
| U_inf: global_data.U_inf | ||
| output: | ||
| pressure: cell_data.pressure | ||
| wss: cell_data.wss | ||
|
|
||
| targets: | ||
| pressure: scalar | ||
| wss: vector | ||
|
|
||
| metrics: [l1, l2, mae] |
82 changes: 82 additions & 0 deletions
82
...d/external_aerodynamics/unified_external_aero_recipe/conf/dataset/shift_suv_fastback.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES. | ||
| # SPDX-FileCopyrightText: All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # SHIFT SUV Fastback surface dataset | ||
| # Triangulated surface mesh. Fields live in cell_data. | ||
|
|
||
| name: shift_suv_fastback | ||
|
|
||
| train_datadir: /lustre/fsw/portfolios/coreai/projects/coreai_modulus_cae/datasets/shift_suv_pnm_mesh/SUV/fastback/train/ | ||
| val_datadir: /lustre/fsw/portfolios/coreai/projects/coreai_modulus_cae/datasets/shift_suv_pnm_mesh/SUV/fastback/val/ | ||
| test_datadir: /lustre/fsw/portfolios/coreai/projects/coreai_modulus_cae/datasets/shift_suv_pnm_mesh/SUV/fastback/test/ | ||
|
|
||
| metadata: | ||
| U_inf: [30.0, 0.0, 0.0] # freestream velocity | ||
| p_inf: 101325 # reference pressure (gauge) | ||
| rho_inf: 1.225 # freestream density | ||
| nu: 1.5e-5 # kinematic viscosity | ||
| L_ref: 5.0 # reference length [m] | ||
|
|
||
| pipeline: | ||
| reader: | ||
| _target_: ${dp:MeshReader} | ||
| path: ${train_datadir} | ||
| pattern: "**/merged_surfaces.vtp.pmsh" | ||
| augmentations: | ||
| - _target_: ${dp:RandomRotateMesh} | ||
| axes: ["z"] | ||
| transform_cell_data: true | ||
| transform_global_data: true | ||
| - _target_: ${dp:RandomTranslateMesh} | ||
| max_offset: [1.0, 1.0, 0.0] | ||
| transforms: | ||
| - _target_: ${dp:CenterMesh} | ||
| use_area_weighting: true | ||
| - _target_: ${dp:NonDimensionalizeByMetadata} | ||
| fields: | ||
| pressure_average: pressure | ||
| wall_shear_stress_average: stress | ||
| section: cell_data | ||
| - _target_: ${dp:RenameMeshFields} | ||
| cell_data: | ||
| pressure_average: pressure | ||
| wall_shear_stress_average: wss | ||
| - _target_: ${dp:NormalizeMeshFields} | ||
| section: cell_data | ||
| fields: | ||
| wss: {type: vector, mean: [0.0, 0.0, 0.0], std: 0.00183} | ||
| - _target_: ${dp:ComputeSurfaceNormals} | ||
| store_as: cell_data | ||
| field_name: normals | ||
| - _target_: ${dp:SubsampleMesh} | ||
| n_cells: ${sampling_resolution} | ||
| - _target_: ${dp:MeshToTensorDict} | ||
| - _target_: ${dp:ComputeCellCentroids} | ||
| - _target_: ${dp:RestructureTensorDict} | ||
| groups: | ||
| input: | ||
| points: cell_centroids | ||
| normals: cell_data.normals | ||
| U_inf: global_data.U_inf | ||
| output: | ||
| pressure: cell_data.pressure | ||
| wss: cell_data.wss | ||
|
|
||
| targets: | ||
| pressure: scalar | ||
| wss: vector | ||
|
|
||
| metrics: [l1, l2, mae] |
99 changes: 99 additions & 0 deletions
99
examples/cfd/external_aerodynamics/unified_external_aero_recipe/conf/train_surface.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES. | ||
| # SPDX-FileCopyrightText: All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
| # Unified External Aerodynamics - Surface Training Configuration | ||
| # --------------------------------------------------------------------------- | ||
| # Trains a GeoTransolver model on surface pressure (Cp) and wall shear | ||
| # stress (Cf) from DrivaerML (point cloud) and/or SHIFT SUV (triangulated). | ||
|
|
||
| output_dir: "runs" | ||
| checkpoint_dir: null | ||
| run_id: "surface_geotransolver_shift_suv_estate" | ||
|
|
||
| precision: "bfloat16" | ||
| compile: true | ||
| profile: false | ||
| augment: false | ||
| benchmark_io: false | ||
|
|
||
| model_type: "surface" | ||
|
|
||
| # -- Model (GeoTransolver) -------------------------------------------------- | ||
| model: | ||
| _target_: physicsnemo.experimental.models.geotransolver.GeoTransolver | ||
| functional_dim: 6 # local_embedding = geometry coords (3) + normals (3) | ||
| out_dim: 4 # pressure (1) + wss (3) | ||
| geometry_dim: 3 # point coordinates | ||
| global_dim: 3 # inlet velocity (3) | ||
| n_layers: 12 | ||
| n_hidden: 256 | ||
| dropout: 0.0 | ||
| n_head: 8 | ||
| act: "gelu" | ||
| mlp_ratio: 4 | ||
| slice_num: 256 | ||
| use_te: false | ||
| plus: false | ||
| include_local_features: false | ||
| radii: [0.1, 0.5, 2.0] | ||
| neighbors_in_radius: [16, 32, 64] | ||
| n_hidden_local: 32 | ||
|
|
||
| # -- Dataset ----------------------------------------------------------------- | ||
| dataset: | ||
| name: drivaer_ml_surface | ||
| sampling_resolution: 200000 # override SubsampleMesh n_cells/n_points in all dataset configs | ||
| targets: | ||
| pressure: scalar | ||
| wss: vector | ||
| metrics: [l1, l2, mae] | ||
|
|
||
| # -- Training ---------------------------------------------------------------- | ||
| training: | ||
| num_epochs: 500 | ||
| save_interval: 25 | ||
| loss_type: "huber" | ||
| batch_size: 1 | ||
| scheduler_update_mode: "epoch" | ||
|
|
||
| optimizer: | ||
| lr: 1.0e-3 | ||
| weight_decay: 1.0e-4 | ||
| betas: [0.9, 0.999] | ||
| eps: 1.0e-8 | ||
|
|
||
| scheduler: | ||
| _target_: torch.optim.lr_scheduler.StepLR | ||
| step_size: 100 | ||
| gamma: 0.1 | ||
|
|
||
| # -- DataLoader / Dataset Performance Tuning -------------------------------- | ||
| dataloader: | ||
| prefetch_factor: 1 | ||
| num_streams: 1 | ||
| use_streams: true | ||
| num_workers: 1 | ||
| pin_memory: true | ||
|
|
||
| # -- Data paths (override per-machine) -------------------------------------- | ||
| data: | ||
| drivaer_ml: | ||
| config: conf/dataset/drivaer_ml_surface.yaml | ||
| shift_suv_estate: | ||
| config: conf/dataset/shift_suv_estate.yaml | ||
| shift_suv_fastback: | ||
| config: conf/dataset/shift_suv_fastback.yaml |
7 changes: 7 additions & 0 deletions
7
examples/cfd/external_aerodynamics/unified_external_aero_recipe/requirements.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| hydra-core>=1.3 | ||
| omegaconf>=2.3 | ||
| pandas | ||
| pyarrow | ||
| tabulate | ||
| tensorboard | ||
| tensordict | ||
15 changes: 15 additions & 0 deletions
15
examples/cfd/external_aerodynamics/unified_external_aero_recipe/src/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2023 - 2026 NVIDIA CORPORATION & AFFILIATES. | ||
| # SPDX-FileCopyrightText: All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.