Skip to content

Conversation

@ajyu
Copy link
Contributor

@ajyu ajyu commented Mar 7, 2022

Summary:
Fuse the following pattern:

%1994 : Tensor = aten::to(%getattr_78.1, %188, %189, %189) # <eval_with_key>.50:11:0
%1995 : Tensor = fb::lengths_to_offsets(%1994, %190) # /mnt/xarfuse/uid-1994

This pattern is applied after all the applicable clip_ranges+gather_ranges patterns

Additional context in https://fb.quip.com/DSCbAozMBwUi

Test Plan:

./caffe2/caffe2/fb/predictor/scripts/run_disagg_model_benchmarks.sh 321004917 27 /data/users/ansha/tmp/ads_tail sr_only

~0.007ms overall reduction in tail model runtime
(321004917_27 oemae_long_attr_win_2d_7d_aux_model)

Local (25 fused nodes)
Before: 2.04ms/iter
0.0112739 ms. 0.543996%. fb::lengths_to_offsets (31 nodes, out variant)
0.00805597 ms. 0.388722%. static_runtime::to_maybe_copy_out (30 nodes, out variant)

After: 1.96256ms/iter
0.0100853 ms. 0.498655%. fb::to_lengths_to_offsets (25 nodes, out variant)
0.00328385 ms. 0.157536%. fb::lengths_to_offsets (6 nodes, out variant)
0.00239722 ms. 0.115002%. static_runtime::to_maybe_copy_out (5 nodes, out variant)

Local_RO (43 fused nodes)
Before: 0.11427
0.0110696 ms. 9.42255%. fb::lengths_to_offsets (43 nodes, out variant)
0.00638323 ms. 5.43349%. static_runtime::to_maybe_copy_out (43 nodes, out variant)
After: 0.112098ms/iter
0.014206 ms. 12.6795%. fb::to_lengths_to_offsets (43 nodes, out variant)

Remote_RO (17 fused nodes)
Before: 0.24
0.0534883 ms. 23.0586%. static_runtime::to_maybe_copy_out (136 nodes, out variant)
0.00216992 ms. 0.935446%. fb::lengths_to_offsets (17 nodes, out variant)
After: 0.240225
0.0525392 ms. 23.2864%. static_runtime::to_maybe_copy_out (119 nodes, out variant)
0.00265347 ms. 1.17607%. fb::to_lengths_to_offsets (17 nodes, out variant)

Remote_Other (3 fused nodes)
Not much affect

Differential Revision: D34696255

@pytorch-bot
Copy link

pytorch-bot bot commented Mar 7, 2022

CI Flow Status

⚛️ CI Flow

Ruleset - Version: v1
Ruleset - File: https://github.com/ajyu/pytorch/blob/3c8a5a6a8363dc30c5a079103e3ca9bcb6d82319/.github/generated-ciflow-ruleset.json
PR ciflow labels: ciflow/default
Add ciflow labels to this PR to trigger more builds:

Workflows Labels (bold enabled) Status
Triggered Workflows
linux-binary-conda ciflow/binaries, ciflow/binaries_conda, ciflow/default ✅ triggered
linux-binary-libtorch-cxx11-abi ciflow/all, ciflow/binaries, ciflow/binaries_libtorch, ciflow/default, ciflow/trunk ✅ triggered
linux-binary-libtorch-pre-cxx11 ciflow/all, ciflow/binaries, ciflow/binaries_libtorch, ciflow/default, ciflow/trunk ✅ triggered
linux-binary-manywheel ciflow/all, ciflow/binaries, ciflow/binaries_wheel, ciflow/default, ciflow/trunk ✅ triggered
linux-bionic-py3.7-clang9 ciflow/all, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/noarch, ciflow/trunk ✅ triggered
linux-bionic-rocm4.5-py3.7 ciflow/all, ciflow/default, ciflow/linux, ciflow/rocm, ciflow/trunk ✅ triggered
linux-docs ciflow/all, ciflow/cpu, ciflow/default, ciflow/docs, ciflow/linux, ciflow/trunk ✅ triggered
linux-vulkan-bionic-py3.7-clang9 ciflow/all, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/trunk, ciflow/vulkan ✅ triggered
linux-xenial-cuda11.3-py3.7-gcc7 ciflow/all, ciflow/cuda, ciflow/default, ciflow/linux, ciflow/trunk ✅ triggered
linux-xenial-cuda11.3-py3.7-gcc7-bazel-test ciflow/all, ciflow/bazel, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/trunk ✅ triggered
linux-xenial-py3-clang5-mobile-build ciflow/all, ciflow/default, ciflow/linux, ciflow/mobile, ciflow/trunk ✅ triggered
linux-xenial-py3-clang5-mobile-custom-build-static ciflow/all, ciflow/default, ciflow/linux, ciflow/mobile, ciflow/trunk ✅ triggered
linux-xenial-py3.7-clang7-asan ciflow/all, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/sanitizers, ciflow/trunk ✅ triggered
linux-xenial-py3.7-clang7-onnx ciflow/all, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/onnx, ciflow/trunk ✅ triggered
linux-xenial-py3.7-gcc5.4 ciflow/all, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/trunk ✅ triggered
linux-xenial-py3.7-gcc5.4-mobile-lightweight-dispatch-build ciflow/all, ciflow/cpu, ciflow/default, ciflow/libtorch, ciflow/linux, ciflow/mobile, ciflow/trunk ✅ triggered
linux-xenial-py3.7-gcc7 ciflow/all, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/trunk ✅ triggered
linux-xenial-py3.7-gcc7-no-ops ciflow/all, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/trunk ✅ triggered
macos-arm64-binary-conda ciflow/binaries, ciflow/binaries_conda, ciflow/default ✅ triggered
macos-arm64-binary-wheel ciflow/binaries, ciflow/binaries_wheel, ciflow/default ✅ triggered
macos-binary-conda ciflow/binaries, ciflow/binaries_conda, ciflow/default ✅ triggered
macos-binary-libtorch-cxx11-abi ciflow/binaries, ciflow/binaries_libtorch, ciflow/default ✅ triggered
macos-binary-libtorch-pre-cxx11 ciflow/binaries, ciflow/binaries_libtorch, ciflow/default ✅ triggered
macos-binary-wheel ciflow/binaries, ciflow/binaries_wheel, ciflow/default ✅ triggered
pytorch-linux-xenial-py3-clang5-android-ndk-r19c-gradle-custom-build-single ciflow/all, ciflow/android, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/trunk ✅ triggered
pytorch-linux-xenial-py3-clang5-android-ndk-r19c-gradle-custom-build-single-full-jit ciflow/all, ciflow/android, ciflow/cpu, ciflow/default, ciflow/linux, ciflow/trunk ✅ triggered
win-vs2019-cpu-py3 ciflow/all, ciflow/cpu, ciflow/default, ciflow/trunk, ciflow/win ✅ triggered
win-vs2019-cuda11.3-py3 ciflow/all, ciflow/cuda, ciflow/default, ciflow/trunk, ciflow/win ✅ triggered
windows-binary-conda ciflow/binaries, ciflow/binaries_conda, ciflow/default ✅ triggered
windows-binary-libtorch-debug ciflow/all, ciflow/binaries, ciflow/binaries_libtorch, ciflow/default, ciflow/trunk ✅ triggered
windows-binary-libtorch-release ciflow/all, ciflow/binaries, ciflow/binaries_libtorch, ciflow/default, ciflow/trunk ✅ triggered
windows-binary-wheel ciflow/all, ciflow/binaries, ciflow/binaries_wheel, ciflow/default, ciflow/trunk ✅ triggered
Skipped Workflows
caffe2-linux-xenial-py3.7-gcc5.4 ciflow/all, ciflow/cpu, ciflow/linux, ciflow/trunk 🚫 skipped
docker-builds ciflow/all, ciflow/trunk 🚫 skipped
ios-12-5-1-arm64 ciflow/all, ciflow/ios, ciflow/macos, ciflow/scheduled 🚫 skipped
ios-12-5-1-arm64-coreml ciflow/all, ciflow/ios, ciflow/macos, ciflow/scheduled 🚫 skipped
ios-12-5-1-arm64-custom-ops ciflow/all, ciflow/ios, ciflow/macos, ciflow/scheduled 🚫 skipped
ios-12-5-1-arm64-metal ciflow/all, ciflow/ios, ciflow/macos, ciflow/scheduled 🚫 skipped
ios-12-5-1-x86-64 ciflow/all, ciflow/ios, ciflow/macos, ciflow/trunk 🚫 skipped
ios-12-5-1-x86-64-coreml ciflow/all, ciflow/ios, ciflow/macos, ciflow/trunk 🚫 skipped
libtorch-linux-xenial-cuda10.2-py3.7-gcc7 ciflow/all, ciflow/cuda, ciflow/libtorch, ciflow/linux, ciflow/trunk 🚫 skipped
libtorch-linux-xenial-cuda11.3-py3.7-gcc7 ciflow/all, ciflow/cuda, ciflow/libtorch, ciflow/linux, ciflow/trunk 🚫 skipped
linux-bionic-cuda10.2-py3.9-gcc7 ciflow/all, ciflow/cuda, ciflow/linux, ciflow/slow, ciflow/trunk 🚫 skipped
linux-docs-push ciflow/all, ciflow/cpu, ciflow/linux, ciflow/scheduled 🚫 skipped
linux-xenial-cuda11.3-py3.7-gcc7-no-ops ciflow/all, ciflow/cuda, ciflow/linux, ciflow/trunk 🚫 skipped
macos-10-15-py3-arm64 ciflow/all, ciflow/macos, ciflow/trunk 🚫 skipped
macos-10-15-py3-lite-interpreter-x86-64 ciflow/all, ciflow/macos, ciflow/trunk 🚫 skipped
macos-11-py3-x86-64 ciflow/all, ciflow/macos, ciflow/trunk 🚫 skipped
parallelnative-linux-xenial-py3.7-gcc5.4 ciflow/all, ciflow/cpu, ciflow/linux, ciflow/trunk 🚫 skipped
periodic-libtorch-linux-bionic-cuda11.5-py3.7-gcc7 ciflow/all, ciflow/cuda, ciflow/libtorch, ciflow/linux, ciflow/scheduled 🚫 skipped
periodic-linux-bionic-cuda11.5-py3.7-gcc7 ciflow/all, ciflow/cuda, ciflow/linux, ciflow/scheduled 🚫 skipped
periodic-linux-xenial-cuda10.2-py3-gcc7-slow-gradcheck ciflow/all, ciflow/cuda, ciflow/linux, ciflow/scheduled, ciflow/slow, ciflow/slow-gradcheck 🚫 skipped
periodic-linux-xenial-cuda11.3-py3.7-gcc7-debug ciflow/all, ciflow/cuda, ciflow/linux, ciflow/scheduled 🚫 skipped
periodic-win-vs2019-cuda11.5-py3 ciflow/all, ciflow/cuda, ciflow/scheduled, ciflow/win 🚫 skipped
pytorch-linux-xenial-py3-clang5-android-ndk-r19c-build ciflow/all, ciflow/android, ciflow/cpu, ciflow/linux, ciflow/trunk 🚫 skipped
pytorch-xla-linux-bionic-py3.7-clang8 ciflow/all, ciflow/cpu, ciflow/linux, ciflow/trunk, ciflow/xla 🚫 skipped

@facebook-github-bot
Copy link
Contributor

facebook-github-bot commented Mar 7, 2022

🔗 Helpful links

💊 CI failures summary and remediations

As of commit 1ce8e40 (more details on the Dr. CI page):


  • 1/1 failures introduced in this PR

🕵️ 1 new failure recognized by patterns

The following CI failures do not appear to be due to upstream breakages:

See GitHub Actions build pull / linux-bionic-rocm4.5-py3.7 / build (1/1)

Step: "Calculate docker image" (full log | diagnosis details | 🔁 rerun)

2022-03-21T20:02:33.4284529Z ERROR: Something h... isn't available for the merge-base of your branch
2022-03-21T20:02:33.4235467Z + [[ 288de548fd0e270b527d941f8d08302006ad9fa5 = \1\c\e\8\e\4\0\5\4\9\f\2\8\6\9\a\d\4\f\7\7\6\d\d\e\9\0\e\9\3\9\b\e\d\7\a\7\4\e\e ]]
2022-03-21T20:02:33.4238367Z ++ git merge-base HEAD 288de548fd0e270b527d941f8d08302006ad9fa5
2022-03-21T20:02:33.4252944Z + MERGE_BASE=288de548fd0e270b527d941f8d08302006ad9fa5
2022-03-21T20:02:33.4253380Z + git rev-parse 288de548fd0e270b527d941f8d08302006ad9fa5:.circleci/docker
2022-03-21T20:02:33.4266222Z 1a95a1a070af5dce05d58354e8615737c1134998
2022-03-21T20:02:33.4269867Z ++ git rev-parse 288de548fd0e270b527d941f8d08302006ad9fa5:.circleci/docker
2022-03-21T20:02:33.4282231Z + PREVIOUS_DOCKER_TAG=1a95a1a070af5dce05d58354e8615737c1134998
2022-03-21T20:02:33.4282824Z + [[ 1a95a1a070af5dce05d58354e8615737c1134998 = \1\a\9\5\a\1\a\0\7\0\a\f\5\d\c\e\0\5\d\5\8\3\5\4\e\8\6\1\5\7\3\7\c\1\1\3\4\9\9\8 ]]
2022-03-21T20:02:33.4283720Z + echo 'ERROR: Something has gone wrong and the previous image isn'\''t available for the merge-base of your branch'
2022-03-21T20:02:33.4284115Z + echo '       contact the PyTorch team to restore the original images'
2022-03-21T20:02:33.4284529Z ERROR: Something has gone wrong and the previous image isn't available for the merge-base of your branch
2022-03-21T20:02:33.4284855Z        contact the PyTorch team to restore the original images
2022-03-21T20:02:33.4285073Z + exit 1
2022-03-21T20:02:33.4294112Z ##[error]Process completed with exit code 1.
2022-03-21T20:02:33.4477156Z ##[group]Run pytorch/pytorch/.github/actions/chown-workspace@master
2022-03-21T20:02:33.4477399Z env:
2022-03-21T20:02:33.4477562Z   IN_CI: 1
2022-03-21T20:02:33.4477729Z   IS_GHA: 1
2022-03-21T20:02:33.4477884Z ##[endgroup]
2022-03-21T20:02:33.4490413Z ##[group]Run docker run --rm -v "$(pwd)":/v -w /v "${ALPINE_IMAGE}" chown -R "$(id -u):$(id -g)" .
2022-03-21T20:02:33.4490760Z �[36;1mdocker run --rm -v "$(pwd)":/v -w /v "${ALPINE_IMAGE}" chown -R "$(id -u):$(id -g)" .�[0m

This comment was automatically generated by Dr. CI (expand for details).

Please report bugs/suggestions to the (internal) Dr. CI Users group.

Click here to manually regenerate this comment.

@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D34696255

@facebook-github-bot facebook-github-bot added the oncall: jit Add this issue/PR to JIT oncall triage queue label Mar 7, 2022
Summary:
Pull Request resolved: pytorch#73879

Fuse the following pattern:
```
%1994 : Tensor = aten::to(%getattr_78.1, %188, %189, %189) # <eval_with_key>.50:11:0
%1995 : Tensor = fb::lengths_to_offsets(%1994, %190) # /mnt/xarfuse/uid-1994
```

This pattern is applied after all the applicable clip_ranges+gather_ranges patterns

Additional context in https://fb.quip.com/DSCbAozMBwUi

Test Plan:
> ./caffe2/caffe2/fb/predictor/scripts/run_disagg_model_benchmarks.sh 321004917 27 /data/users/ansha/tmp/ads_tail sr_only

~0.007ms overall reduction in tail model runtime
(321004917_27 oemae_long_attr_win_2d_7d_aux_model)

**Local  (25 fused nodes)**
Before: 2.04ms/iter
      0.0112739 ms.   0.543996%. fb::lengths_to_offsets (31 nodes, out variant)
     0.00805597 ms.   0.388722%. static_runtime::to_maybe_copy_out (30 nodes, out variant)

After: 1.96256ms/iter
      0.0100853 ms.   0.498655%. fb::to_lengths_to_offsets (25 nodes, out variant)
     0.00328385 ms.   0.157536%. fb::lengths_to_offsets (6 nodes, out variant)
     0.00239722 ms.   0.115002%. static_runtime::to_maybe_copy_out (5 nodes, out variant)

**Local_RO  (43 fused nodes)**
Before: 0.11427
      0.0110696 ms.    9.42255%. fb::lengths_to_offsets (43 nodes, out variant)
     0.00638323 ms.    5.43349%. static_runtime::to_maybe_copy_out (43 nodes, out variant)
After: 0.112098ms/iter
       0.014206 ms.    12.6795%. fb::to_lengths_to_offsets (43 nodes, out variant)

**Remote_RO (17 fused nodes)**
Before: 0.24
      0.0534883 ms.    23.0586%. static_runtime::to_maybe_copy_out (136 nodes, out variant)
     0.00216992 ms.   0.935446%. fb::lengths_to_offsets (17 nodes, out variant)
After: 0.240225
      0.0525392 ms.    23.2864%. static_runtime::to_maybe_copy_out (119 nodes, out variant)
     0.00265347 ms.    1.17607%. fb::to_lengths_to_offsets (17 nodes, out variant)

Remote_Other (3 fused nodes)
Not much affect

Differential Revision: D34696255

fbshipit-source-id: d9b07a9f7f3b3ec83584305295de5cdad538abc9
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D34696255

@ajyu ajyu force-pushed the export-D34696255 branch from 3c8a5a6 to 1ce8e40 Compare March 21, 2022 20:00
facebook-github-bot pushed a commit that referenced this pull request Mar 24, 2022
Summary:
Pull Request resolved: #73879

Fuse the following pattern:
```
%1994 : Tensor = aten::to(%getattr_78.1, %188, %189, %189) # <eval_with_key>.50:11:0
%1995 : Tensor = fb::lengths_to_offsets(%1994, %190) # /mnt/xarfuse/uid-1994
```

This pattern is applied after all the applicable clip_ranges+gather_ranges patterns

Additional context in https://fb.quip.com/DSCbAozMBwUi

Test Plan:
> ./caffe2/caffe2/fb/predictor/scripts/run_disagg_model_benchmarks.sh 321004917 27 /data/users/ansha/tmp/ads_tail sr_only

~0.007ms overall reduction in tail model runtime
(321004917_27 oemae_long_attr_win_2d_7d_aux_model)

**Local  (25 fused nodes)**
Before: 2.04ms/iter
      0.0112739 ms.   0.543996%. fb::lengths_to_offsets (31 nodes, out variant)
     0.00805597 ms.   0.388722%. static_runtime::to_maybe_copy_out (30 nodes, out variant)

After: 1.96256ms/iter
      0.0100853 ms.   0.498655%. fb::to_lengths_to_offsets (25 nodes, out variant)
     0.00328385 ms.   0.157536%. fb::lengths_to_offsets (6 nodes, out variant)
     0.00239722 ms.   0.115002%. static_runtime::to_maybe_copy_out (5 nodes, out variant)

**Local_RO  (43 fused nodes)**
Before: 0.11427
      0.0110696 ms.    9.42255%. fb::lengths_to_offsets (43 nodes, out variant)
     0.00638323 ms.    5.43349%. static_runtime::to_maybe_copy_out (43 nodes, out variant)
After: 0.112098ms/iter
       0.014206 ms.    12.6795%. fb::to_lengths_to_offsets (43 nodes, out variant)

**Remote_RO (17 fused nodes)**
Before: 0.24
      0.0534883 ms.    23.0586%. static_runtime::to_maybe_copy_out (136 nodes, out variant)
     0.00216992 ms.   0.935446%. fb::lengths_to_offsets (17 nodes, out variant)
After: 0.240225
      0.0525392 ms.    23.2864%. static_runtime::to_maybe_copy_out (119 nodes, out variant)
     0.00265347 ms.    1.17607%. fb::to_lengths_to_offsets (17 nodes, out variant)

Remote_Other (3 fused nodes)
Not much affect

Reviewed By: mikeiovine

Differential Revision: D34696255

fbshipit-source-id: a0dc4a8ff8f25a825f6dc371ec5e4b3b09740c29
@github-actions
Copy link
Contributor

Hey @ajyu.
You've committed this PR, but it does not have both a 'release notes: ...' and 'topics: ...' label. Please add one of each to the PR. The 'release notes: ...' label should represent the part of PyTorch that this PR changes (fx, autograd, distributed, etc) and the 'topics: ...' label should represent the kind of PR it is (not user facing, new feature, bug fix, perf improvement, etc). The list of valid labels can be found here for the 'release notes: ...' and here for the 'topics: ...'.
For changes that are 'topic: not user facing' there is no need for a release notes label.

shahofblah pushed a commit that referenced this pull request Mar 25, 2022
Summary:
Pull Request resolved: #73879

Fuse the following pattern:
```
%1994 : Tensor = aten::to(%getattr_78.1, %188, %189, %189) # <eval_with_key>.50:11:0
%1995 : Tensor = fb::lengths_to_offsets(%1994, %190) # /mnt/xarfuse/uid-1994
```

This pattern is applied after all the applicable clip_ranges+gather_ranges patterns

Additional context in https://fb.quip.com/DSCbAozMBwUi

Test Plan:
> ./caffe2/caffe2/fb/predictor/scripts/run_disagg_model_benchmarks.sh 321004917 27 /data/users/ansha/tmp/ads_tail sr_only

~0.007ms overall reduction in tail model runtime
(321004917_27 oemae_long_attr_win_2d_7d_aux_model)

**Local  (25 fused nodes)**
Before: 2.04ms/iter
      0.0112739 ms.   0.543996%. fb::lengths_to_offsets (31 nodes, out variant)
     0.00805597 ms.   0.388722%. static_runtime::to_maybe_copy_out (30 nodes, out variant)

After: 1.96256ms/iter
      0.0100853 ms.   0.498655%. fb::to_lengths_to_offsets (25 nodes, out variant)
     0.00328385 ms.   0.157536%. fb::lengths_to_offsets (6 nodes, out variant)
     0.00239722 ms.   0.115002%. static_runtime::to_maybe_copy_out (5 nodes, out variant)

**Local_RO  (43 fused nodes)**
Before: 0.11427
      0.0110696 ms.    9.42255%. fb::lengths_to_offsets (43 nodes, out variant)
     0.00638323 ms.    5.43349%. static_runtime::to_maybe_copy_out (43 nodes, out variant)
After: 0.112098ms/iter
       0.014206 ms.    12.6795%. fb::to_lengths_to_offsets (43 nodes, out variant)

**Remote_RO (17 fused nodes)**
Before: 0.24
      0.0534883 ms.    23.0586%. static_runtime::to_maybe_copy_out (136 nodes, out variant)
     0.00216992 ms.   0.935446%. fb::lengths_to_offsets (17 nodes, out variant)
After: 0.240225
      0.0525392 ms.    23.2864%. static_runtime::to_maybe_copy_out (119 nodes, out variant)
     0.00265347 ms.    1.17607%. fb::to_lengths_to_offsets (17 nodes, out variant)

Remote_Other (3 fused nodes)
Not much affect

Reviewed By: mikeiovine

Differential Revision: D34696255

fbshipit-source-id: a0dc4a8ff8f25a825f6dc371ec5e4b3b09740c29
(cherry picked from commit a49b482)
@facebook-github-bot
Copy link
Contributor

This pull request has been reverted by 91a72e9. To re-land this change, please open another pull request, assignthe same reviewers, fix the CI failures that caused the revert and make sure that the failing CI runs on the PR by applying the proper ciflow label (e.g., ciflow/trunk).

@facebook-github-bot
Copy link
Contributor

This pull request has been reverted by 91a72e9. To re-land this change, please open another pull request, assignthe same reviewers, fix the CI failures that caused the revert and make sure that the failing CI runs on the PR by applying the proper ciflow label (e.g., ciflow/trunk).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla signed fb-exported oncall: jit Add this issue/PR to JIT oncall triage queue Reverted

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants