diff --git a/.github/ISSUE_TEMPLATE/sub-task.md b/.github/ISSUE_TEMPLATE/sub-task.md index 34374422b3f2d..21c1855bc4283 100644 --- a/.github/ISSUE_TEMPLATE/sub-task.md +++ b/.github/ISSUE_TEMPLATE/sub-task.md @@ -2,7 +2,7 @@ name: 🍰 Sub-Task about: Reserve a sub-task from a ToDo list issue title: "" -labels: Sub Task, hacktoberfest +labels: Sub Task assignees: '' --- diff --git a/.github/workflows/array-api-intelligent-tests-pr.yml b/.github/workflows/array-api-intelligent-tests-pr.yml index 2bb007f86ba61..e67478445676e 100644 --- a/.github/workflows/array-api-intelligent-tests-pr.yml +++ b/.github/workflows/array-api-intelligent-tests-pr.yml @@ -1,7 +1,7 @@ name: array-api-intelligent-tests-pr on: pull_request: - types: [ labeled, opened, synchronize, reopened, review_requested ] + types: [opened, synchronize, reopened, review_requested ] permissions: actions: read diff --git a/.github/workflows/binaries.yml b/.github/workflows/binaries.yml index 51dd639e700d0..9520707a2bd18 100644 --- a/.github/workflows/binaries.yml +++ b/.github/workflows/binaries.yml @@ -6,11 +6,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout πŸ›ŽοΈBinaries - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: repository: unifyai/binaries + token: ${{ secrets.IVY_BRANCH_TOKEN }} path: binaries - persist-credentials: false - name: Add Tag to Binaries run: | diff --git a/.github/workflows/dockerfile-image.yml b/.github/workflows/dockerfile-image.yml index 3f82ea05ea63c..fd19c2b90ab7c 100644 --- a/.github/workflows/dockerfile-image.yml +++ b/.github/workflows/dockerfile-image.yml @@ -4,7 +4,7 @@ on: push: branches: [ "main" ] pull_request: - types: [labeled, review_requested] + types: [review_requested] branches: [ "main" ] jobs: diff --git a/.github/workflows/intelligent-tests-pr.yml b/.github/workflows/intelligent-tests-pr.yml index ece59285375a0..91e08239a9d23 100644 --- a/.github/workflows/intelligent-tests-pr.yml +++ b/.github/workflows/intelligent-tests-pr.yml @@ -2,7 +2,7 @@ name: intelligent-tests-pr on: workflow_dispatch: pull_request: - types: [labeled, opened, synchronize, reopened, review_requested] + types: [opened, synchronize, reopened, review_requested] permissions: actions: read diff --git a/.github/workflows/intelligent-tests.yml b/.github/workflows/intelligent-tests.yml index d4e2ec5de132a..6614e53eb42fd 100644 --- a/.github/workflows/intelligent-tests.yml +++ b/.github/workflows/intelligent-tests.yml @@ -89,7 +89,7 @@ jobs: run: | cd ivy set -o pipefail - python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'false' ${{ steps.jobs.outputs.html_url }} | tee test_results_${{ matrix.branch }}.txt + python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'false' 'false' ${{ steps.jobs.outputs.html_url }} | tee test_results_${{ matrix.branch }}.txt continue-on-error: true - name: Upload test results diff --git a/.github/workflows/manual-tests.yml b/.github/workflows/manual-tests.yml index 819ff6cccc31e..71c231e952c49 100644 --- a/.github/workflows/manual-tests.yml +++ b/.github/workflows/manual-tests.yml @@ -17,6 +17,11 @@ on: default: false required: false + tracer: + description: 'Tracer Testing :' + default: false + required: false + permissions: actions: read @@ -40,7 +45,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem @@ -59,7 +64,7 @@ jobs: pip3 install pymongo cd ivy python3 scripts/setup_tests/setup_tests.py ${{ github.event.inputs.test }} - python3 scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' ${{ github.event.inputs.gpu }} ${{ github.run_id }} 'false' ${{ steps.jobs.outputs.html_url }} + python3 scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' ${{ github.event.inputs.gpu }} ${{ github.run_id }} 'false' ${{ github.event.inputs.tracer }} ${{ steps.jobs.outputs.html_url }} continue-on-error: true - name: Check on failures @@ -81,7 +86,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem @@ -99,9 +104,9 @@ jobs: run: | pip3 install pymongo cd ivy - pip3 install -e . + sudo pip3 install -e . python scripts/setup_tests/setup_tests.py "${{ github.event.inputs.test }}" - python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} ${{ github.event.inputs.version}} 'false' ${{ github.run_id }} 'false' ${{ steps.jobs.outputs.html_url }} + python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} ${{ github.event.inputs.version}} 'false' ${{ github.run_id }} 'false' ${{ github.event.inputs.tracer }} ${{ steps.jobs.outputs.html_url }} continue-on-error: true - name: Check on failures diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index c7ccc919b6e61..249038c320383 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -35,9 +35,9 @@ jobs: - name: Run CPU Tests run: | cd ivy - python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'true' ${{ steps.jobs.outputs.html_url }} + python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'true' 'false' ${{ steps.jobs.outputs.html_url }} - name: Run GPU Tests run: | cd ivy - python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'true' ${{ github.run_id }} 'true' ${{ steps.jobs.outputs.html_url }} + python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'true' ${{ github.run_id }} 'true' 'false' ${{ steps.jobs.outputs.html_url }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f29e7b8bbf2c8..98f08e09360a6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: publish-binaries: name: Publish Binaries - uses: unifyai/workflows/.github/workflows/binaries.yml@main + uses: ./.github/workflows/binaries.yml secrets: inherit deploy: diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 64153d06ffa31..c7bebee196cf6 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -45,7 +45,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem @@ -64,7 +64,7 @@ jobs: cd ivy python scripts/setup_tests/filter_tests.py ${{ matrix.branch }} set -o pipefail - python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'false' ${{ steps.jobs.outputs.html_url }} | tee test_results_${{ matrix.branch }}.txt + python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'false' 'false' ${{ steps.jobs.outputs.html_url }} | tee test_results_${{ matrix.branch }}.txt continue-on-error: true - name: Upload test results diff --git a/.github/workflows/run-failing-tests.yml b/.github/workflows/run-failing-tests.yml new file mode 100644 index 0000000000000..e15935ccd581d --- /dev/null +++ b/.github/workflows/run-failing-tests.yml @@ -0,0 +1,76 @@ +name: Run Failing Tests +on: + workflow_dispatch: + inputs: + priority: + description: 'Priority:' + default: true + required: false + +permissions: + actions: read +jobs: + display_test_results: + if: ${{ always() }} + runs-on: ubuntu-latest + needs: + - run_tests + + steps: + - name: Download all test results + uses: actions/download-artifact@v3 + + - name: Combined Test Results + run: | + find . -name "test_results_*.txt" -exec cat {} + > combined_test_results.txt + echo "Test results summary:" + cat combined_test_results.txt + + run_tests: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + branch: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128 ] + steps: + - name: Checkout Ivy πŸ›Ž + uses: actions/checkout@v3 + with: + path: ivy + persist-credentials: false + submodules: "recursive" + fetch-depth: 1 + + - name: Get Job URL + uses: Tiryoh/gha-jobid-action@v0 + id: jobs + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + job_name: ${{ github.job }} + + - name: Setup Tests + run: | + pip3 install pymongo + cd ivy + mkdir .ivy + touch .ivy/key.pem + echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem + python scripts/setup_tests/setup_failing_tests.py ${{ github.event.inputs.priority }} ${{ matrix.branch }} + + - name: Run Tests + run: | + cd ivy + python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'false' 'false' ${{ steps.jobs.outputs.html_url }} + continue-on-error: true diff --git a/.github/workflows/test-docstrings.yml b/.github/workflows/test-docstrings.yml index c8b7f6bf519f1..77be6f4e6c969 100644 --- a/.github/workflows/test-docstrings.yml +++ b/.github/workflows/test-docstrings.yml @@ -2,7 +2,7 @@ name: test-docstrings on: push: pull_request: - types: [labeled, opened, synchronize, reopened, review_requested] + types: [opened, synchronize, reopened, review_requested] workflow_dispatch: jobs: run-docstring-tests: diff --git a/.github/workflows/test-frontend-jax.yml b/.github/workflows/test-frontend-jax.yml index 7724876d33b7e..13e676f735a5a 100644 --- a/.github/workflows/test-frontend-jax.yml +++ b/.github/workflows/test-frontend-jax.yml @@ -19,7 +19,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem diff --git a/.github/workflows/test-frontend-numpy.yml b/.github/workflows/test-frontend-numpy.yml index d99000c459b95..464b98a0d802d 100644 --- a/.github/workflows/test-frontend-numpy.yml +++ b/.github/workflows/test-frontend-numpy.yml @@ -19,7 +19,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem diff --git a/.github/workflows/test-frontend-tensorflow.yml b/.github/workflows/test-frontend-tensorflow.yml index f5a03dcef7e1a..1ba8b51c427d6 100644 --- a/.github/workflows/test-frontend-tensorflow.yml +++ b/.github/workflows/test-frontend-tensorflow.yml @@ -19,7 +19,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem diff --git a/.github/workflows/test-frontend-torch.yml b/.github/workflows/test-frontend-torch.yml index 732958fd972a4..acbe96ab030c4 100644 --- a/.github/workflows/test-frontend-torch.yml +++ b/.github/workflows/test-frontend-torch.yml @@ -19,7 +19,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem diff --git a/.github/workflows/test-ivy-core.yml b/.github/workflows/test-ivy-core.yml index f87a42a0abb43..25c41a929e9e8 100644 --- a/.github/workflows/test-ivy-core.yml +++ b/.github/workflows/test-ivy-core.yml @@ -30,7 +30,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem diff --git a/.github/workflows/test-ivy-cron-gpu.yml b/.github/workflows/test-ivy-cron-gpu.yml index b4cd6719fbe58..03e8f5b36851c 100644 --- a/.github/workflows/test-ivy-cron-gpu.yml +++ b/.github/workflows/test-ivy-cron-gpu.yml @@ -1,8 +1,8 @@ name: test-ivy-cron-gpu on: workflow_dispatch: - schedule: - - cron: '25 * * * *' + # schedule: + # - cron: '25 * * * *' permissions: actions: read concurrency: @@ -56,7 +56,7 @@ jobs: run: | cd ivy export TAG="cp310-cp310-manylinux_2_17_x86_64" - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem @@ -74,8 +74,8 @@ jobs: run: | pip3 install pymongo cd ivy - python3 scripts/setup_tests/cron_tests.py ${{ github.run_number }} true - python3 scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'true' ${{ github.run_id }} 'false' ${{ steps.jobs.outputs.html_url }} + python3 scripts/setup_tests/cron_tests.py ${{ github.run_number }} true false + python3 scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'true' ${{ github.run_id }} 'false' 'false' ${{ steps.jobs.outputs.html_url }} stop-vm: needs: run-gpu-tests diff --git a/.github/workflows/test-ivy-cron-multi-version.yml b/.github/workflows/test-ivy-cron-multi-version.yml index fd36dd585d175..5f4177b3d0cf7 100644 --- a/.github/workflows/test-ivy-cron-multi-version.yml +++ b/.github/workflows/test-ivy-cron-multi-version.yml @@ -19,7 +19,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem @@ -38,7 +38,7 @@ jobs: cd ivy pip3 install pymongo python scripts/setup_tests/cron_tests_multi_version.py ${{ github.run_number }} - python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'true' 'false' ${{ github.run_id }} 'false' ${{ steps.jobs.outputs.html_url }} + python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'true' 'false' ${{ github.run_id }} 'false' 'false' ${{ steps.jobs.outputs.html_url }} continue-on-error: true - name: Check on failures diff --git a/.github/workflows/test-ivy-cron.yml b/.github/workflows/test-ivy-cron.yml index 8e9e62f3faf35..047076cc012b4 100644 --- a/.github/workflows/test-ivy-cron.yml +++ b/.github/workflows/test-ivy-cron.yml @@ -19,7 +19,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem @@ -37,8 +37,8 @@ jobs: run: | cd ivy pip3 install pymongo - python scripts/setup_tests/cron_tests.py ${{ github.run_number }} false - python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'false' ${{ steps.jobs.outputs.html_url }} + python scripts/setup_tests/cron_tests.py ${{ github.run_number }} false false + python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'false' 'false' ${{ steps.jobs.outputs.html_url }} continue-on-error: true - name: Check on failures diff --git a/.github/workflows/test-ivy-experimental-core.yml b/.github/workflows/test-ivy-experimental-core.yml index 8f8117978b2f5..e45ca220c1be2 100644 --- a/.github/workflows/test-ivy-experimental-core.yml +++ b/.github/workflows/test-ivy-experimental-core.yml @@ -29,7 +29,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem diff --git a/.github/workflows/test-ivy-experimental-nn.yml b/.github/workflows/test-ivy-experimental-nn.yml index ef5ebe1c294b1..d6d3e5e3ed5cc 100644 --- a/.github/workflows/test-ivy-experimental-nn.yml +++ b/.github/workflows/test-ivy-experimental-nn.yml @@ -27,7 +27,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem diff --git a/.github/workflows/test-ivy-nn.yml b/.github/workflows/test-ivy-nn.yml index 9f213e1e013bd..8e89adaf2ab2b 100644 --- a/.github/workflows/test-ivy-nn.yml +++ b/.github/workflows/test-ivy-nn.yml @@ -27,7 +27,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem diff --git a/.github/workflows/test-ivy-stateful.yml b/.github/workflows/test-ivy-stateful.yml index c4aeeb690f0b4..b8ea545d0ff24 100644 --- a/.github/workflows/test-ivy-stateful.yml +++ b/.github/workflows/test-ivy-stateful.yml @@ -28,7 +28,7 @@ jobs: - name: Install ivy and fetch binaries run: | cd ivy - pip3 install -e . + sudo pip3 install -e . mkdir .ivy touch .ivy/key.pem echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem diff --git a/.github/workflows/test-ivy-tracer-cron.yml b/.github/workflows/test-ivy-tracer-cron.yml new file mode 100644 index 0000000000000..0696b5c4aedf4 --- /dev/null +++ b/.github/workflows/test-ivy-tracer-cron.yml @@ -0,0 +1,46 @@ +name: test-ivy-tracer-cron +on: + workflow_dispatch: + schedule: + - cron: '15 * * * *' +permissions: + actions: read +jobs: + run-nightly-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout πŸ›ŽοΈIvy + uses: actions/checkout@v2 + with: + path: ivy + persist-credentials: false + submodules: "recursive" + + - name: Install ivy and fetch binaries + run: | + cd ivy + sudo pip3 install -e . + mkdir .ivy + touch .ivy/key.pem + echo -n ${{ secrets.USER_API_KEY }} > .ivy/key.pem + cd .. + + - name: Get Job URL + uses: Tiryoh/gha-jobid-action@v0 + id: jobs + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + job_name: ${{ github.job }} + + - name: Run Tests + id: tests + run: | + cd ivy + pip3 install pymongo + python scripts/setup_tests/cron_tests.py ${{ github.run_number }} false true + python scripts/run_tests/run_tests.py ${{ secrets.REDIS_CONNECTION_URL }} ${{ secrets.REDIS_PASSWORD }} ${{ secrets.MONGODB_PASSWORD }} 'false' 'false' ${{ github.run_id }} 'false' 'true' ${{ steps.jobs.outputs.html_url }} + continue-on-error: true + + - name: Check on failures + if: steps.tests.outcome != 'success' + run: exit 1 diff --git a/.gitignore b/.gitignore index fef9e99694c8c..9d225dc28b7ff 100644 --- a/.gitignore +++ b/.gitignore @@ -20,8 +20,8 @@ with_time_logs/ *.ods *.jpg *.jpeg -*.png *.gif +*.so .hypothesis .array_api_tests_k_flag* internal_automation_tools/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2e231afb1f7a7..7f554e7ec95f6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,8 +6,14 @@ repos: - id: trailing-whitespace - id: check-toml - id: end-of-file-fixer + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.2.2 + hooks: + # Run the linter. + - id: ruff + args: [ --fix ] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.12.0 + rev: 24.2.0 hooks: - id: black language_version: python3 @@ -20,24 +26,13 @@ repos: ivy_tests/test_ivy/(?!.*(?:__init__\.py|conftest\.py|helpers/.*|test_frontends/config/.*$)).* ) - repo: https://github.com/PyCQA/autoflake - rev: v2.2.1 + rev: v2.3.0 hooks: - id: autoflake - - repo: https://github.com/pycqa/flake8 - rev: 6.1.0 - hooks: - - id: flake8 - exclude: ^.*__init__.py$ - repo: https://github.com/PyCQA/docformatter rev: v1.7.5 hooks: - id: docformatter - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.8 - hooks: - # Run the linter. - - id: ruff - args: [ --fix ] - repo: https://github.com/unifyai/lint-hook rev: a72ffb17562d919311653d7f593cb537d1245c19 hooks: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 37cfa8e39bd59..1655ef485e509 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,4 +48,4 @@ Please, follow the next process when you work on your subtask: [![Video](https://img.youtube.com/vi/wBKTOGmwfbo/0.jpg)](https://www.youtube.com/embed/wBKTOGmwfbo) -For questions, please reach out on [discord](https://discord.gg/MDK979Ga) in the [todo list issues channel](https://discord.com/channels/799879767196958751/982728618469912627)! +For questions, please reach out on [discord](https://discord.gg/MDK979Ga) in the [todo list issues thread](https://discord.com/channels/799879767196958751/1189903501011202128)! diff --git a/MANIFEST.in b/MANIFEST.in index e0a363d10c6ec..8003b02e6779e 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,3 +4,4 @@ include ivy/compiler/*.so include ivy/compiler/*.py include binaries.json include available_configs.json +include wrappers.json diff --git a/available_configs.json b/available_configs.json index 21eb28357ddc5..a0697c63b5791 100644 --- a/available_configs.json +++ b/available_configs.json @@ -1,10 +1,14 @@ { "compiler": [ "cp38-cp38-manylinux_2_17_x86_64", + "cp38-cp38-win_amd64", "cp39-cp39-manylinux_2_17_x86_64", + "cp39-cp39-win_amd64", "cp310-cp310-manylinux_2_17_x86_64", - "cp311-cp311-manylinux_2_17_x86_64", + "cp310-cp310-win_amd64", "cp310-cp310-macosx_12_0_arm64", + "cp311-cp311-manylinux_2_17_x86_64", + "cp311-cp311-win_amd64", "cp311-cp311-macosx_12_0_arm64" ] } diff --git a/binaries.json b/binaries.json index 8f31596c7a3a7..86406c4fc4a82 100644 --- a/binaries.json +++ b/binaries.json @@ -1,73 +1,73 @@ { "ivy": { "compiler": [ - "_compiler.so", + "_compiler", { "utils": [ - "CC.so", - "CD.so", - "CI.so", - "CL.so", - "CM.so", - "CV.so", - "CX.so", - "C.so", - - "DC.so", - "DD.so", - "DI.so", - "DL.so", - "DM.so", - "DV.so", - "DX.so", - "D.so", - - "IC.so", - "ID.so", - "II.so", - "IL.so", - "IM.so", - "IV.so", - "IX.so", - "I.so", - - "LC.so", - "LD.so", - "LI.so", - "LL.so", - "LM.so", - "LV.so", - "LX.so", - "L.so", - - "MC.so", - "MD.so", - "MI.so", - "ML.so", - "MM.so", - "MV.so", - "MX.so", - "M.so", - - "VC.so", - "VD.so", - "VI.so", - "VL.so", - "VM.so", - "VV.so", - "VX.so", - "V.so", - - "XC.so", - "XD.so", - "XI.so", - "XL.so", - "XM.so", - "XV.so", - "XX.so", - "X.so", - - "IIC.so" + "C", + "CC", + "CD", + "CI", + "CL", + "CM", + "CV", + "CX", + "D", + "DC", + "DD", + "DI", + "DL", + "DM", + "DV", + "DX", + "I", + "IC", + "ID", + "II", + "IIC", + "IID", + "III", + "IIL", + "IIM", + "IIV", + "IIX", + "IL", + "IM", + "IV", + "IVI", + "IX", + "L", + "LC", + "LD", + "LI", + "LL", + "LM", + "LV", + "LX", + "M", + "MC", + "MD", + "MI", + "ML", + "MM", + "MV", + "MX", + "V", + "VC", + "VD", + "VI", + "VL", + "VM", + "VV", + "VX", + "X", + "XC", + "XD", + "XI", + "XL", + "XM", + "XV", + "XX" ] } ] diff --git a/docker/gpu_framework_directory.py b/docker/gpu_framework_directory.py index d5ecc15c70ecc..3dee4b7bf7750 100644 --- a/docker/gpu_framework_directory.py +++ b/docker/gpu_framework_directory.py @@ -43,6 +43,13 @@ def install_pkg(path, pkg, base="fw/"): " --no-cache-dir", shell=True, ) + subprocess.run( + f"yes |pip3 install --upgrade torchvision --index-url" + f" https://download.pytorch.org/whl/cu121 --target" + f" {path} --default-timeout=100 --extra-index-url" + " --no-cache-dir", + shell=True, + ) elif pkg.split("==")[0] if "==" in pkg else pkg == "jax": subprocess.run( f"yes |pip install --upgrade --target {path} 'jax[cuda12_pip]' -f" @@ -53,9 +60,8 @@ def install_pkg(path, pkg, base="fw/"): elif pkg.split("==")[0] if "==" in pkg else pkg == "paddle": subprocess.run( "yes |pip install " - f" paddlepaddle-gpu=={get_latest_package_version('paddlepaddle')}.post120" - f" --target {path} -f" - " https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html " + f" paddlepaddle-gpu=={get_latest_package_version('paddlepaddle')}" + f" --target {path} -f https://mirror.baidu.com/pypi/simple " " --no-cache-dir", shell=True, ) diff --git a/docker/requirement_mappings_gpu.json b/docker/requirement_mappings_gpu.json index a851f62b1ce3f..ade51df83cc09 100644 --- a/docker/requirement_mappings_gpu.json +++ b/docker/requirement_mappings_gpu.json @@ -2,6 +2,6 @@ "jax": ["dm-haiku", "flax"], "numpy": ["numpy"], "mxnet": ["mxnet"], - "torch": ["torch-scatter", "torchvision"], + "torch": ["torchvision", "torch-scatter"], "tensorflow": ["tensorflow-probability"] } diff --git a/docs/demos b/docs/demos index 98870b7b92546..104f88a7be642 160000 --- a/docs/demos +++ b/docs/demos @@ -1 +1 @@ -Subproject commit 98870b7b92546a9e1dc9b45a0042771bd3c7b505 +Subproject commit 104f88a7be64234ec58950deed8142bc7748d9da diff --git a/docs/index.rst b/docs/index.rst index e88f08969b560..02a4eefdf723a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -46,6 +46,7 @@ overview/design.rst overview/contributing.rst + overview/volunteer_ranks.rst overview/deep_dive.rst overview/glossary.rst overview/faq.rst diff --git a/docs/overview/contributing.rst b/docs/overview/contributing.rst index 6e988bba87b52..53a98e9417dc0 100644 --- a/docs/overview/contributing.rst +++ b/docs/overview/contributing.rst @@ -21,19 +21,25 @@ The contributor guide is split into the sections below, it's best to go from sta | (b) `The Basics `_ | Managing your fork πŸ‡Ύ, creating issues β­•, and creating pull-requests ⬆️ | -| (c) `Building the Docs `_ +| (c) `Open Tasks `_ +| See where you can help us out! πŸ™‹ +| +| (d) `Contributor Rewards `_ +| Check out our contributor badges and achievements! πŸ… +| +| (e) `Contributor Program `_ +| How to climb up the ranks in our Contributor program πŸ§— +| +| (f) `Building the Docs `_ | How to build the documentation locally πŸ—οΈ | -| (d) `Deep Dive `_ +| (g) `Deep Dive `_ | Take a deep dive into the codebase 🀿 | -| (e) `Open Tasks `_ -| See where you can help us out! πŸ™‹ -| -| (f) `Helpful Resources `_ +| (h) `Helpful Resources `_ | Resources you would find useful when learning Ivy πŸ“– | -| (g) `Error Handling `_ +| (i) `Error Handling `_ | Common errors you will be facing contributing to Ivy ❌ .. toctree:: @@ -46,6 +52,8 @@ The contributor guide is split into the sections below, it's best to go from sta contributing/building_the_docs.rst Deep Dive contributing/open_tasks.rst + contributing/volunteer_program.rst + contributing/contributor_rewards.rst contributing/helpful_resources.rst contributing/error_handling.rst diff --git a/docs/overview/contributing/contributor_rewards.rst b/docs/overview/contributing/contributor_rewards.rst new file mode 100644 index 0000000000000..07dd0f6b6db4b --- /dev/null +++ b/docs/overview/contributing/contributor_rewards.rst @@ -0,0 +1,82 @@ +Contributor Rewards +=================== + +We award a range of badges, each designed to formally recognize the specific achievements of our contributors in various key areas of ivy's development. + +Badges +~~~~~~~ + +**Debugging Dynamos** - These badges are earned by creating useful issues. If you find a problem that isn't listed as an open task, report it by creating a new issue. Make sure to describe the problem thoroughly. If your issue is confirmed as useful and marked as a "Useful Issue" by our team, you'll receive the badge as recognition for your valuable contribution to improving our codebase. + +**Merging Master** - These badges are formal recognitions for contributors whose pull requests consistently meet our standards of quality and are successfully merged into the main codebase. + +**Merging Wizard** - These exclusive badges are awarded to contributors who successfully get *priority* pull requests merged. This recognition is for handling complex, high-priority tasks that have a substantial impact on the project's progress and success. Priority pull requests are those that close `"Priority Open" issues `_ found within each framework. + +**Ivy Inspectors** - These badges are given in acknowledgment of the essential role played by those who review our pull requests. It honours the commitment to quality and diligence in ensuring that each code merge aligns with our standards. + +Each badge comes in four distinct tiers – Initial, Bronze, Silver, and Gold, mirroring your growing expertise and commitment in these areas. + +Badge Tiers +~~~~~~~~~~~~ + +.. list-table:: + :widths: 50 25 30 30 30 + :header-rows: 1 + + * - GitHub Badge + - Initial (1 Task) + - Bronze (5 Tasks) + - Silver (15 Tasks) + - Gold (30 Tasks) + * - Debugging Dynamos + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_01-00.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_01-02.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_01-03.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_01-04.png + :width: 110 + :alt: Alternative text + * - Merging Master + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_04-00.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_04-02.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_04-03.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_04-04.png + :width: 110 + :alt: Alternative text + * - Merging Wizard + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_05-00.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_05-02.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_05-03.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_05-04.png + :width: 110 + :alt: Alternative text + * - Ivy Inspectors + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_06-00.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_06-02.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_06-03.png + :width: 110 + :alt: Alternative text + - .. image:: https://raw.githubusercontent.com/unifyai/ivy/main/.vaunt/badges/badge_06-04.png + :width: 110 + :alt: Alternative text diff --git a/docs/overview/contributing/error_handling.rst b/docs/overview/contributing/error_handling.rst index 2ddfa6be2c4ca..75f7e300e5432 100644 --- a/docs/overview/contributing/error_handling.rst +++ b/docs/overview/contributing/error_handling.rst @@ -2,11 +2,11 @@ Error Handling ============== .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`pycharm channel`: https://discord.com/channels/799879767196958751/942114831039856730 -.. _`docker channel`: https://discord.com/channels/799879767196958751/942114744691740772 -.. _`pre-commit channel`: https://discord.com/channels/799879767196958751/982725464110034944 -.. _`pip packages channel`: https://discord.com/channels/799879767196958751/942114789642080317 -.. _`ivy tests channel`: https://discord.com/channels/799879767196958751/982738436383445073 +.. _`pycharm thread`: https://discord.com/channels/799879767196958751/1186628916522262629 +.. _`docker thread`: https://discord.com/channels/799879767196958751/1186629067966009424 +.. _`pre-commit thread`: https://discord.com/channels/799879767196958751/1186629635694399539 +.. _`pip packages thread`: https://discord.com/channels/799879767196958751/1186629837515935765 +.. _`ivy tests thread`: https://discord.com/channels/799879767196958751/1189907526226034698 This section, "Error Handling" aims to assist you in navigating through some common errors you might encounter while working with the Ivy's Functional API. We'll go through some common errors which you might encounter while working as a contributor or a developer. @@ -150,4 +150,4 @@ This section is specifically targeted towards dealing with the Ivy Functional AP This should have hopefully given you an understanding of how to deal with common errors while working with the the functional API. -If you have any questions, please feel free to reach out on `discord`_ in the `ivy tests channel`_, `pycharm channel`_, `docker channel`_, `pre-commit channel`_, `pip packages channel`_ depending on the question! +If you have any questions, please feel free to reach out on `discord`_ in the `ivy tests thread`_, `pycharm thread`_, `docker thread`_, `pre-commit thread`_, `pip packages thread`_ depending on the question! diff --git a/docs/overview/contributing/open_tasks.rst b/docs/overview/contributing/open_tasks.rst index de80e03222b7c..4420295b0d893 100644 --- a/docs/overview/contributing/open_tasks.rst +++ b/docs/overview/contributing/open_tasks.rst @@ -3,7 +3,7 @@ Open Tasks .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`open tasks channel`: https://discord.com/channels/799879767196958751/982728618469912627 +.. _`open tasks thread`: https://discord.com/channels/799879767196958751/1189903501011202128 .. _`issue description`: https://github.com/unifyai/ivy/issues/1526 .. _`reference API`: https://numpy.org/doc/stable/reference/routines.linalg.html .. _`imports`: https://github.com/unifyai/ivy/blob/38dbb607334cb32eb513630c4496ad0024f80e1c/ivy/functional/frontends/numpy/__init__.py#L27 @@ -25,29 +25,50 @@ The tasks currently open are: #. Frontend APIs #. Ivy Experimental API -We try to explain these tasks as clearly as possible, but in cases where things are not clear, then please feel free to reach out on `discord`_ in the `open tasks channel`_! +We try to explain these tasks as clearly as possible, but in cases where things are not clear, then please feel free to reach out on `discord`_ in the `open tasks thread`_! Please always use the latest commit on GitHub when working on any of these tasks, **DO NOT** develop your code using the latest PyPI release of :code:`ivy`. Fixing Failing Tests -------------------- -In the Ivy repository, we've identified a range of functions and tests that currently fall short of our quality standards. The root of these issues is not always clear-cut. In some instances, the problem may lie within the functions themselves, while in others, it could be the tests, which were crafted by various contributors, that are at fault. This situation presents a unique opportunity for community involvement. We are actively inviting contributions from our community to help tackle these challenges. +We've identified a range of functions and tests that fail the tests. +The root of these issues is not always straightforward. +In some instances, the problem may lie within the function implementations, while in others, it could be the way the tests were added previously. +Certain failing tests are more urgent to fix than others, as mentioned in the sub-section below. +We encourage contributions from the community to help tackle these challenges. How to Contribute ~~~~~~~~~~~~~~~~~ **Identifying Issues** -To get started, visit our issues page: `Failing Tests `_. Here, you will find a list of open issues labeled as "Failing Test" and "ToDo". These issues are categorised under various frameworks supported by our repository. We encourage you to select a framework you're comfortable with or interested in contributing to. +To get started, visit our issues page: `Failing Tests `_. +Here, you will find a list of open issues labeled as "Failing Test" and "ToDo". +These issues are categorised under various frameworks supported by our repository. +We encourage you to select a framework you're comfortable with or interested in contributing to. **Selecting a Test** -Within each framework, tests are classified as either "Priority Open" or "Other Open." While we prioritize fixing the "Priority Open" tests, contributions towards any test, including those labeled "Other Open," are highly valuable. Each test issue is linked directly to the specific failing workflow. This linkage provides you with immediate access to the details of what exactly is failing and the context around it. +Within each framework, tests are classified as either "Priority Open" or "Other Open." +While we prioritize fixing the "Priority Open" tests, contributions towards any test, including those labeled "Other Open," are highly valuable. +Each test issue is linked directly to the specific failing workflow. +This linkage provides you with immediate access to the details of what exactly is failing and the context around it. **Making Your Contribution** -After selecting a test to work on, please fork the repository and create a new branch for your fix. Ensure that your solution addresses the issue effectively and doesn't introduce new errors. Once you're confident in your fix, submit a pull request to the main repository. Our team will review your contribution, provide feedback if necessary, and then merge your changes once they meet our standards. +After selecting a test to work on, please make the necessary changes and create a PR referring to `the basics `_. +Ensure that your solution addresses the issue effectively and doesn't introduce new errors. +Once you're confident in your fix, submit a pull request to the main repository. +Our team will review your contribution, provide feedback if necessary, and then merge your changes once we're good to go. + +**Video** + +.. raw:: html + + Frontend APIs ------------- @@ -338,4 +359,4 @@ Creating an Issue on Ivy's GitHub using a Template This should have hopefully given you a good understanding of the basics for contributing. -If you have any questions, please feel free to reach out on `discord`_ in the `open tasks channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `open tasks thread`_! diff --git a/docs/overview/contributing/setting_up.rst b/docs/overview/contributing/setting_up.rst index 0b6c0535dbc93..fa329b7358713 100644 --- a/docs/overview/contributing/setting_up.rst +++ b/docs/overview/contributing/setting_up.rst @@ -3,10 +3,10 @@ Setting Up .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`pycharm channel`: https://discord.com/channels/799879767196958751/942114831039856730 -.. _`docker channel`: https://discord.com/channels/799879767196958751/942114744691740772 -.. _`pre-commit channel`: https://discord.com/channels/799879767196958751/982725464110034944 -.. _`pip packages channel`: https://discord.com/channels/799879767196958751/942114789642080317 +.. _`pycharm thread`: https://discord.com/channels/799879767196958751/1186628916522262629 +.. _`docker thread`: https://discord.com/channels/799879767196958751/1186629067966009424 +.. _`pre-commit thread`: https://discord.com/channels/799879767196958751/1186629635694399539 +.. _`pip packages thread`: https://discord.com/channels/799879767196958751/1186629837515935765 .. _`miniconda`: https://docs.conda.io/en/latest/miniconda.html .. _`venv`: https://docs.python.org/3/library/venv.html .. _`ivy/scripts`: https://github.com/unifyai/ivy/tree/bcddc79978afe447958dfa3ea660716845c85846/scripts @@ -66,7 +66,7 @@ In order to install and properly set up pre-commit, these steps should be follow That's it! Now when you make a commit, the pre-commit hooks will all be run correctly, as explained above. -For questions, please reach out on `discord`_ in the `pre-commit channel`_! +For questions, please reach out on `discord`_ in the `pre-commit thread`_! PyCharm @@ -83,7 +83,7 @@ Many people seem to miss this option, so we thought we would add an explicit rem #. To continue using PyCharm Professional, you can use the trial version making a jetbrains account but that would be only valid for 1 month. #. After the trial expires you have to buy the paid version of PyCharm Professional. -For questions, please reach out on `discord`_ in the `pycharm channel`_! +For questions, please reach out on `discord`_ in the `pycharm thread`_! Virtual environments - No Docker -------------------------------- @@ -231,8 +231,8 @@ This is a builtin package and doesn't require explicit installation. .. code-block:: none - wget http://nz2.archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb - sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb + wget http://nz2.archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb + sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb PS: If the link gets expired at some point in the future, check http://nz2.archive.ubuntu.com/ubuntu/pool/main/o/openssl/?C=M;O=D for a valid one. @@ -445,7 +445,7 @@ This is a common error which you might face. If you are not successfully able to sudo chmod a+rwx /var/run/docker.pid -For questions, please reach out on `discord`_ in the `docker channel`_! +For questions, please reach out on `discord`_ in the `docker thread`_! **Video** @@ -560,7 +560,7 @@ Now, if Hypothesis detects an error in the code it will return more detailed inf .. image:: https://raw.githubusercontent.com/unifyai/unifyai.github.io/main/img/externally_linked/contributing/setting_up/more_detailed_hypothesis_logs/detailed_hypothesis_example.png?raw=true :width: 420 -For questions, please reach out on `discord`_ in the `docker channel`_! +For questions, please reach out on `discord`_ in the `docker thread`_! **"Empty Suite" error fix:** @@ -650,7 +650,7 @@ the steps explained below will help you in setting up a less resource-intensive pip install git+https://github.com/unifyai/ivy.git -#. If you want to set up a local repository, you can do so by following :ref:`this guide ` +#. Or else, if you want to set up a local repository, you can do so by following :ref:`this guide ` as explained above and install the required development dependencies by running: .. code-block:: none @@ -660,6 +660,7 @@ the steps explained below will help you in setting up a less resource-intensive .. code-block:: none pip install -r requirements/requirements.txt + pip install -r requirements/optional.txt #. Once done, you can now open VSCode right from your terminal and get started with your development by just running: @@ -893,4 +894,4 @@ Running a :code:`pip install -e .` is sufficient to download the binaries if the This should have hopefully given you a good understanding of how to get things properly set up. -If you have any questions, please feel free to reach out on `discord`_ in the `pycharm channel`_, `docker channel`_, `pre-commit channel`_, `pip packages channel`_ depending on the question! +If you have any questions, please feel free to reach out on `discord`_ in the `pycharm thread`_, `docker thread`_, `pre-commit thread`_, `pip packages thread`_ depending on the question! diff --git a/docs/overview/contributing/the_basics.rst b/docs/overview/contributing/the_basics.rst index 1c2f3966ce8c9..7f2add42f6967 100644 --- a/docs/overview/contributing/the_basics.rst +++ b/docs/overview/contributing/the_basics.rst @@ -3,9 +3,9 @@ The Basics .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`todo list issues channel`: https://discord.com/channels/799879767196958751/982728618469912627 +.. _`todo list issues thread`: https://discord.com/channels/799879767196958751/1189903501011202128 .. _`Atlassian tutorial`: https://www.atlassian.com/git/tutorials/saving-changes/git-stash -.. _`fork management channel`: https://discord.com/channels/799879767196958751/982728689408167956 +.. _`fork management thread`: https://discord.com/channels/799879767196958751/1189903708465672272 .. _`pull requests channel`: https://discord.com/channels/799879767196958751/982728733859414056 .. _`PyCharm blog`: https://www.jetbrains.com/help/pycharm/finding-and-replacing-text-in-file.html .. _`Debugging`: https://www.jetbrains.com/help/pycharm/debugging-code.html @@ -112,7 +112,7 @@ For example, a sequence of comments like this :code:`- [ ] #Issue_number` will r | -For questions, please reach out on `discord`_ in the `todo list issues channel`_! +For questions, please reach out on `discord`_ in the `todo list issues thread`_! Managing Your Fork ------------------ @@ -153,7 +153,7 @@ For a comprehensive explanation of git stashing, check out this `Atlassian tutor | -For questions, please reach out on `discord`_ in the `fork management channel`_! +For questions, please reach out on `discord`_ in the `fork management thread`_! Who To Ask ---------- @@ -248,7 +248,7 @@ The code review process is explained in more detail in the following video. | -For questions, please reach out on `discord`_ in the `pull requests channel`_! +For questions, please reach out on `discord`_ in the `pull requests thread`_! Small Commits Often ------------------- @@ -294,7 +294,7 @@ As a final note, a beautiful commit history is not something we particularly car We're much more concerned that the code itself is good, that things are updated as quickly as possible, and that all developers are able to work efficiently. If a mistake is committed into the history, it's generally not too difficult to simply undo this in future commits, so don't stress about this too much πŸ™‚ -For questions, please reach out on the on `discord`_ in the `commit frequency channel`_! +For questions, please reach out on the on `discord`_ in the `commit frequency thread`_! Interactive Ivy Docker Container -------------------------------- @@ -598,4 +598,4 @@ with PyCharm This should have hopefully given you a good understanding of the basics for contributing. -If you have any questions, please feel free to reach out on `discord`_ in the `todo list issues channel`_, `fork management channel`_, `pull requests channel`_, depending on the question! +If you have any questions, please feel free to reach out on `discord`_ in the `todo list issues thread`_, `fork management thread`_, `pull requests thread`_, depending on the question! diff --git a/docs/overview/contributing/volunteer_program.rst b/docs/overview/contributing/volunteer_program.rst new file mode 100644 index 0000000000000..23a901a45146c --- /dev/null +++ b/docs/overview/contributing/volunteer_program.rst @@ -0,0 +1,43 @@ +Contributor Program +================= + +The goal of the Contributor program is to facilitate contributors in the community that would like to work more closely +with our team. +Embark on a rewarding journey with Unify by `signing up `_ as a Contributor. +Let's innovate together! + +We've created a promotion workflow to help you advance through the different tiers of contribution, +from Contributor to Core Contributor, Rising Contributor, and finally, Top Contributor. + +Our promotion structure is based on our badge system. +Check out `Contributor Rewards `_ for more information about them! + +Contributor +----------- +Start as a Contributor by earning any of the Initial Badges. +It's straightforward β€” complete one of the open tasks listed and you're in! +This first step opens the door for you to become an integral part of our community. + +Core Contributor +---------------- +Get elevated to Core Contributor status by earning a Bronze Badge. +As a Core Contributor, you're recognized not just for your skills but also for your growing commitment to our mission. +You'll have the opportunity to engage more deeply with our projects and play an important role in shaping the future of our initiatives. +This tier is a testament to your dedication and a stepping stone to even greater achievements within our community. +As a token of appreciation, you'll be eligible for a $25 welcome gift. + +Rising Contributor +------------------ +Ascend to the Rising Contributor level by acquiring a Silver Badge. +This tier will allow you to be more deeply involved with our core group. +You'll join our GitHub team, enabling you to directly commit changes to :code:`main`, manage PRs made by others in the community, etc. +You'll also be invited to all our internal meetings to be able to follow along with everything happening in the team. +As a Rising Contributor, you're encouraged to tackle complex tasks, pushing your skills to new heights. + +Top Contributor +--------------- +Achieve a Gold Badge to reach the peak of our program as a Top Contributor. +This tier is for those who demonstrate exceptional dedication and expertise. +You'll gain the privilege of engaging with bounty-holding internal tasks and join our Bounty Program, +where completing top-priority issues can earn you cash rewards. +Upon reaching this level, we will be delighted to acknowledge your contributions with a special token of appreciation. diff --git a/docs/overview/deep_dive/array_api_tests.rst b/docs/overview/deep_dive/array_api_tests.rst index 3a6aa29a8d67b..383c3e30098a0 100644 --- a/docs/overview/deep_dive/array_api_tests.rst +++ b/docs/overview/deep_dive/array_api_tests.rst @@ -7,7 +7,7 @@ Array API Tests .. _`for each backend`: https://github.com/unifyai/ivy/tree/20d07d7887766bb0d1707afdabe6e88df55f27a5/.github/workflows .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`array api tests channel`: https://discord.com/channels/799879767196958751/982738404611592256 +.. _`array api tests thread`: https://discord.com/channels/799879767196958751/1189907361494741073 .. _`scripts/shell/test_array_api.sh`: https://github.com/unifyai/ivy/blob/bcddc79978afe447958dfa3ea660716845c85846/scripts/shell/test_array_api.sh .. _`array-api test repository`: https://github.com/data-apis/array-api/tree/main .. _`issue`: https://github.com/numpy/numpy/issues/21213 @@ -204,7 +204,7 @@ The fact that the skip instruction itself contains the exact input conditions th This should have hopefully given you a good understanding of how the Array API test suite is used for testing Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `array api tests channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `array api tests thread`_! **Video** diff --git a/docs/overview/deep_dive/arrays.rst b/docs/overview/deep_dive/arrays.rst index 02dccc5352c56..83ee85f9d9026 100644 --- a/docs/overview/deep_dive/arrays.rst +++ b/docs/overview/deep_dive/arrays.rst @@ -21,7 +21,7 @@ Arrays .. _`__truediv__`: https://github.com/unifyai/ivy/blob/e4d9247266f5d99faad59543923bb24b88a968d9/ivy/array/__init__.py#L319 .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`arrays channel`: https://discord.com/channels/799879767196958751/933380487353872454 +.. _`arrays thread`: https://discord.com/channels/799879767196958751/1189905906905919609 .. _`wrapped logic`: https://github.com/unifyai/ivy/blob/6a729004c5e0db966412b00aa2fce174482da7dd/ivy/func_wrapper.py#L95 .. _`NumPy's`: https://numpy.org/doc/stable/user/basics.dispatch.html#basics-dispatch .. _`PyTorch's`: https://pytorch.org/docs/stable/notes/extending.html#extending-torch @@ -176,7 +176,7 @@ It is relevant to mention again that any function not stored inside the dict :co This should have hopefully given you a good feel for the different types of arrays, and how these are handled in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `arrays channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `arrays thread`_! **Video** diff --git a/docs/overview/deep_dive/backend_setting.rst b/docs/overview/deep_dive/backend_setting.rst index 6a7565ec335f0..18e89197b684c 100644 --- a/docs/overview/deep_dive/backend_setting.rst +++ b/docs/overview/deep_dive/backend_setting.rst @@ -8,7 +8,7 @@ Backend Setting .. _`wrap the functions`: https://github.com/unifyai/ivy/blob/1eb841cdf595e2bb269fce084bd50fb79ce01a69/ivy/backend_handler.py#L204 .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`backend setting channel`: https://discord.com/channels/799879767196958751/982737886963187772 +.. _`backend setting thread`: https://discord.com/channels/799879767196958751/1189905734645850254 The backend framework can either be set by calling :code:`ivy.set_backend(backend_name)` or it can inferred from the arguments. For the latter, a global variable `implicit_backend`_ is located in the file which is initialized as numpy, and is always used to infer the backend in cases where: (a) no backend has been set using the :code:`set_backend` function and (b) the backend cannot be inferred from the inputs. @@ -129,7 +129,7 @@ If the user's system doesn't have the backend framework installed, we default to This should have hopefully given you a good feel for how the backend framework is set. -If you have any questions, please feel free to reach out on `discord`_ in the `backend setting channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `backend setting thread`_! **Video** diff --git a/docs/overview/deep_dive/containers.rst b/docs/overview/deep_dive/containers.rst index bfcc94e048bbe..5ffa466429872 100644 --- a/docs/overview/deep_dive/containers.rst +++ b/docs/overview/deep_dive/containers.rst @@ -31,7 +31,7 @@ Containers .. _`__truediv__`: https://github.com/unifyai/ivy/blob/b725ed10bca15f6f10a0e5154af10231ca842da2/ivy/container/container.py#L399 .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`containers channel`: https://discord.com/channels/799879767196958751/982738042886422598 +.. _`containers thread`: https://discord.com/channels/799879767196958751/1189906066549506048 The `ivy.Container`_ inherits from `dict`_, and is useful for storing nested data. @@ -334,7 +334,7 @@ This is for three reasons, (a) the key chain :code:`g` is not shared by any cont This should have hopefully given you a good feel for containers, and how these are handled in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `containers channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `containers thread`_! **Video** diff --git a/docs/overview/deep_dive/continuous_integration.rst b/docs/overview/deep_dive/continuous_integration.rst index 9653ddd175da9..09c63c4fd4f5b 100644 --- a/docs/overview/deep_dive/continuous_integration.rst +++ b/docs/overview/deep_dive/continuous_integration.rst @@ -1,7 +1,7 @@ Continuous Integration ====================== -.. _`continuous integration channel`: https://discord.com/channels/799879767196958751/1028268051776413759 +.. _`continuous integration channel`: https://discord.com/channels/799879767196958751/1189908611208597544 .. _`discord`: https://discord.gg/sXyFF8tDtm We follow the practice of Continuous Integration (CI), in order to regularly build and test code at Ivy. @@ -397,7 +397,7 @@ You can filter tests by selecting choices from the various dropdowns. The link c This should have hopefully given you a good feel for how Continuous Integration works in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `continuous integration channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `continuous integration thread`_! **Video** diff --git a/docs/overview/deep_dive/data_types.rst b/docs/overview/deep_dive/data_types.rst index f3cb6defae24b..bbf15ebd1839e 100644 --- a/docs/overview/deep_dive/data_types.rst +++ b/docs/overview/deep_dive/data_types.rst @@ -24,7 +24,7 @@ Data Types .. _`ivy.set_default_dtype`: https://github.com/unifyai/ivy/blob/8482eb3fcadd0721f339a1a55c3f3b9f5c86d8ba/ivy/functional/ivy/data_type.py#L1555 .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`data types channel`: https://discord.com/channels/799879767196958751/982738078445760532 +.. _`data type thread`: https://discord.com/channels/799879767196958751/1190234670806351892 The data types supported by Ivy are as follows: @@ -423,7 +423,7 @@ set of dtypes is not supported by a certain device. .. code-block:: python - @with_unsupported_device_and_dtypes({"2.5.2 and below": {"cpu": ("int8", "int16", "uint8")}}, backend_version) + @with_unsupported_device_and_dtypes({"2.6.0 and below": {"cpu": ("int8", "int16", "uint8")}}, backend_version) def gcd( x1: Union[paddle.Tensor, int, list, tuple], x2: Union[paddle.Tensor, float, list, tuple], @@ -739,7 +739,7 @@ As with all superset design decisions, this behavior makes it much easier to sup This should have hopefully given you a good feel for data types, and how these are handled in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `data types channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `data types thread`_! **Video** diff --git a/docs/overview/deep_dive/devices.rst b/docs/overview/deep_dive/devices.rst index 2b68f1bbabec1..33636fdee3b6f 100644 --- a/docs/overview/deep_dive/devices.rst +++ b/docs/overview/deep_dive/devices.rst @@ -25,7 +25,7 @@ Devices .. _`ivy.unset_default_device()`: https://github.com/unifyai/ivy/blob/2f90ce7b6a4c8ddb7227348d58363cd2a3968602/ivy/functional/ivy/device.py#L869 .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`devices channel`: https://discord.com/channels/799879767196958751/982738108166602752 +.. _`devices thread`: https://discord.com/channels/799879767196958751/1189906353653817354 The devices currently supported by Ivy are as follows: @@ -270,7 +270,7 @@ There are some functions(mostly creation function) which accept a :code:`device` This should have hopefully given you a good feel for devices, and how these are handled in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `devices channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `devices thread`_! **Video** diff --git a/docs/overview/deep_dive/docstring_examples.rst b/docs/overview/deep_dive/docstring_examples.rst index 1debbc8d67963..5ca12840e0534 100644 --- a/docs/overview/deep_dive/docstring_examples.rst +++ b/docs/overview/deep_dive/docstring_examples.rst @@ -3,7 +3,7 @@ Docstring Examples .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`docstring examples channel`: https://discord.com/channels/799879767196958751/982738352103129098 +.. _`docstring examples thread`: https://discord.com/channels/799879767196958751/1189906990307233822 After writing the general docstrings, the final step is to add helpful examples to the docstrings. @@ -747,7 +747,7 @@ Passing docstring tests is a necessary but not sufficient condition for the comp These three examples should give you a good understanding of what is required when adding docstring examples. -If you have any questions, please feel free to reach out on `discord`_ in the `docstring examples channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `docstring examples thread`_! **Video** diff --git a/docs/overview/deep_dive/docstrings.rst b/docs/overview/deep_dive/docstrings.rst index ead0f7a5b19c4..5e83f4face088 100644 --- a/docs/overview/deep_dive/docstrings.rst +++ b/docs/overview/deep_dive/docstrings.rst @@ -5,7 +5,7 @@ Docstrings .. _`spec/API_specification/array_api`: https://github.com/data-apis/array-api/blob/main .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`docstrings channel`: https://discord.com/channels/799879767196958751/982738313897197600 +.. _`docstrings thread`: https://discord.com/channels/799879767196958751/1189906836426596412 All functions in the Ivy API at :mod:`ivy/functional/ivy/category_name.py` should have full and thorough docstrings. @@ -193,7 +193,7 @@ Therefore, with the exception of the :class:`ivy.Array` and :class:`ivy.Containe These examples should hopefully give you a good understanding of what is required when adding docstings. -If you have any questions, please feel free to reach out on `discord`_ in the `docstrings channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `docstrings thread`_! **Video** diff --git a/docs/overview/deep_dive/exception_handling.rst b/docs/overview/deep_dive/exception_handling.rst index 55313c46b00a4..2ad306b06f03a 100644 --- a/docs/overview/deep_dive/exception_handling.rst +++ b/docs/overview/deep_dive/exception_handling.rst @@ -1,7 +1,7 @@ Exception Handling ================== -.. _`exception handling channel`: https://discord.com/channels/799879767196958751/1028267924043092068 +.. _`exception handling thread`: https://discord.com/channels/799879767196958751/1189908450570928149 .. _`discord`: https://discord.gg/sXyFF8tDtm As Ivy is unifying multiple backends, various issues are seen during exception handling: @@ -545,7 +545,7 @@ Instead of coding a conditional block and raising an exception if the conditions This should have hopefully given you a good feel for how function wrapping is applied to functions in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `exception handling channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `exception handling thread`_! **Video** diff --git a/docs/overview/deep_dive/fix_failing_tests.rst b/docs/overview/deep_dive/fix_failing_tests.rst index c2dc97832636c..f86dfc62cc99e 100644 --- a/docs/overview/deep_dive/fix_failing_tests.rst +++ b/docs/overview/deep_dive/fix_failing_tests.rst @@ -5,17 +5,17 @@ Fix Failing Tests: .. _`issues`: https://github.com/unifyai/ivy/issues?q=is%3Aopen+is%3Aissue+label%3A%22Failing+Test%22 .. _`issue`: https://github.com/unifyai/ivy/issues/25849 .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`docker channel`: https://discord.com/channels/799879767196958751/942114744691740772 +.. _`docker thread`: https://discord.com/channels/799879767196958751/1186629067966009424 .. _`miniconda`: https://docs.conda.io/en/latest/miniconda.html .. _`venv`: https://docs.python.org/3/library/venv.html .. _`ivy/scripts/shell`: https://github.com/unifyai/ivy/tree/f71a414417646e1dfecb5de27fb555f80333932c/scripts/shell .. _`platform compatibility tags`: https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/ .. _`logging level`: https://docs.python.org/3/library/logging.html#logging.Logger.setLevel -.. _`pycharm channel`: https://discord.com/channels/799879767196958751/942114831039856730 -.. _`pre-commit channel`: https://discord.com/channels/799879767196958751/982725464110034944 -.. _`pip packages channel`: https://discord.com/channels/799879767196958751/942114789642080317 -.. _`ivy tests channel`: https://discord.com/channels/799879767196958751/982738436383445073 -.. _`ivy frontend tests channel`: https://discord.com/channels/799879767196958751/1028267758028337193 +.. _`pycharm thread`: https://discord.com/channels/799879767196958751/1186628916522262629 +.. _`pre-commit thread`: https://discord.com/channels/799879767196958751/1186629635694399539 +.. _`pip packages thread`: https://discord.com/channels/799879767196958751/1186629837515935765 +.. _`ivy tests thread`: https://discord.com/channels/799879767196958751/1189907526226034698 +.. _`ivy frontend tests thread`: https://discord.com/channels/799879767196958751/1190246804940402738 We're really happy you'd like to learn how to contribute towards Ivy πŸ™‚ @@ -307,4 +307,4 @@ This section aims to assist you in navigating through some common errors you mig Where to ask for Help ********************* -The best place to ask for help is our `discord`_ server in the relevant channels. For instance, lets say you're facing an issue with :code:`test_jax_transpose` function, in this case you should post your query in the `ivy frontend tests channel`_. +The best place to ask for help is our `discord`_ server in the relevant channels. For instance, lets say you're facing an issue with :code:`test_jax_transpose` function, in this case you should post your query in the `ivy frontend tests thread`_. diff --git a/docs/overview/deep_dive/formatting.rst b/docs/overview/deep_dive/formatting.rst index f970f8e0c24d2..9cb5d4b15cbf4 100644 --- a/docs/overview/deep_dive/formatting.rst +++ b/docs/overview/deep_dive/formatting.rst @@ -3,7 +3,7 @@ Formatting .. _`flake8`: https://flake8.pycqa.org/en/latest/index.html .. _`black`: https://black.readthedocs.io/en/stable/index.html -.. _`formatting channel`: https://discord.com/channels/799879767196958751/1028266706436624456 +.. _`formatting thread`: https://discord.com/channels/799879767196958751/1190247322626572408 .. _`discord`: https://discord.gg/sXyFF8tDtm Currently, Ivy follows the `black`_ code style, and `flake8`_ formatter in order to ensure that our code is consistent, @@ -192,7 +192,7 @@ another try, or manually resolve the formatting errors by committing the changes This should have hopefully given you a good feel for what is our coding style and how to format your code to contribute to Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `formatting channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `formatting thread`_! **Video** diff --git a/docs/overview/deep_dive/function_arguments.rst b/docs/overview/deep_dive/function_arguments.rst index 988db211600ec..60888fdb0335e 100644 --- a/docs/overview/deep_dive/function_arguments.rst +++ b/docs/overview/deep_dive/function_arguments.rst @@ -5,7 +5,7 @@ Function Arguments .. _`spec/API_specification/signatures`: https://github.com/data-apis/array-api/tree/main/spec/2022.12/API_specification .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`function arguments channel`: https://discord.com/channels/799879767196958751/982738240354254898 +.. _`function arguments thread`: https://discord.com/channels/799879767196958751/1190247823275470978 .. _`Array API Standard convention`: https://data-apis.org/array-api/2021.12/API_specification/array_object.html#api-specification-array-object--page-root Here, we explain how the function arguments differ between the placeholder implementation at :mod:`ivy/functional/ivy/category_name.py`, and the backend-specific implementation at :mod:`ivy/functional/backends/backend_name/category_name.py`. @@ -210,7 +210,7 @@ Therefore, we simply omit these :class:`ivy.Container` type hints from *nestable These examples should hopefully give you a good understanding of what is required when adding function arguments. -If you have any questions, please feel free to reach out on `discord`_ in the `function arguments channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `function arguments thread`_! **Video** diff --git a/docs/overview/deep_dive/function_types.rst b/docs/overview/deep_dive/function_types.rst index d2bc16af271f8..c00d2839c73b5 100644 --- a/docs/overview/deep_dive/function_types.rst +++ b/docs/overview/deep_dive/function_types.rst @@ -33,7 +33,7 @@ Function Types .. _`handle`: https://github.com/unifyai/ivy/blob/0ef2888cbabeaa8f61ce8aaea4f1175071f7c396/ivy/func_wrapper.py#L1027-L1030 .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`function types channel`: https://discord.com/channels/799879767196958751/982737839861145630 +.. _`function types thread`: https://discord.com/channels/799879767196958751/1189905318650576896 Firstly, we explain the difference between *primary*, *compositional*, *mixed* and *standalone* functions. These four function categorizations are all **mutually exclusive**, and combined they constitute the set of **all** functions in Ivy, as outlined in the simple Venn diagram below. @@ -249,7 +249,7 @@ Feel free to have a look through all of the `submodules`_, you should be able to This should have hopefully given you a good feel for the different function types. -If you have any questions, please feel free to reach out on `discord`_ in the `function types channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `function types thread`_! **Video** diff --git a/docs/overview/deep_dive/function_wrapping.rst b/docs/overview/deep_dive/function_wrapping.rst index 8a585244222e6..5cee12cd1a25d 100644 --- a/docs/overview/deep_dive/function_wrapping.rst +++ b/docs/overview/deep_dive/function_wrapping.rst @@ -24,7 +24,7 @@ Function Wrapping .. _`handle_complex_input`: https://github.com/unifyai/ivy/blob/bd9b5b1080d33004e821a48c486b3a879b9d6616/ivy/func_wrapper.py#L1393 .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`function wrapping channel`: https://discord.com/channels/799879767196958751/982737993028755496 +.. _`function wrapping thread`: https://discord.com/channels/799879767196958751/1189906704775794688 .. _`handle_partial_mixed_function`: https://github.com/unifyai/ivy/blob/5658401b266352d3bf72c95e4af6ae9233115722/ivy/func_wrapper.py#L944 .. _`stored as an attribute`: https://github.com/unifyai/ivy/blob/5658401b266352d3bf72c95e4af6ae9233115722/ivy/func_wrapper.py#L1054 .. _`ivy.linear`: https://github.com/unifyai/ivy/blob/5658401b266352d3bf72c95e4af6ae9233115722/ivy/functional/ivy/layers.py#L81 @@ -151,7 +151,7 @@ For now, suffice it to say that they do quite a lot. This should have hopefully given you a good feel for how function wrapping is applied to functions in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `function wrapping channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `function wrapping thread`_! **Video** diff --git a/docs/overview/deep_dive/gradients.rst b/docs/overview/deep_dive/gradients.rst index bd502228f5031..2ae91e75aedf1 100644 --- a/docs/overview/deep_dive/gradients.rst +++ b/docs/overview/deep_dive/gradients.rst @@ -2,7 +2,7 @@ Gradients ========= .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`gradients channel`: https://discord.com/channels/799879767196958751/1000043921633722509 +.. _`gradients thread`: https://discord.com/channels/799879767196958751/1190235826806853672 Overview -------- @@ -172,7 +172,7 @@ Framework-specific Considerations This should have hopefully given you a good feel for how the gradient API is implemented in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `gradients channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `gradients thread`_! **Video** diff --git a/docs/overview/deep_dive/inplace_updates.rst b/docs/overview/deep_dive/inplace_updates.rst index a2a4019a8e106..17bfa0aca2c7b 100644 --- a/docs/overview/deep_dive/inplace_updates.rst +++ b/docs/overview/deep_dive/inplace_updates.rst @@ -18,7 +18,7 @@ Inplace Updates .. _`ivy.asarray`: https://github.com/unifyai/ivy/blob/8482eb3fcadd0721f339a1a55c3f3b9f5c86d8ba/ivy/functional/ivy/creation.py#L114 .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`inplace updates channel`: https://discord.com/channels/799879767196958751/1028681763947552778 +.. _`inplace updates thread`: https://discord.com/channels/799879767196958751/1189906590166437938 .. _`example`: https://github.com/unifyai/ivy/blob/0ef2888cbabeaa8f61ce8aaea4f1175071f7c396/ivy/functional/ivy/layers.py#L169-L176 @@ -511,7 +511,7 @@ Here's a brief description of what happens during an inplace operation with a Py This should have hopefully given you a good feel for inplace updates, and how these are handled in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `inplace updates channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `inplace updates thread`_! **Video** diff --git a/docs/overview/deep_dive/ivy_frontends.rst b/docs/overview/deep_dive/ivy_frontends.rst index ac7f1aab1ea14..c13c69169ae62 100644 --- a/docs/overview/deep_dive/ivy_frontends.rst +++ b/docs/overview/deep_dive/ivy_frontends.rst @@ -16,7 +16,7 @@ Ivy Frontends .. _`torch.tan`: https://pytorch.org/docs/stable/generated/torch.tan.html#torch.tan .. _`YouTube tutorial series`: https://www.youtube.com/watch?v=72kBVJTpzIw&list=PLwNuX3xB_tv-wTpVDMSJr7XW6IP_qZH0t .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`ivy frontends channel`: https://discord.com/channels/799879767196958751/998782045494976522 +.. _`ivy frontends thread`: https://discord.com/channels/799879767196958751/1189908295041941514 .. _`Array manipulation routines`: https://numpy.org/doc/stable/reference/routines.array-manipulation.html# .. _`Array creation routines`: https://numpy.org/doc/stable/reference/routines.array-creation.html @@ -676,7 +676,7 @@ Unit tests should be written for all aliases. This is arguably a duplication, bu This should hopefully have given you a better grasp on what the Ivy Frontend APIs are for, how they should be implemented, and the things to watch out for! We also have a short `YouTube tutorial series`_ on this as well if you prefer a video explanation! -If you have any questions, please feel free to reach out on `discord`_ in the `ivy frontends channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `ivy frontends thread`_! **Video** diff --git a/docs/overview/deep_dive/ivy_frontends_tests.rst b/docs/overview/deep_dive/ivy_frontends_tests.rst index 6cdad3a87772d..aacc3c6eefe42 100644 --- a/docs/overview/deep_dive/ivy_frontends_tests.rst +++ b/docs/overview/deep_dive/ivy_frontends_tests.rst @@ -2,7 +2,7 @@ Ivy Frontend Tests ================== .. _`here`: ../design/ivy_as_a_transpiler.rst -.. _`ivy frontends tests channel`: https://discord.com/channels/799879767196958751/1028267758028337193 +.. _`ivy frontends tests thread`: https://discord.com/channels/799879767196958751/1190246804940402738 .. _`test ivy`: https://github.com/unifyai/ivy/tree/db9a22d96efd3820fb289e9997eb41dda6570868/ivy_tests/test_ivy .. _`test_frontend_function`: https://github.com/unifyai/ivy/blob/591ac37a664ebdf2ca50a5b0751a3a54ee9d5934/ivy_tests/test_ivy/helpers.py#L1047 .. _`discord`: https://discord.gg/sXyFF8tDtm @@ -816,7 +816,7 @@ The configuration files are located at: :code:`ivy_tests/test_ivy/test_frontends This should have hopefully given you a good understanding of Ivy Frontend Tests! -If you have any questions, please feel free to reach out on `discord`_ in the `ivy frontends tests channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `ivy frontends tests thread`_! **Video** diff --git a/docs/overview/deep_dive/ivy_lint.rst b/docs/overview/deep_dive/ivy_lint.rst index a777f110a7470..1ac74dbd30979 100644 --- a/docs/overview/deep_dive/ivy_lint.rst +++ b/docs/overview/deep_dive/ivy_lint.rst @@ -55,4 +55,4 @@ Round Up ``ivy-lint`` stands as a testament to Ivy's commitment to code clarity and uniformity. As the landscape of our needs shifts, we foresee further refining and expanding our suite of formatters. -For all discussions or inquiries, you're always welcome on `discord `_ in the `formatting channel `_. +For all discussions or inquiries, you're always welcome on `discord `_ in the `formatting thread `_. diff --git a/docs/overview/deep_dive/ivy_tests.rst b/docs/overview/deep_dive/ivy_tests.rst index be78008687a57..9b3639dd385df 100644 --- a/docs/overview/deep_dive/ivy_tests.rst +++ b/docs/overview/deep_dive/ivy_tests.rst @@ -47,7 +47,7 @@ Ivy Tests .. _`artifact`: https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`ivy tests channel`: https://discord.com/channels/799879767196958751/982738436383445073 +.. _`ivy tests thread`: https://discord.com/channels/799879767196958751/1189907526226034698 .. _`test helpers`: https://github.com/unifyai/ivy/tree/main/ivy_tests/test_ivy/helpers/hypothesis_helpers .. _`get_dtypes`: https://github.com/unifyai/ivy/blob/e50f71e283313caa9737f3c284496022ac67b58b/ivy_tests/test_ivy/helpers/hypothesis_helpers/dtype_helpers.py#L60 .. _`dtype_and_values`: https://github.com/unifyai/ivy/blob/e50f71e283313caa9737f3c284496022ac67b58b/ivy_tests/test_ivy/helpers/hypothesis_helpers/array_helpers.py#L83 @@ -63,6 +63,7 @@ Ivy Tests .. _`num_positional_args`: https://github.com/unifyai/ivy/blob/e50f71e283313caa9737f3c284496022ac67b58b/ivy_tests/test_ivy/helpers/testing_helpers.py#L78 .. _`CI Pipeline`: continuous_integration.rst .. _`Hypothesis docs`: https://hypothesis.readthedocs.io/en/latest/data.html#core-strategies +.. _`this`: https://github.com/unifyai/ivy/blob/8dcc33b895240395686db165c710ac31708aa691/ivy_tests/test_ivy/test_functional/test_core/test_general.py#L1650 On top of the Array API `test suite`_, which is included as a submodule mapped to the folder :code:`test_array_api`, there is also a collection of Ivy tests, located in subfolder `test_ivy`_. @@ -221,7 +222,7 @@ Ivy Test Decorators - Why do we need to handle test decorators? -In order to run a test, a lot of pre-processing must be done, e.g. import the function, does it support complex data type? does it run on CPU? how many parameters does it take? are they positional or keyword only, or both? and a lot of information about the function that is being tested, this allows us later to run the test efficiently and in a **complete** way. all of this happens at collecting time. +In order to run a test, a lot of pre-processing must be done, e.g. import the function, does it support complex data type? does it run on CPU? how many parameters does it take? are they positional or keyword only, or both? and a lot of information about the function that is being tested, this allows us later to run the test efficiently and in a **complete** way. All of this happens at collecting time. - What do the handle test decorators do? @@ -241,14 +242,15 @@ This is not an exhaustive list of what the :code:`handle_test` decorators actual - Why do we have multiple handle test decorators? -Having multiple test decorators is mainly for efficiency, `handle_test` could do what `handle_frontend_test` does, it just handles the parameters slightly different, and this can be inferred at run time, but we choose to separate the decorator for general different usages, currently we have 4 separate decorators +Having multiple test decorators is mainly for efficiency, `handle_test` could do what `handle_frontend_test` does, it just handles the parameters slightly different, and this can be inferred at run time, but we choose to separate the decorator for general different usages, currently we have 5 separate decorators 1. :code:`handle_test` 2. :code:`handle_method` 3. :code:`handle_frontend_test` 4. :code:`handle_frontend_method` +5. :code:`handle_example` -One of the few differences between the 4 decorators is that they generate different kinds of flags, some generate more or less, but they all share the same general structure. +One of the few differences between the 5 decorators is that they generate different kinds of flags, some generate more or less, but they all share the same general structure. - Integration @@ -359,6 +361,49 @@ Let's look at the data produced by this strategy -: These values are then unpacked, converted to :class:`ivy.Array` class, with corresponding dtypes. The test then runs on the newly created arrays with specified data types. +Adding Explicit Examples to tests +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In certain cases where we'd like to test certain examples explicitly which are outliers and it isn't feasible to define them as a strategy, +we can use the :code:`@handle_example` decorator. One such example is `this`_ where we need to test `ivy.set_item` with slice objects. + +Hypothesis allows us to test with an explicit example deterministically using the `@example`_ decorator. Our :code:`@handle_example` decorator is a wrapper around this. +Which helps us to use the default values of the test_flags, method_flags allowing us to easily test explicit examples for the ivy functional tests, frontend_tests, methods, and frontend_methods. + +We have to pass one of the following 4 arguments as `True` to the :code:`@handle_example` decorator depending on what test we are dealing with. +1. `test_example` +2. `test_frontend_example` +3. `test_method_example` +4. `test_frontend_method_example` + +The following example shows, how we can use the :code:`@handle_example` decorator to test the one of the frontend functions by adding an explicit example. + +.. code-block:: python + @handle_frontend_test( + fn_tree="paddle.acos", + dtype_and_x=helpers.dtype_and_values(available_dtypes=helpers.get_dtypes("float"),), + ) + @handle_example( + test_frontend_example=True, + dtype_and_x=(["float32"], [np.array(9.0, dtype=np.float32)]), + fn_tree="ivy.functional.frontends.paddle.acos", + test_flags={ + "native_arrays": [True], + "with_copy": True, + "with_out": True, + }, + ) + def test_some_function( + *, + dtype_and_x, + fn_tree, + frontend, + test_flags, + backend_fw, + ): + pass + + Why do we need helper functions? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -895,7 +940,7 @@ This ensures that the given example is always tested while running the test, all This should have hopefully given you a good feel for how the tests are implemented in Ivy. -If you have any questions, please feel free to reach out on `discord`_ in the `ivy tests channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `ivy tests thread`_! **Video** diff --git a/docs/overview/deep_dive/navigating_the_code.rst b/docs/overview/deep_dive/navigating_the_code.rst index 1fe0e6f256cd7..0bdb82f9418c0 100644 --- a/docs/overview/deep_dive/navigating_the_code.rst +++ b/docs/overview/deep_dive/navigating_the_code.rst @@ -4,7 +4,7 @@ Navigating the Code .. _`Array API Standard`: https://data-apis.org/array-api/latest/ .. _`repo`: https://github.com/unifyai/ivy .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`navigating the code channel`: https://discord.com/channels/799879767196958751/982737793476345888 +.. _`navigating the code thread`: https://discord.com/channels/799879767196958751/1189905165373935616 .. _`Array API Standard convention`: https://data-apis.org/array-api/2021.12/API_specification/array_object.html#api-specification-array-object--page-root .. _`flake8`: https://flake8.pycqa.org/en/latest/index.html @@ -199,7 +199,7 @@ To have a better idea on this, let's look at an example! In the :func:`full_like` function in :mod:`creation.py`, the types of :code:`fill_value` and :code:`dtype` has to be verified to avoid errors. This check has to be applied to all backends, which means the related code is common and identical. In this case, we can extract the code to be a helper function on its own, placed in its related submodule (:mod:`creation.py` here). -In this example, the helper function is named as :func:`_assert_fill_value_and_dtype_are_compatible`. +In this example, the helper function is named as :func:`check_fill_value_and_dtype_are_compatible`. Then, we import this submodule-specific helper function to the respective backends, where examples for each backend is shown below. @@ -299,7 +299,7 @@ This helps to prevent our work from culminating over a fixed version while strid This should have hopefully given you a good feel for how to navigate the Ivy codebase. -If you have any questions, please feel free to reach out on `discord`_ in the `navigating the code channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `navigating the code thread`_! **Video** diff --git a/docs/overview/deep_dive/superset_behaviour.rst b/docs/overview/deep_dive/superset_behaviour.rst index 6ccccad5696f6..d2e9e940cdc44 100644 --- a/docs/overview/deep_dive/superset_behaviour.rst +++ b/docs/overview/deep_dive/superset_behaviour.rst @@ -3,7 +3,7 @@ Superset Behaviour .. _`Array API Standard`: https://data-apis.org/array-api/latest/ .. _`discord`: https://discord.gg/sXyFF8tDtm -.. _`superset behavior channel`: https://discord.com/channels/799879767196958751/1018954266322419732 +.. _`superset behavior thread`: https://discord.com/channels/799879767196958751/1189905520686014514 .. _`partial_mixed_handler`: https://github.com/unifyai/ivy/blob/a07919ebf64181852a3564c4d994bc1c25bd9a6f/ivy/functional/backends/tensorflow/experimental/layers.py#L817 .. _`handle_partial_mixed_function`: https://github.com/unifyai/ivy/blob/a07919ebf64181852a3564c4d994bc1c25bd9a6f/ivy/func_wrapper.py#L981 @@ -266,7 +266,7 @@ This should have hopefully given you a good feel of what should and should not b In many cases, there is not a clear right and wrong answer, and we arrive at the final decision via open discussion. If you find yourself proposing the addition of a new function in Ivy, then we will most likely have this discussion on your Pull Request! -If you have any questions, please feel free to reach out on `discord`_ in the `superset behavior channel`_! +If you have any questions, please feel free to reach out on `discord`_ in the `superset behavior thread`_! **Video** diff --git a/docs/overview/design/building_blocks.rst b/docs/overview/design/building_blocks.rst index 249e48050e006..ca520798d67c2 100644 --- a/docs/overview/design/building_blocks.rst +++ b/docs/overview/design/building_blocks.rst @@ -11,7 +11,7 @@ These are the 4 parts labelled as (a) in the image below: Backend Functional APIs βœ… -------------------------- -The first important point to make is that, Ivy does not implement it’s own C++ or CUDA backend. +The first important point to make is that, Ivy does not implement its own C++ or CUDA backend. Instead, Ivy **wraps** the functional APIs of existing frameworks, bringing them into syntactic and semantic alignment. Let’s take the function :func:`ivy.stack` as an example. diff --git a/docs/overview/volunteer_ranks.rst b/docs/overview/volunteer_ranks.rst new file mode 100644 index 0000000000000..e359c13c4280f --- /dev/null +++ b/docs/overview/volunteer_ranks.rst @@ -0,0 +1,83 @@ +Contributor Leaderboard +======================= + +This page lists all of our amazing Contributors who have contributed to the project! We are grateful for your contributions and we hope to see you grow with the project! The ranks listed here are based on the `level of contribution `_\. + +Top Contributors +---------------- +.. list-table:: + :widths: 50 50 50 + :header-rows: 1 + + * - Name + - Github ID + - Badges + * - samunder singh + - `samthakur587 `_ + - Merging Master Gold, Merging Wizard, Ivy Inspector Bronze + * - V\. Sai Suraj + - `Sai-Suraj-27 `_ + - Merging Master Gold, Ivy Inspector Bronze +Core Contributors +----------------- +.. list-table:: + :widths: 50 50 50 + :header-rows: 1 + + * - Name + - Github ID + - Badges + * - Sanjay Suthar + - `Sanjay8602 `_ + - Merging Master Bronze, Ivy Inspector Bronze + * - Muhammad ishaque + - `MuhammadNizamani `_ + - Merging Master Bronze, Merging Wizard + * - nitesh kesharwani + - `NiteshK84 `_ + - Ivy Inspector Bronze + * - sarvesh kesharwani + - `Sarvesh-Kesharwani `_ + - Ivy Inspector Bronze +Contributors +------------ +.. list-table:: + :widths: 50 50 50 + :header-rows: 1 + + * - Name + - Github ID + - Badges + * - Suyash Gupta + - `sgalpha01 `_ + - Debugging Dynamo, Merging Master, Merging Wizard + * - Garima Saroj + - `AndroGari `_ + - Merging Master, Ivy Inspector + * - Jackson McClintock + - `jacksondm33 `_ + - Merging Master, Ivy Inspector + * - Mostafa Gamal + - `Mr-Array22 `_ + - Merging Master, Ivy Inspector + * - Rahul Prem + - `rp097 `_ + - Merging Master, Ivy Inspector + * - Rohit Kumar Salla + - `rohitsalla `_ + - Merging Master, Ivy Inspector + * - Waqar Ahmed + - `waqaarahmed `_ + - Merging Master, Ivy Inspector + * - David Adlai Nettey + - `Adlai-1 `_ + - Merging Master + * - Kacper KoΕΌdoΕ„ + - `Kacper-W-Kozdon `_ + - Merging Master + * - R E Zera Marveen Lyngkhoi + - `fleventy-5 `_ + - Merging Master + * - Sheroz Khan + - `ksheroz `_ + - Merging Master diff --git a/ivy/__init__.py b/ivy/__init__.py index 54a493d5f7e6e..d40ab10bfb12d 100644 --- a/ivy/__init__.py +++ b/ivy/__init__.py @@ -7,6 +7,7 @@ import numpy as np import sys import inspect +import importlib import os from collections.abc import Sequence @@ -69,6 +70,10 @@ class NativeShape: pass +class NativeModule: + pass + + class Container: pass @@ -282,15 +287,24 @@ def __radd__(self, other): return self def __mul__(self, other): - self._shape = self._shape * other + if ivy.current_backend_str() == "tensorflow": + shape_tup = builtins.tuple(self._shape) * other + self._shape = ivy.to_native_shape(shape_tup) + else: + self._shape = self._shape * other return self def __rmul__(self, other): - self._shape = other * self._shape + # handle tensorflow case as tf.TensorShape doesn't support multiplications + if ivy.current_backend_str() == "tensorflow": + shape_tup = other * builtins.tuple(self._shape) + self._shape = ivy.to_native_shape(shape_tup) + else: + self._shape = other * self._shape return self def __bool__(self): - return self._shape.__bool__() + return builtins.bool(self._shape) def __div__(self, other): return self._shape // other @@ -308,7 +322,7 @@ def __rmod__(self, other): return other % self._shape def __reduce__(self): - return (self._shape,) + return (self.__class__, (self._shape,)) def as_dimension(self, other): if isinstance(other, self._shape): @@ -443,8 +457,8 @@ def unknown_shape(rank=None, **kwargs): def with_rank(self, rank): try: return self.merge_with(self.unknown_shape(rank=rank)) - except ValueError: - raise ValueError(f"Shape {self} must have rank {rank}") + except ValueError as e: + raise ValueError(f"Shape {self} must have rank {rank}") from e def with_rank_at_least(self, rank): if self.rank is not None and self.rank < rank: @@ -591,7 +605,7 @@ class Node(str): nan_policy_stack = [] dynamic_backend_stack = [] warn_to_regex = {"all": "!.*", "ivy_only": "^(?!.*ivy).*$", "none": ".*"} - +cython_wrappers_stack = [] # local import threading @@ -741,7 +755,7 @@ class Node(str): locks = {"backend_setter": threading.Lock()} - +from .wrappers import * from .func_wrapper import * from .data_classes.array import Array, add_ivy_array_instance_methods from .data_classes.array.conversions import * @@ -776,6 +790,7 @@ class Node(str): choose_random_backend, unset_backend, ) +from . import wrappers from . import func_wrapper from .utils import assertions, exceptions, verbosity from .utils.backend import handler @@ -800,7 +815,7 @@ class Node(str): pass # Added for the finally statement try: from .compiler.replace_with import replace_with, transform_function -except: +except: # noqa: E722 pass finally: # Skip framework imports done by Ivy compiler for now @@ -924,44 +939,47 @@ def __deepcopy__(self, memo): # defines ivy.globals attribute -globals_vars = GlobalsDict({ - "backend_stack": backend_stack, - "default_device_stack": device.default_device_stack, - "valid_dtypes": valid_dtypes, - "valid_numeric_dtypes": valid_numeric_dtypes, - "valid_int_dtypes": valid_int_dtypes, - "valid_uint_dtypes": valid_uint_dtypes, - "valid_complex_dtypes": valid_complex_dtypes, - "valid_devices": valid_devices, - "invalid_dtypes": invalid_dtypes, - "invalid_numeric_dtypes": invalid_numeric_dtypes, - "invalid_int_dtypes": invalid_int_dtypes, - "invalid_float_dtypes": invalid_float_dtypes, - "invalid_uint_dtypes": invalid_uint_dtypes, - "invalid_complex_dtypes": invalid_complex_dtypes, - "invalid_devices": invalid_devices, - "array_significant_figures_stack": array_significant_figures_stack, - "array_decimal_values_stack": array_decimal_values_stack, - "warning_level_stack": warning_level_stack, - "queue_timeout_stack": general.queue_timeout_stack, - "array_mode_stack": general.array_mode_stack, - "inplace_mode_stack": general.inplace_mode_stack, - "soft_device_mode_stack": device.soft_device_mode_stack, - "shape_array_mode_stack": general.shape_array_mode_stack, - "show_func_wrapper_trace_mode_stack": general.show_func_wrapper_trace_mode_stack, - "min_denominator_stack": general.min_denominator_stack, - "min_base_stack": general.min_base_stack, - "tmp_dir_stack": general.tmp_dir_stack, - "precise_mode_stack": general.precise_mode_stack, - "nestable_mode_stack": general.nestable_mode_stack, - "exception_trace_mode_stack": general.exception_trace_mode_stack, - "default_dtype_stack": data_type.default_dtype_stack, - "default_float_dtype_stack": data_type.default_float_dtype_stack, - "default_int_dtype_stack": data_type.default_int_dtype_stack, - "default_uint_dtype_stack": data_type.default_uint_dtype_stack, - "nan_policy_stack": nan_policy_stack, - "dynamic_backend_stack": dynamic_backend_stack, -}) +globals_vars = GlobalsDict( + { + "backend_stack": backend_stack, + "default_device_stack": device.default_device_stack, + "valid_dtypes": valid_dtypes, + "valid_numeric_dtypes": valid_numeric_dtypes, + "valid_int_dtypes": valid_int_dtypes, + "valid_uint_dtypes": valid_uint_dtypes, + "valid_complex_dtypes": valid_complex_dtypes, + "valid_devices": valid_devices, + "invalid_dtypes": invalid_dtypes, + "invalid_numeric_dtypes": invalid_numeric_dtypes, + "invalid_int_dtypes": invalid_int_dtypes, + "invalid_float_dtypes": invalid_float_dtypes, + "invalid_uint_dtypes": invalid_uint_dtypes, + "invalid_complex_dtypes": invalid_complex_dtypes, + "invalid_devices": invalid_devices, + "array_significant_figures_stack": array_significant_figures_stack, + "array_decimal_values_stack": array_decimal_values_stack, + "warning_level_stack": warning_level_stack, + "queue_timeout_stack": general.queue_timeout_stack, + "array_mode_stack": general.array_mode_stack, + "inplace_mode_stack": general.inplace_mode_stack, + "soft_device_mode_stack": device.soft_device_mode_stack, + "shape_array_mode_stack": general.shape_array_mode_stack, + "show_func_wrapper_trace_mode_stack": general.show_func_wrapper_trace_mode_stack, + "min_denominator_stack": general.min_denominator_stack, + "min_base_stack": general.min_base_stack, + "tmp_dir_stack": general.tmp_dir_stack, + "precise_mode_stack": general.precise_mode_stack, + "nestable_mode_stack": general.nestable_mode_stack, + "exception_trace_mode_stack": general.exception_trace_mode_stack, + "default_dtype_stack": data_type.default_dtype_stack, + "default_float_dtype_stack": data_type.default_float_dtype_stack, + "default_int_dtype_stack": data_type.default_int_dtype_stack, + "default_uint_dtype_stack": data_type.default_uint_dtype_stack, + "nan_policy_stack": nan_policy_stack, + "dynamic_backend_stack": dynamic_backend_stack, + "cython_wrappers_stack": cython_wrappers_stack, + } +) _default_globals = copy.deepcopy(globals_vars) @@ -1144,7 +1162,7 @@ def unset_nan_policy(): ivy.dynamic_backend = dynamic_backend_stack[-1] if dynamic_backend_stack else True -def set_dynamic_backend(flag): +def set_dynamic_backend(flag): # noqa: D209 """Set the global dynamic backend setting to the provided flag (True or False)""" global dynamic_backend_stack @@ -1166,6 +1184,37 @@ def unset_dynamic_backend(): ivy.__setattr__("dynamic_backend", flag, True) +# Cython wrappers + +ivy.cython_wrappers_mode = cython_wrappers_stack[-1] if cython_wrappers_stack else False + + +@handle_exceptions +def set_cython_wrappers_mode(flag: bool = True) -> None: + """Set the mode of whether to use cython wrappers for functions. + + Parameter + --------- + flag + boolean whether to use cython wrappers for functions + + Examples + -------- + >>> ivy.set_cython_wrappers_mode(False) + >>> ivy.cython_wrappers_mode + False + + >>> ivy.set_cython_wrappers_mode(True) + >>> ivy.cython_wrappers_mode + True + """ + global cython_wrappers_stack + if flag not in [True, False]: + raise ValueError("cython_wrappers_mode must be a boolean value (True or False)") + cython_wrappers_stack.append(flag) + ivy.__setattr__("cython_wrappers_mode", flag, True) + + # Context Managers @@ -1213,7 +1262,10 @@ def dynamic_backend_as(value): downcast_dtypes = False upcast_dtypes = False crosscast_dtypes = False -cast_dtypes = lambda: downcast_dtypes and upcast_dtypes and crosscast_dtypes + + +def cast_dtypes(): + return downcast_dtypes and upcast_dtypes and crosscast_dtypes def downcast_data_types(val=True): @@ -1435,6 +1487,7 @@ def cast_data_types(val=True): "default_int_dtype", "default_complex_dtype", "default_uint_dtype", + "cython_wrappers_mode", ] @@ -1476,7 +1529,7 @@ def set_logging_mode(self, mode): logging.getLogger().setLevel(mode) self.logging_mode_stack.append(mode) - def unset_logging_mode(self): + def unset_logging_mode(self): # noqa: D209 """Remove the most recently set logging mode, returning to the previous one.""" if len(self.logging_mode_stack) > 1: @@ -1499,6 +1552,14 @@ def __setattr__(self, name, value, internal=False): ) self.__dict__[name] = value + def __reduce__(self): + def _get_module_and_replace_name(module_name: str): + module = importlib.import_module(module_name) + module.__class__ = self.__class__ + return module + + return (_get_module_and_replace_name, (self.__name__,)) + if ( "ivy" in sys.modules diff --git a/ivy/_version.py b/ivy/_version.py index d1bfff206d3b1..b982b20f2a8b3 100644 --- a/ivy/_version.py +++ b/ivy/_version.py @@ -1 +1 @@ -__version__ = "0.0.4.0" +__version__ = "0.0.7.2" diff --git a/ivy/compiler/compiler.py b/ivy/compiler/compiler.py index 535e749daff4b..4bd5ae74aeb45 100644 --- a/ivy/compiler/compiler.py +++ b/ivy/compiler/compiler.py @@ -128,6 +128,7 @@ def transpile( static_argnames: Optional[Union[str, Iterable[str]]] = None, compile_mode: Optional[str] = None, graph_caching: bool = False, + graph_optimizations: bool = True, modes_to_trace: str = "all", stateful: Optional[List] = None, arg_stateful_idxs: Optional[List] = None, @@ -170,6 +171,7 @@ def transpile( static_argnames=static_argnames, compile_mode=compile_mode, graph_caching=graph_caching, + graph_optimizations=graph_optimizations, modes_to_trace=modes_to_trace, stateful=stateful, arg_stateful_idxs=arg_stateful_idxs, @@ -185,18 +187,21 @@ def unify( *objs: Callable, source: Optional[str] = None, graph_caching: bool = False, + graph_optimizations: bool = True, args: Optional[Sequence] = None, kwargs: Optional[Mapping] = None, with_numpy: bool = True, modes_to_trace: str = "all", **transpile_kwargs ): + from ._compiler import unify as _unify return _unify( *objs, source=source, graph_caching=graph_caching, + graph_optimizations=graph_optimizations, args=args, kwargs=kwargs, with_numpy=with_numpy, diff --git a/ivy/data_classes/array/array.py b/ivy/data_classes/array/array.py index 358efed6ddd7b..77536ed75c53e 100644 --- a/ivy/data_classes/array/array.py +++ b/ivy/data_classes/array/array.py @@ -144,6 +144,8 @@ def _init(self, data, dynamic_backend=None): self._data = data elif isinstance(data, np.ndarray): self._data = ivy.asarray(data)._data + elif isinstance(data, (list, tuple)): + self._data = ivy.asarray(data)._data elif ivy.is_ivy_sparse_array(data): self._data = data._data elif ivy.is_native_sparse_array(data): @@ -399,7 +401,13 @@ def __repr__(self): self._post_repr = ")" sig_fig = ivy.array_significant_figures dec_vals = ivy.array_decimal_values - backend = ivy.with_backend(self.backend) + if self.backend == "" or ivy.is_local(): + # If the array was constructed using implicit backend + backend = ivy.current_backend() + else: + # Requirerd in the case that backend is different + # from the currently set backend + backend = ivy.with_backend(self.backend) arr_np = backend.to_numpy(self._data) rep = ( np.array(ivy.vec_sig_fig(arr_np, sig_fig)) diff --git a/ivy/data_classes/array/elementwise.py b/ivy/data_classes/array/elementwise.py index b8de2d75e91ad..35a79eb00ee3d 100644 --- a/ivy/data_classes/array/elementwise.py +++ b/ivy/data_classes/array/elementwise.py @@ -2731,40 +2731,6 @@ def nan_to_num( self._data, copy=copy, nan=nan, posinf=posinf, neginf=neginf, out=out ) - def imag( - self: ivy.Array, - /, - *, - out: Optional[ivy.Array] = None, - ) -> ivy.Array: - """ivy.Array instance method variant of ivy.imag. This method simply - wraps the function, and so the docstring for ivy.imag also applies to - this method with minimal changes. - - Parameters - ---------- - self - Array-like input. - out - optional output array, for writing the result to. - - Returns - ------- - ret - Returns an array with the imaginary part of complex numbers. - - Examples - -------- - >>> b = ivy.array(np.array([1+2j, 3+4j, 5+6j])) - >>> b - ivy.array([1.+2.j, 3.+4.j, 5.+6.j]) - >>> ivy.imag(b) - ivy.array([2., 4., 6.]) - >>> b.imag() - ivy.array([2., 4., 6.]) - """ - return ivy.imag(self._data, out=out) - def angle( self: ivy.Array, /, diff --git a/ivy/data_classes/array/experimental/activations.py b/ivy/data_classes/array/experimental/activations.py index 6e44b4240c190..5798896266b90 100644 --- a/ivy/data_classes/array/experimental/activations.py +++ b/ivy/data_classes/array/experimental/activations.py @@ -325,7 +325,7 @@ def hardtanh( >>> x = ivy.array([-1., .2, 1.]) >>> y = x.hardtanh() >>> print(y) - ivy.array([-1., 1., 1.]) + ivy.array([-1. , 0.2, 1. ]) """ return ivy.hardtanh(self._data, min_val=min_val, max_val=max_val, out=out) @@ -554,3 +554,28 @@ def hardshrink( ivy.array([0., 0., 0.]) """ return ivy.hardshrink(self._data, lambd=lambd, out=out) + + def hardsilu(self, out: Optional[ivy.Array] = None) -> ivy.Array: + """ivy.Array instance method which acts as a wrapper for ivy.hardsilu. + + Parameters + ---------- + self + input array + out + optional output array, for writing the result to. It must have a shape + that the inputs broadcast to. + + Returns + ------- + an array containing the output of the hardsilu/hardswish function applied + to each element in ``x``. + + Examples + -------- + >>> x = ivy.array([1., 2., 3.]) + >>> y = x.hardsilu() + >>> print(y) + ivy.array([0.66666667, 1.66666667, 3.]) + """ + return ivy.hardsilu(self._data, out=out) diff --git a/ivy/data_classes/array/experimental/creation.py b/ivy/data_classes/array/experimental/creation.py index 62ab0e9f1744d..589f7d9168ace 100644 --- a/ivy/data_classes/array/experimental/creation.py +++ b/ivy/data_classes/array/experimental/creation.py @@ -167,9 +167,7 @@ def blackman_window( ivy.array([-1.38777878e-17, 1.30000000e-01, 6.30000000e-01, 1.00000000e+00, 6.30000000e-01, 1.30000000e-01, -1.38777878e-17]) """ - return ivy.blackman_window( - self._data, periodic=periodic, dtype=dtype, device=device, out=out - ) + return ivy.blackman_window(self._data, periodic=periodic, dtype=dtype, out=out) def trilu( self: ivy.Array, @@ -344,6 +342,4 @@ def polyval( return ivy.polyval( coeffs, x, - dtype=dtype, - device=device, ) diff --git a/ivy/data_classes/array/experimental/elementwise.py b/ivy/data_classes/array/experimental/elementwise.py index f48d1b303fc55..80eb526cb7093 100644 --- a/ivy/data_classes/array/experimental/elementwise.py +++ b/ivy/data_classes/array/experimental/elementwise.py @@ -1191,3 +1191,34 @@ def erfc( ivy.array([1.00000000e+00, 1.84270084e+00, 2.80259693e-45]) """ return ivy.erfc(self._data, out=out) + + def erfinv( + self: ivy.Array, + /, + *, + out: Optional[ivy.Array] = None, + ) -> ivy.Array: + """ivy.Array instance method variant of ivy.erfinv. This method simply + wraps the function, and so the docstring for ivy.erfinv also applies to + this method with minimal changes. + + Parameters + ---------- + self + Input array with real or complex valued argument. + out + Alternate output array in which to place the result. + The default is None. + + Returns + ------- + ret + Values of the inverse error function. + + Examples + -------- + >>> x = ivy.array([0, -1., 10.]) + >>> x.erfinv() + ivy.array([1.00000000e+00, 1.84270084e+00, 2.80259693e-45]) + """ + return ivy.erfinv(self._data, out=out) diff --git a/ivy/data_classes/array/experimental/layers.py b/ivy/data_classes/array/experimental/layers.py index 730efb67569d8..7ba561245349b 100644 --- a/ivy/data_classes/array/experimental/layers.py +++ b/ivy/data_classes/array/experimental/layers.py @@ -877,6 +877,15 @@ def adaptive_max_pool2d( output_size, ) + def adaptive_max_pool3d( + self: ivy.Array, + output_size: Union[Sequence[int], int], + ) -> ivy.Array: + return ivy.adaptive_max_pool3d( + self._data, + output_size, + ) + def reduce_window( self: ivy.Array, init_value: Union[int, float], diff --git a/ivy/data_classes/array/experimental/linear_algebra.py b/ivy/data_classes/array/experimental/linear_algebra.py index 6156d43f33ee0..865c4a1296942 100644 --- a/ivy/data_classes/array/experimental/linear_algebra.py +++ b/ivy/data_classes/array/experimental/linear_algebra.py @@ -323,8 +323,8 @@ def multi_mode_dot( If True, the matrices or vectors in in the list are transposed. For complex tensors, the conjugate transpose is used. out - optional output array, for writing the result to. It must have a shape that the - result can broadcast to. + optional output array, for writing the result to. + It must have a shape that the result can broadcast to. Returns ------- @@ -334,8 +334,8 @@ def multi_mode_dot( Notes ----- If no modes are specified, just assumes there is one matrix or vector per mode and returns: - :math:`\\text{x }\\times_0 \\text{ matrix or vec list[0] }\\times_1 \\cdots \\times_n \\text{ matrix or vec list[n] }` # noqa - """ + :math:`\\text{x }\\times_0 \\text{ matrix or vec list[0] }\\times_1 \\cdots \\times_n \\text{ matrix or vec list[n] }` + """ # noqa: E501 return ivy.multi_mode_dot( self._data, mat_or_vec_list, modes, skip, transpose, out=out ) @@ -832,7 +832,7 @@ def general_inner_product( >>> a = ivy.array([1, 2, 3]) >>> b = ivy.array([4, 5, 6]) - >>> result = a.general_inner_product(b, n_modes=1) + >>> result = a.general_inner_product(b, 1) >>> print(result) ivy.array(32) @@ -844,7 +844,7 @@ def general_inner_product( >>> a = ivy.array([[1, 1], [1, 1]]) >>> b = ivy.array([[1, 2, 3, 4],[1, 1, 1, 1]]) - >>> result = a.general_inner_product(b, n_modes=1) + >>> result = a.general_inner_product(b, 1) >>> print(result) ivy.array([[2, 3, 4, 5], [2, 3, 4, 5]]) diff --git a/ivy/data_classes/array/experimental/losses.py b/ivy/data_classes/array/experimental/losses.py index f676338c11c89..8912d815ff5a0 100644 --- a/ivy/data_classes/array/experimental/losses.py +++ b/ivy/data_classes/array/experimental/losses.py @@ -98,7 +98,7 @@ def log_poisson_loss( ivy.array([1.28402555, 1.28402555, 1.03402555, 1.28402555]) >>> z = ivy.array([0.1, 0.1, 0.7, 0.1]) - >>> loss = x.x.log_poisson_loss(z, reduction='mean') + >>> loss = x.log_poisson_loss(z, reduction='mean') >>> print(loss) ivy.array(1.1573164) """ @@ -353,9 +353,9 @@ def poisson_nll_loss( -------- >>> input_tensor = ivy.array([1, 2, 3, 4], dtype=ivy.float64) >>> target_tensor = ivy.array([2, 2, 2, 2], dtype=ivy.float64) - >>> loss = poisson_nll_loss(input_tensor, target_tensor, log_input=True) + >>> loss = input_tensor.poisson_nll_loss(target_tensor, log_input=True) >>> print(loss) - ivy.array(16.1978) + ivy.array(16.1977562) """ return ivy.poisson_nll_loss( self._data, @@ -365,3 +365,84 @@ def poisson_nll_loss( eps=eps, reduction=reduction, ) + + def hinge_embedding_loss( + self: Union[ivy.Array, ivy.NativeArray], + target: Union[ivy.Array, ivy.NativeArray], + *, + margin: float = 1.0, + reduction: str = "mean", + ) -> ivy.Array: + r"""Measures loss from input `x` and label `y` with values 1 or -1. It + evaluates if two inputs are similar or not, often used for embedding or + semi-supervised learning. + + Loss for the `n`-th sample: + .. math:: + l_n = \begin{cases} + x_n, & \text{if}\; y_n = 1,\\ + \max \{0, margin - x_n\}, & \text{if}\; y_n = -1, + \end{cases} + + Total loss: + .. math:: + \ell(x, y) = \begin{cases} + \operatorname{mean}(L), & \text{if reduction} = \text{`mean';}\\ + \operatorname{sum}(L), & \text{if reduction} = \text{`sum'.} + \end{cases} + + where :math:`L = \{l_1,\dots,l_N\}^\top` + + Parameters + ---------- + input + Input tensor with dtype float. + The shape is [N, \*], where N is batch size and `\*` represents + any number of additional dimensions. + label + Label tensor containing 1 or -1 with dtype float32 or float64. + Its shape matches that of the input. + margin + Sets the hyperparameter margin. Determines the necessary input size + for hinge_embedding_loss calculations when label is -1. Inputs smaller + than the margin are minimized with hinge_embedding_loss. + Default is 1.0. + reduction + Specifies how to aggregate the loss across the batch. Options are: + - ``'none'``: Returns the unreduced loss. + - ``'mean'``: Returns the mean loss. + - ``'sum'``: Returns the summed loss. + Default is ``'mean'``. + + Shape + ----- + - Input: :math:`(*)` where :math:`*` means, any number of dimensions. \ + The sum operation operates over all the elements. + - Target: :math:`(*)`, same shape as the input + - Output: scalar. If :attr:`reduction` is ``'none'``, + then same shape as the input + + Returns + ------- + ret + Hinge embedding loss calculated from the input and label, + shaped based on the reduction method. + + Examples + -------- + >>> input_tensor = ivy.array([1, 2, 3, 4], dtype=ivy.float64) + >>> target_tensor = ivy.array([1, 1, 1, 1], dtype=ivy.float64) + >>> input_tensor.hinge_embedding_loss(target_tensor,reduction="sum") + ivy.array(10.) + + >>> input_tensor = ivy.array([1, 2, 3], dtype=ivy.float64) + >>> target_tensor = ivy.array([1, -1, -1], dtype=ivy.float64) + >>> input_tensor.hinge_embedding_loss(target_tensor, margin=2.0) + ivy.array(0.33333333) + """ + return ivy.hinge_embedding_loss( + self._data, + target, + margin=margin, + reduction=reduction, + ) diff --git a/ivy/data_classes/array/experimental/manipulation.py b/ivy/data_classes/array/experimental/manipulation.py index 013af82658b0a..af3292542a678 100644 --- a/ivy/data_classes/array/experimental/manipulation.py +++ b/ivy/data_classes/array/experimental/manipulation.py @@ -1134,6 +1134,64 @@ def take( self, indices, axis=axis, mode=mode, fill_value=fill_value, out=out ) + def unflatten( + self: ivy.Array, + /, + shape: Union[Tuple[int], ivy.Array, ivy.NativeArray], + dim: Optional[int] = 0, + *, + out: Optional[ivy.Array] = None, + ) -> ivy.Array: + """ivy.Array instance method variant of ivy.unflatten. This method + simply wraps the function, and so the docstring for ivy.unflatten also + applies to this method with minimal changes. + + Parameters + ---------- + self + input array + shape + array indices. Must have an integer data type. + dim + axis over which to unflatten. If `axis` is negative, + the function must determine the axis along which to select values + by counting from the last dimension. + By default, the flattened input array is used. + out + optional output array, for writing the result to. It must + have a shape that the inputs broadcast to. + + Returns + ------- + ret + an array having the same data type as `x`. + The output array must have the same rank + (i.e., number of dimensions) as `x` and + must have the same shape as `x`, + except for the axis specified by `dim` + which is replaced with a tuple specified in `shape`. + + + Examples + -------- + With 'ivy.Array' input: + + >>> x = ivy.array([[1.2, 2.3, 3.4, 4.5], + ... [5.6, 6.7, 7.8, 8.9]]) + >>> dim = 1 + >>> shape = (2, 2) + >>> y = ivy.zeros([2, 2, 2]) + >>> x.unflatten(shape=shape, dim=dim, out=y) + >>> print(y) + ivy.array([[[1.2, 2.3], [3.4, 4.5]], [[5.6, 6.7], [7.8, 8.9]]]) + """ + return ivy.unflatten( + self._data, + shape=shape, + dim=dim, + out=out, + ) + def trim_zeros( self: ivy.Array, /, diff --git a/ivy/data_classes/array/losses.py b/ivy/data_classes/array/losses.py index b11f9d9399e3b..216ef9e4e2322 100644 --- a/ivy/data_classes/array/losses.py +++ b/ivy/data_classes/array/losses.py @@ -50,7 +50,7 @@ def cross_entropy( >>> y = ivy.array([0.25, 0.25, 0.25, 0.25]) >>> z = x.cross_entropy(y) >>> print(z) - ivy.array(1.3862944) + ivy.array(0.34657359) """ return ivy.cross_entropy( self._data, pred, axis=axis, epsilon=epsilon, reduction=reduction, out=out @@ -110,7 +110,7 @@ def binary_cross_entropy( >>> y = ivy.array([0.7, 0.8, 0.2]) >>> z = x.binary_cross_entropy(y) >>> print(z) - ivy.array([0.357, 0.223, 0.223]) + ivy.array(0.26765382) """ return ivy.binary_cross_entropy( self._data, @@ -170,7 +170,7 @@ def sparse_cross_entropy( >>> y = ivy.array([0.7, 0.8, 0.2]) >>> z = x.sparse_cross_entropy(y) >>> print(z) - ivy.array([0.223, 0.223, 0.357]) + ivy.array([0.07438118, 0.07438118, 0.11889165]) """ return ivy.sparse_cross_entropy( self._data, pred, axis=axis, epsilon=epsilon, reduction=reduction, out=out diff --git a/ivy/data_classes/array/manipulation.py b/ivy/data_classes/array/manipulation.py index a090309c39673..231a356ca6be4 100644 --- a/ivy/data_classes/array/manipulation.py +++ b/ivy/data_classes/array/manipulation.py @@ -440,9 +440,9 @@ def stack( def clip( self: ivy.Array, + /, x_min: Optional[Union[Number, ivy.Array, ivy.NativeArray]] = None, x_max: Optional[Union[Number, ivy.Array, ivy.NativeArray]] = None, - /, *, out: Optional[ivy.Array] = None, ) -> ivy.Array: diff --git a/ivy/data_classes/array/statistical.py b/ivy/data_classes/array/statistical.py index 53b309c0a78e6..b07294c52696e 100644 --- a/ivy/data_classes/array/statistical.py +++ b/ivy/data_classes/array/statistical.py @@ -15,6 +15,8 @@ def min( *, axis: Optional[Union[int, Sequence[int]]] = None, keepdims: bool = False, + initial: Optional[Union[int, float, complex]] = None, + where: Optional[ivy.Array] = None, out: Optional[ivy.Array] = None, ) -> ivy.Array: """Calculate the minimum value of the input array ``x``. @@ -36,6 +38,11 @@ def min( array (see :ref:`broadcasting`). Otherwise, if ``False``, the reduced axes (dimensions) must not be included in the result. Default: ``False``. + initial + The maximum value of an output element. + Must be present to allow computation on empty slice. + where + Elements to compare for minimum out optional output array, for writing the result to. @@ -68,7 +75,14 @@ def min( >>> print(y) ivy.array(0.1) """ - return ivy.min(self._data, axis=axis, keepdims=keepdims, out=out) + return ivy.min( + self._data, + axis=axis, + keepdims=keepdims, + initial=initial, + where=where, + out=out, + ) def max( self: ivy.Array, diff --git a/ivy/data_classes/container/base.py b/ivy/data_classes/container/base.py index a265766f69aa2..bb004b709a37f 100644 --- a/ivy/data_classes/container/base.py +++ b/ivy/data_classes/container/base.py @@ -1155,7 +1155,7 @@ def cont_from_disk_as_hdf5( ), ) container_dict = {} - if type(h5_obj_or_filepath) is str: + if isinstance(h5_obj_or_filepath, str): h5_obj = h5py.File(h5_obj_or_filepath, "r") else: h5_obj = h5_obj_or_filepath @@ -1238,7 +1238,7 @@ def h5_file_size(h5_obj_or_filepath): "the size of hdf5 files." ), ) - if type(h5_obj_or_filepath) is str: + if isinstance(h5_obj_or_filepath, str): h5_obj = h5py.File(h5_obj_or_filepath, "r") else: h5_obj = h5_obj_or_filepath @@ -1280,7 +1280,7 @@ def shuffle_h5_file(h5_obj_or_filepath, seed_value=0): ) if seed_value is None: seed_value = random.randint(0, 1000) - if type(h5_obj_or_filepath) is str: + if isinstance(h5_obj_or_filepath, str): h5_obj = h5py.File(h5_obj_or_filepath, "a") else: h5_obj = h5_obj_or_filepath @@ -1367,15 +1367,17 @@ def cont_flatten_key_chain( if below_depth and num_keys > below_depth: pre_keys = flat_keys[0:below_depth] del flat_keys[0:below_depth] - return "/".join([ - k - for k in [ - "/".join(pre_keys), - replacement.join(flat_keys), - "/".join(post_keys), + return "/".join( + [ + k + for k in [ + "/".join(pre_keys), + replacement.join(flat_keys), + "/".join(post_keys), + ] + if k ] - if k - ]) + ) @staticmethod def cont_trim_key(key, max_length): @@ -1697,16 +1699,18 @@ def cont_all_true( Boolean, whether all entries are boolean True. """ return bool( - np.prod([ - v - for k, v in self.cont_as_bools( - assert_is_bool, - key_chains, - to_apply, - prune_unapplied, - map_sequences, - ).cont_to_iterator() - ]) + np.prod( + [ + v + for k, v in self.cont_as_bools( + assert_is_bool, + key_chains, + to_apply, + prune_unapplied, + map_sequences, + ).cont_to_iterator() + ] + ) ) def cont_all_false( @@ -1742,16 +1746,18 @@ def cont_all_false( Boolean, whether all entries are boolean False. """ return not bool( - np.sum([ - v - for k, v in self.cont_as_bools( - assert_is_bool, - key_chains, - to_apply, - prune_unapplied, - map_sequences, - ).cont_to_iterator() - ]) + np.sum( + [ + v + for k, v in self.cont_as_bools( + assert_is_bool, + key_chains, + to_apply, + prune_unapplied, + map_sequences, + ).cont_to_iterator() + ] + ) ) def cont_slice_via_key(self, slice_key): @@ -1843,11 +1849,15 @@ def cont_unstack_conts(self, axis, keepdims=False, dim_size=None): if keepdims: # noinspection PyTypeChecker return [ - self[( - slice(i, i + 1, 1) - if axis == 0 - else tuple([slice(None, None, None)] * axis + [slice(i, i + 1, 1)]) - )] + self[ + ( + slice(i, i + 1, 1) + if axis == 0 + else tuple( + [slice(None, None, None)] * axis + [slice(i, i + 1, 1)] + ) + ) + ] for i in range(dim_size) ] # noinspection PyTypeChecker @@ -1997,7 +2007,7 @@ def cont_to_disk_as_hdf5( "containers to disk as hdf5 files." ), ) - if type(h5_obj_or_filepath) is str: + if isinstance(h5_obj_or_filepath, str): h5_obj = h5py.File(h5_obj_or_filepath, mode) else: h5_obj = h5_obj_or_filepath @@ -3690,10 +3700,12 @@ def _pre_pad_alpha_line(str_in): padded = True return "\\n" + indent_str + indented_key_str + str_in - leading_str_to_keep = ", ".join([ - _pre_pad_alpha_line(s) if s[0].isalpha() and i != 0 else s - for i, s in enumerate(leading_str_to_keep.split(", ")) - ]) + leading_str_to_keep = ", ".join( + [ + _pre_pad_alpha_line(s) if s[0].isalpha() and i != 0 else s + for i, s in enumerate(leading_str_to_keep.split(", ")) + ] + ) local_indent_str = "" if padded else indent_str leading_str = leading_str_to_keep.split("\\n")[-1].replace('"', "") remaining_str = array_str_in_split[1] @@ -3710,23 +3722,25 @@ def _pre_pad_alpha_line(str_in): uniform_indent_wo_overflow_list = list( filter(None, uniform_indent_wo_overflow.split("\\n")) ) - uniform_indent = "\n".join([ - ( - local_indent_str + extra_indent + " " + s - if ( - s[0].isnumeric() - or s[0] == "-" - or s[0:3] == "..." - or max(ss in s[0:6] for ss in ["nan, ", "inf, "]) - ) - else ( - indent_str + indented_key_str + s - if (not s[0].isspace() and s[0] != '"') - else s + uniform_indent = "\n".join( + [ + ( + local_indent_str + extra_indent + " " + s + if ( + s[0].isnumeric() + or s[0] == "-" + or s[0:3] == "..." + or max(ss in s[0:6] for ss in ["nan, ", "inf, "]) + ) + else ( + indent_str + indented_key_str + s + if (not s[0].isspace() and s[0] != '"') + else s + ) ) - ) - for s in uniform_indent_wo_overflow_list - ]) + for s in uniform_indent_wo_overflow_list + ] + ) indented = uniform_indent # 10 dimensions is a sensible upper bound for the number in a single array for i in range(2, 10): @@ -3832,14 +3846,16 @@ def _align_arrays(str_in): def _add_newline(str_in): str_in_split = str_in.split("\n") str_split_size = len(str_in_split) - return "\n".join([ - ( - ("\n" * self._print_line_spacing + ss) - if i == (str_split_size - 1) - else ss - ) - for i, ss in enumerate(str_in_split) - ]) + return "\n".join( + [ + ( + ("\n" * self._print_line_spacing + ss) + if i == (str_split_size - 1) + else ss + ) + for i, ss in enumerate(str_in_split) + ] + ) json_dumped_str = '":'.join( [_add_newline(s) for s in json_dumped_str.split('":')] @@ -3850,9 +3866,12 @@ def _add_newline(str_in): json_dumped_str = ( json_dumped_str_split[0] + ", " - + ", ".join([ - "'".join(ss.split("'")[1:]) for ss in json_dumped_str_split[1:] - ]) + + ", ".join( + [ + "'".join(ss.split("'")[1:]) + for ss in json_dumped_str_split[1:] + ] + ) ) json_dumped_str = ( json_dumped_str.replace(":shape", ", shape") @@ -3863,24 +3882,26 @@ def _add_newline(str_in): # color keys json_dumped_str_split = json_dumped_str.split('":') split_size = len(json_dumped_str_split) - json_dumped_str = '":'.join([ - ( - ' "'.join( - sub_str.split(' "')[:-1] - + [ - termcolor.colored( - ivy.Container.cont_trim_key( - sub_str.split(' "')[-1], self._key_length_limit - ), - self._default_key_color, - ) - ] + json_dumped_str = '":'.join( + [ + ( + ' "'.join( + sub_str.split(' "')[:-1] + + [ + termcolor.colored( + ivy.Container.cont_trim_key( + sub_str.split(' "')[-1], self._key_length_limit + ), + self._default_key_color, + ) + ] + ) + if i < split_size - 1 + else sub_str ) - if i < split_size - 1 - else sub_str - ) - for i, sub_str in enumerate(json_dumped_str_split) - ]) + for i, sub_str in enumerate(json_dumped_str_split) + ] + ) # remove quotation marks, shape tuple, and color other elements of the dict ret = ( json_dumped_str.replace('"', "") diff --git a/ivy/data_classes/container/experimental/activations.py b/ivy/data_classes/container/experimental/activations.py index e42c7d270d00c..02f174d8d9a49 100644 --- a/ivy/data_classes/container/experimental/activations.py +++ b/ivy/data_classes/container/experimental/activations.py @@ -968,10 +968,10 @@ def _static_hardtanh( Examples -------- >>> x = x = ivy.Container(a=ivy.array([0.39, -2.0]), b=ivy.array([2., -0.2])) - >>> y = ivy.Container.static_hardtanh(x) + >>> y = ivy.Container._static_hardtanh(x) >>> print(y) { - a: ivy.array([0.39, -1.]), + a: ivy.array([0.3899, -1.]), b: ivy.array([1., -0.2]) } """ @@ -1033,11 +1033,11 @@ def hardtanh( Examples -------- - >>> x = x = ivy.Container(a=ivy.array([0.39, -2.0]), b=ivy.array([2., -0.2])) - >>> y = ivy.Container.static_hardtanh(x) + >>> x = ivy.Container(a=ivy.array([0.39, -2.0]), b=ivy.array([2., -0.2])) + >>> y = ivy.Container.hardtanh(x) >>> print(y) { - a: ivy.array([0.39, -1.]), + a: ivy.array([0.389999, -1.]), b: ivy.array([1., -0.2]) } """ @@ -1820,8 +1820,7 @@ def hardshrink( Examples -------- - >>> import ivy.numpy as np - >>> x = ivy.Container(a=np.array([1., -2.]), b=np.array([0.4, -0.2])) + >>> x = ivy.Container(a=ivy.array([1., -2.]), b=ivy.array([0.4, -0.2])) >>> y = ivy.Container.hardshrink(x) >>> print(y) { @@ -1838,3 +1837,117 @@ def hardshrink( map_sequences=map_sequences, out=out, ) + + @staticmethod + def _static_hardsilu( + x: Union[ivy.Array, ivy.NativeArray, ivy.Container], + /, + *, + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + out: Optional[ivy.Container] = None, + ) -> ivy.Container: + """ivy.Container static method which acts as a wrapper for + ivy.hardsilu. + + Parameters + ---------- + x + input container + key_chains + The keychains to apply or not apply the method to. Default is ``None``. + to_apply + If True, the method will be applied to key_chains, otherwise key_chains + will be skipped. Default is ``True``. + prune_unapplied + Whether to prune key_chains for which the function was not applied. + Default is ``False``. + map_sequences + Whether to also map method to sequences (lists, tuples). + Default is ``False``. + out + optional output container, for writing the result to. It must have a shape + that the inputs broadcast to. + + Returns + ------- + a container containing the output of the hardsilu/hardswish function applied + to each element in ``x``. + + Examples + -------- + >>> x = ivy.Container(a=ivy.array([-0.5, -1, 0]), b=ivy.array([0.5, 1., 2])) + >>> y = ivy.Container._static_hardsilu(x) + >>> print(y) + { + a: ivy.array([-0.20833333, -0.33333334, 0.]), + b: ivy.array([0.29166666, 0.66666669, 1.66666663]) + } + """ + return ContainerBase.cont_multi_map_in_function( + "hardsilu", + x, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + out=out, + ) + + def hardsilu( + self, + /, + *, + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + out: Optional[ivy.Container] = None, + ) -> ivy.Container: + """ivy.Container instance method which acts as a wrapper for + ivy.hardsilu. + + Parameters + ---------- + self + input container + key_chains + The keychains to apply or not apply the method to. Default is ``None``. + to_apply + If True, the method will be applied to key_chains, otherwise key_chains + will be skipped. Default is ``True``. + prune_unapplied + Whether to prune key_chains for which the function was not applied. + Default is ``False``. + map_sequences + Whether to also map method to sequences (lists, tuples). + Default is ``False``. + out + optional output container, for writing the result to. It must have a shape + that the inputs broadcast to. + + Returns + ------- + a container containing the output of the hardsilu/hardswish function applied + to each element in the input container. + + Examples + -------- + >>> x = ivy.Container(a=ivy.array([-0.5, -1, 0]), b=ivy.array([0.5, 1., 2])) + >>> y = x.hardsilu() + >>> print(y) + { + a: ivy.array([-0.20833333, -0.33333334, 0.]), + b: ivy.array([0.29166666, 0.66666669, 1.66666663]) + } + """ + return self._static_hardsilu( + self, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + out=out, + ) diff --git a/ivy/data_classes/container/experimental/elementwise.py b/ivy/data_classes/container/experimental/elementwise.py index 939c32874fc50..402e0fa1fac1e 100644 --- a/ivy/data_classes/container/experimental/elementwise.py +++ b/ivy/data_classes/container/experimental/elementwise.py @@ -3491,3 +3491,94 @@ def erfc( } """ return self.static_erfc(self, out=out) + + @staticmethod + def static_erfinv( + x: Union[ivy.Array, ivy.NativeArray, ivy.Container], + /, + *, + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + out: Optional[ivy.Container] = None, + ) -> ivy.Container: + """ivy.Container static method variant of ivy.erfinv. This method + simply wraps the function, and so the docstring for ivy.erfinv also + applies to this method with minimal changes. + + Parameters + ---------- + x + The container whose array contains real or complex valued argument. + key_chains + The key-chains to apply or not apply the method to. Default is ``None``. + to_apply + If True, the method will be applied to key_chains, otherwise key_chains + will be skipped. Default is ``True``. + prune_unapplied + Whether to prune key_chains for which the function was not applied. + Default is ``False``. + map_sequences + Whether to also map method to sequences (lists, tuples). + Default is ``False``. + out + optional output container, for writing the result to. + + Returns + ------- + ret + container with values of the inverse error function. + + Examples + -------- + >>> x = ivy.Container(a=ivy.array([1., 2.]), b=ivy.array([-3., -4.])) + >>> ivy.Container.static_erfinv(x) + { + a: ivy.array([0.15729921, 0.00467773]), + b: ivy.array([1.99997795, 2.]) + } + """ + return ContainerBase.cont_multi_map_in_function( + "erfinv", + x, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + out=out, + ) + + def erfinv( + self: ivy.Container, + /, + *, + out: Optional[ivy.Container] = None, + ) -> ivy.Container: + """ivy.Container instance method variant of ivy.erfinv. This method + simply wraps the function, and so the docstring for ivy.erfinv also + applies to this method with minimal changes. + + Parameters + ---------- + self + The container whose array contains real or complex valued argument. + out + optional output container, for writing the result to. + + Returns + ------- + ret + container with values of the inverse error function. + + Examples + -------- + With one :class:`ivy.Container` input: + >>> x = ivy.Container(a=ivy.array([1., 2., 3.]), b=ivy.array([-1., -2., -3.])) + >>> x.erfinv() + { + a: ivy.array([1.57299206e-01, 4.67773480e-03, 2.20904985e-05]), + b: ivy.array([1.84270084, 1.99532223, 1.99997795]) + } + """ + return self.static_erfinv(self, out=out) diff --git a/ivy/data_classes/container/experimental/layers.py b/ivy/data_classes/container/experimental/layers.py index 9e994c2d67b9a..d6d53e4b58490 100644 --- a/ivy/data_classes/container/experimental/layers.py +++ b/ivy/data_classes/container/experimental/layers.py @@ -2014,6 +2014,44 @@ def adaptive_max_pool2d( map_sequences=map_sequences, ) + @staticmethod + def static_adaptive_max_pool3d( + input: Union[ivy.Array, ivy.NativeArray, ivy.Container], + output_size: Union[Sequence[int], int, ivy.Container], + *, + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + ) -> ivy.Container: + return ContainerBase.cont_multi_map_in_function( + "adaptive_max_pool3d", + input, + output_size, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + ) + + def adaptive_max_pool3d( + self: ivy.Container, + output_size: Union[int, ivy.Container], + *, + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + ) -> ivy.Container: + return self.static_adaptive_max_pool3d( + self, + output_size, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + ) + @staticmethod def static_ifftn( x: ivy.Container, @@ -2896,4 +2934,78 @@ def adaptive_max_pool1d( to_apply=to_apply, prune_unapplied=prune_unapplied, map_sequences=map_sequences, + + def static_rnn( + step_function: Callable, + inputs: ivy.Array, + initial_states: List[ivy.Array], + /, + *, + go_backwards: bool = False, + mask: Optional[ivy.Array] = None, + constants: Optional[ivy.Array] = None, + unroll: bool = False, + input_length: Optional[int] = None, + time_major: bool = False, + zero_output_for_mask: bool = False, + return_all_outputs: bool = True, + ) -> ivy.Container: + """ivy.Container static method variant of ivy.rnn. + + Parameters + ---------- + step_function + RNN step function. + inputs + Array of temporal data of shape (samples, time, ...). + initial_states + Array with shape (samples, state_size). + go_backwards + If True, do the iteration over the time dimension in reverse order and + return the reversed sequence. + mask + Binary array with shape (samples, time, 1), with a zero for every element + that is masked. + constants + List of constant values passed at each step. + unroll + Whether to use a pythonic while loop or ivy.while_loop + input_length + An integer or 1-D array, depending on whether the time dimension is + fixed-length. In case of variable length input, it is used for masking in + case there is no mask specified. + time_major + If True, the inputs and outputs will be in shape (timesteps, batch, ...) + whereas in the False case, it will be (batch, timesteps, ...). + zero_output_for_mask + If True, the otput for masked timestep will be zeros, whereas in the False + case, output from previous timestep is returned + return_all_outputs + If True, return the recurrent outputs for all timesteps in the sequence. If + False, only return the output for the last timestep. + + Returns + ------- + ret + A tuple of + - the latest output of the rnn of shape (samples, ...) + - the output of the rnn of shape (samples, time, ...) if + return_all_outputs=True else (samples, 1, ...) + - list of tensors, latest states returned by the step funciton, of shape + (samples, ...) + """ + return ContainerBase.cont_multi_map_in_function( + "rnn", + step_function, + inputs, + initial_states, + go_backwards=go_backwards, + mask=mask, + constants=constants, + unroll=unroll, + input_length=input_length, + time_major=time_major, + zero_output_for_mask=zero_output_for_mask, + return_all_outputs=return_all_outputs, + ) diff --git a/ivy/data_classes/container/experimental/losses.py b/ivy/data_classes/container/experimental/losses.py index 799c44adfcb25..6247eb3a3dcf7 100644 --- a/ivy/data_classes/container/experimental/losses.py +++ b/ivy/data_classes/container/experimental/losses.py @@ -143,7 +143,7 @@ def l1_loss( >>> z = x.l1_loss(y) >>> print(z) { - a: ivy.array(1.), + a: ivy.array(0.), b: ivy.array(0.) } """ @@ -314,8 +314,8 @@ def log_poisson_loss( >>> z = x.log_poisson_loss(y) >>> print(z) { - a: ivy.array(1.), - b: ivy.array(0.) + a: ivy.array(3.3890561), + b: ivy.array(123.413159) } """ return self._static_log_poisson_loss( @@ -478,12 +478,12 @@ def smooth_l1_loss( -------- >>> x = ivy.Container(a=ivy.array([1, 0, 2]), b=ivy.array([3, 2, 1])) >>> y = ivy.Container(a=ivy.array([0.6, 0.2, 0.3]), - b=ivy.array([0.8, 0.2, 0.2])) + ... b=ivy.array([0.8, 0.2, 0.2])) >>> z = x.smooth_l1_loss(y) >>> print(z) { - a: ivy.array(0.9), - b: ivy.array(0.25) + a: ivy.array(0.43333333), + b: ivy.array(1.10666666) } """ return self._static_smooth_l1_loss( @@ -1089,3 +1089,186 @@ def poisson_nll_loss( prune_unapplied=prune_unapplied, map_sequences=map_sequences, ) + + @staticmethod + def _static_hinge_embedding_loss( + input: Union[ivy.Container, ivy.Array, ivy.NativeArray], + target: Union[ivy.Container, ivy.Array, ivy.NativeArray], + *, + margin: [Union[float, ivy.Container]] = 1.0, + reduction: [Union[str, ivy.Container]] = "mean", + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + ) -> ivy.Container: + r"""ivy.Container static method variant of ivy.hinge_embedding_loss. + This method simplywraps the function, and so the docstring for + ivy.hinge_embedding_loss also applies to this method with minimal + changes. + + Parameters + ---------- + input + input array or container containing input labels. + target + input array or container containing the target labels. + margin + Sets the hyperparameter margin. Determines the necessary input size + for hinge_embedding_loss calculations when label is -1. Inputs smaller + than the margin are minimized with hinge_embedding_loss. + Default is 1.0. + reduction + Specifies how to aggregate the loss across the batch. Options are: + - ``'none'``: Returns the unreduced loss. + - ``'mean'``: Returns the mean loss. + - ``'sum'``: Returns the summed loss. + Default is ``'mean'``. + key_chains + The key-chains to apply or not apply the method to. Default is ``None``. + to_apply + If input, the method will be applied to key_chains, otherwise key_chains + will be skipped. Default is ``input``. + prune_unapplied + Whether to prune key_chains for which the function was not applied. + Default is ``False``. + map_sequences + Whether to also map method to sequences (lists, tuples). + Default is ``False``. + + Shape + ----- + - Input: :math:`(*)` where :math:`*` means, any number of dimensions. \ + The sum operation operates over all the elements. + - Target: :math:`(*)`, same shape as the input + - Output: scalar. If :attr:`reduction` is ``'none'``, + then same shape as the input + + Returns + ------- + ret + Hinge embedding loss calculated from the input and label, + shaped based on the reduction method. + + Examples + -------- + With :class:`ivy.Container` inputs: + + >>> x = ivy.Container(a=ivy.array([[1, 0, 2]], dtype=ivy.float32), + ... b=ivy.array([[-1, 1, 1]], dtype=ivy.float32)) + >>> y = ivy.Container(a=ivy.array([[0.6, 0.2, 0.3]], dtype=ivy.float32), + ... b=ivy.array([[1, 1, 1]], dtype=ivy.float32)) + >>> z = ivy.Container._static_hinge_embedding_loss(x, y, reduction="none") + >>> z + { + a: ivy.array([[0., 0., 0.]]), + b: ivy.array([[-1., 1., 1.]]) + } + + With a mix of :class:`ivy.Array` and :class:`ivy.Container` inputs: + + >>> x = ivy.array([[10, 20, 32]], dtype=ivy.float32) + >>> y = ivy.Container(a=ivy.array([[-1, -1, -1]], dtype=ivy.float32), + ... b=ivy.array([[1, 1, 1]], dtype=ivy.float32)) + >>> z = ivy.Container._static_hinge_embedding_loss(x, y, + ... reduction="sum", margin=2.0) + >>> z + { + a: ivy.array(0.), + b: ivy.array(62.) + } + """ + return ContainerBase.cont_multi_map_in_function( + "hinge_embedding_loss", + input, + target, + margin=margin, + reduction=reduction, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + ) + + def hinge_embedding_loss( + self: Union[ivy.Container, ivy.Array, ivy.NativeArray], + target: Union[ivy.Container, ivy.Array, ivy.NativeArray], + *, + margin: [Union[float, ivy.Container]] = 1.0, + reduction: [Union[str, ivy.Container]] = "mean", + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + ) -> ivy.Container: + r"""ivy.Container instance method variant of ivy.hinge_embedding_loss. + This method simply wraps the function, and so the docstring for + ivy.hinge_embedding_loss also applies to this method with minimal + changes. + + Parameters + ---------- + input + input array or container containing input labels. + target + input array or container containing the target labels. + margin + Sets the hyperparameter margin. Determines the necessary input size + for hinge_embedding_loss calculations when label is -1. Inputs smaller + than the margin are minimized with hinge_embedding_loss. + Default is 1.0. + reduction + Specifies how to aggregate the loss across the batch. Options are: + - ``'none'``: Returns the unreduced loss. + - ``'mean'``: Returns the mean loss. + - ``'sum'``: Returns the summed loss. + Default is ``'mean'``. + key_chains + The key-chains to apply or not apply the method to. Default is ``None``. + to_apply + If input, the method will be applied to key_chains, otherwise key_chains + will be skipped. Default is ``input``. + prune_unapplied + Whether to prune key_chains for which the function was not applied. + Default is ``False``. + map_sequences + Whether to also map method to sequences (lists, tuples). + Default is ``False``. + + Shape + ----- + - Input: :math:`(*)` where :math:`*` means, any number of dimensions. \ + The sum operation operates over all the elements. + - Target: :math:`(*)`, same shape as the input + - Output: scalar. If :attr:`reduction` is ``'none'``, + then same shape as the input + + Returns + ------- + ret + Hinge embedding loss calculated from the input and label, + shaped based on the reduction method. + + + Examples + -------- + >>> x = ivy.Container(a=ivy.array([[1, 0, 2]], dtype=ivy.float32), + ... b=ivy.array([[3, 2, 1]], dtype=ivy.float32)) + >>> y = ivy.Container(a=ivy.array([[-1, -1, -1]], dtype=ivy.float32), + ... b=ivy.array([[1, 1, 1]], dtype=ivy.float32)) + >>> x.hinge_embedding_loss(y, reduction="none", margin=0.5) + { + a: ivy.array([[0., 0.5, 0.]]), + b: ivy.array([[3., 2., 1.]]) + } + """ + return self._static_hinge_embedding_loss( + self, + target, + margin=margin, + reduction=reduction, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + ) diff --git a/ivy/data_classes/container/experimental/manipulation.py b/ivy/data_classes/container/experimental/manipulation.py index 20e72671746e1..0c54a775d5a43 100644 --- a/ivy/data_classes/container/experimental/manipulation.py +++ b/ivy/data_classes/container/experimental/manipulation.py @@ -4065,6 +4065,180 @@ def trim_zeros( """ return self._static_trim_zeros(self, trim=trim) + @staticmethod + def _static_unflatten( + x: Union[int, ivy.Array, ivy.NativeArray, ivy.Container], + /, + shape: Union[Tuple[int], ivy.Array, ivy.NativeArray, ivy.Container], + dim: Optional[Union[int, ivy.Container]] = 0, + *, + out: Optional[Union[ivy.Array, ivy.Container]] = None, + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + ) -> ivy.Container: + """ivy.Container static method variant of ivy.unflatten. This method + simply wraps the function, and so the docstring for ivy.unflatten also + applies to this method with minimal changes. + + Parameters + ---------- + x + input array + shape + array indices. Must have an integer data type. + dim + axis over which to select values. If `axis` is negative, + the function must determine the axis along which to select values + by counting from the last dimension. + By default, the flattened input array is used. + out + optional output array, for writing the result to. It must + have a shape that the inputs broadcast to. + key_chains + The key-chains to apply or not apply the method to. + Default is ``None``. + to_apply + If True, the method will be applied to key_chains, + otherwise key_chains will be skipped. Default is ``True``. + prune_unapplied + Whether to prune key_chains for which the function was + not applied. Default is ``False``. + map_sequences + Whether to also map method to sequences (lists, tuples). + Default is ``False``. + + Returns + ------- + ret + an array having the same data type as `x`. + The output array must have the same rank + (i.e., number of dimensions) as `x` and + must have the same shape as `x`, + except for the axis specified by `axis` + whose size must equal the number of elements in `indices`. + + + Examples + -------- + With 'ivy.Container' input: + + >>> x = ivy.Container(a = ivy.array([[True, False, False, True], + [False, True, False, True]])), + ... b = ivy.array([[1.2, 2.3, 3.4, 4.5], + [5.6, 6.7, 7.8, 8.9]]), + ... c = ivy.array([[1, 2, 3, 4], + [5, 6, 7, 8]])) + >>> dim = 1 + >>> shape = (2, 2) + >>> y = ivy.Container._static_unflatten(x, shape=shape, dim=dim) + >>> print(y) + { + a: ivy.array([[[True, False], [False, True]], + [[False, True], [False, True]]]) + b: ivy.array([[[1.2, 2.3], [3.4, 4.5]], [[5.6, 6.7], [7.8, 8.9]]]) + c: ivy.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) + } + """ + return ContainerBase.cont_multi_map_in_function( + "unflatten", + x, + shape=shape, + dim=dim, + out=out, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + ) + + def unflatten( + self: ivy.Container, + /, + shape: Union[Tuple[int], ivy.Array, ivy.NativeArray, ivy.Container], + dim: Optional[Union[int, ivy.Container]] = 0, + *, + out: Optional[Union[ivy.Array, ivy.Container]] = None, + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + ) -> ivy.Container: + """ivy.Container instance method variant of ivy.unflatten. This method + simply wraps the function, and so the docstring for ivy.unflatten also + applies to this method with minimal changes. + + Parameters + ---------- + self + input array + shape + array indices. Must have an integer data type. + dim + axis over which to unflatten. If `axis` is negative, + the function must determine the axis along which to select values + by counting from the last dimension. + By default, the flattened input array is used. + out + optional output array, for writing the result to. It must + have a shape that the inputs broadcast to. + key_chains + The key-chains to apply or not apply the method to. + Default is ``None``. + to_apply + If True, the method will be applied to key_chains, + otherwise key_chains will be skipped. Default is ``True``. + prune_unapplied + Whether to prune key_chains for which the function was + not applied. Default is ``False``. + map_sequences + Whether to also map method to sequences (lists, tuples). + Default is ``False``. + + Returns + ------- + ret + an array having the same data type as `x`. + The output array must have the same rank + (i.e., number of dimensions) as `x` and + must have the same shape as `x`, + except for the axis specified by `dim` + which is replaced with a tuple specified in `shape`. + + + Examples + -------- + With 'ivy.Container' input: + + >>> x = ivy.Container(a = ivy.array([[True, False, False, True], + ... [False, True, False, True]]), + ... b = ivy.array([[1.2, 2.3, 3.4, 4.5], + ... [5.6, 6.7, 7.8, 8.9]]), + ... c = ivy.array([[1, 2, 3, 4], + ... [5, 6, 7, 8]])) + >>> dim = 1 + >>> shape = (2, 2) + >>> y = x.unflatten(shape=shape, dim=dim) + >>> print(y) + { + a: ivy.array([[[True, False], [False, True]], + [[False, True], [False, True]]]), + b: ivy.array([[[1.2, 2.3], [3.4, 4.5]], [[5.6, 6.7], [7.8, 8.9]]]), + c: ivy.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) + } + """ + return self._static_unflatten( + self, + shape=shape, + dim=dim, + out=out, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + ) + def concat_from_sequence( self: ivy.Container, @@ -4130,11 +4304,11 @@ def concat_from_sequence( >>> print(z) { 'a': ivy.array([[[0, 1], - [3, 2]], - [[2, 3], - [1, 0]]]), + [3, 2]], + [[2, 3], + [1, 0]]]), 'b': ivy.array([[[4, 5], - [1, 0]]]) + [1, 0]]]) } """ new_input_sequence = ( diff --git a/ivy/data_classes/container/experimental/statistical.py b/ivy/data_classes/container/experimental/statistical.py index 09c0e616384b1..8c88175c9a543 100644 --- a/ivy/data_classes/container/experimental/statistical.py +++ b/ivy/data_classes/container/experimental/statistical.py @@ -1338,6 +1338,35 @@ def igamma( """ return self.static_igamma(self, x=x, out=out) + @staticmethod + def static_lgamma( + a: Union[ivy.Container, ivy.Array, ivy.NativeArray], + /, + *, + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + out: Optional[ivy.Container] = None, + ) -> ivy.Container: + return ContainerBase.cont_multi_map_in_function( + "lgamma", + a, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + out=out, + ) + + def lgamma( + self: ivy.Container, + /, + *, + out: Optional[ivy.Container] = None, + ) -> ivy.Container: + return self.static_lgamma(self, out=out) + @staticmethod def static_cov( x1: Union[ivy.Array, ivy.NativeArray, ivy.Container], diff --git a/ivy/data_classes/container/losses.py b/ivy/data_classes/container/losses.py index 60dff4e8e4d2a..52c31b3b7f175 100644 --- a/ivy/data_classes/container/losses.py +++ b/ivy/data_classes/container/losses.py @@ -157,8 +157,8 @@ def cross_entropy( >>> z = x.cross_entropy(y) >>> print(z) { - a:ivy.array(0.5108256), - b:ivy.array(1.609438) + a: ivy.array(0.17027519), + b: ivy.array(0.53647931) } """ return self._static_cross_entropy( @@ -348,8 +348,8 @@ def binary_cross_entropy( >>> z = x.binary_cross_entropy(y) >>> print(z) { - a: ivy.array([0.511, 0.223, 0.357]), - b: ivy.array([1.61, 0.223, 1.61]) + a: ivy.array(0.36354783), + b: ivy.array(1.14733934) } """ return self._static_binary_cross_entropy( @@ -517,8 +517,8 @@ def sparse_cross_entropy( >>> z = x.sparse_cross_entropy(y) >>> print(z) { - a: ivy.array([1.61, 0.511, 0.511]), - b: ivy.array([0.223, 0.223, 1.61]) + a: ivy.array([0.53647929, 0.1702752, 0.1702752]), + b: ivy.array([0.07438118, 0.07438118, 0.53647929]) } """ return self._static_sparse_cross_entropy( diff --git a/ivy/data_classes/container/manipulation.py b/ivy/data_classes/container/manipulation.py index 94e1ba3658401..2b22319bacb04 100644 --- a/ivy/data_classes/container/manipulation.py +++ b/ivy/data_classes/container/manipulation.py @@ -2287,13 +2287,13 @@ def _static_clip( def clip( self: ivy.Container, + /, x_min: Optional[ Union[Number, ivy.Array, ivy.NativeArray, ivy.Container] ] = None, x_max: Optional[ Union[Number, ivy.Array, ivy.NativeArray, ivy.Container] ] = None, - /, *, key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, to_apply: Union[bool, ivy.Container] = True, diff --git a/ivy/data_classes/container/set.py b/ivy/data_classes/container/set.py index 930560637b588..e388499e07c52 100644 --- a/ivy/data_classes/container/set.py +++ b/ivy/data_classes/container/set.py @@ -511,6 +511,18 @@ def unique_inverse( a: ivy.array([1, 3, 0, 2, 4, 1]), b: ivy.array([5, 4, 2, 3, 4, 1, 0]) }] + + >>> x = ivy.Container(a=ivy.array([1., 4., 3. , 5. , 3. , 7.]), + ... b=ivy.array([3, 2, 6, 3, 7, 4, 9])) + >>> y = ivy.ivy.unique_inverse(x) + >>> print(y) + [{ + a: ivy.array([1., 3., 4., 5., 7.]), + b: ivy.array([2, 3, 4, 6, 7, 9]) + }, { + a: ivy.array([0, 2, 1, 3, 1, 4]), + b: ivy.array([1, 0, 3, 1, 4, 2, 5]) + }] """ return self._static_unique_inverse( self, diff --git a/ivy/data_classes/container/statistical.py b/ivy/data_classes/container/statistical.py index 77ccb6ac0fd23..26db9e83fab4b 100644 --- a/ivy/data_classes/container/statistical.py +++ b/ivy/data_classes/container/statistical.py @@ -9,12 +9,101 @@ class _ContainerWithStatistical(ContainerBase): + @staticmethod + def _static_min( + x: ivy.Container, + /, + *, + axis: Optional[Union[int, Sequence[int], ivy.Container]] = None, + keepdims: Union[bool, ivy.Container] = False, + initial: Optional[Union[int, float, complex, ivy.Container]] = None, + where: Optional[Union[ivy.Array, ivy.Container]] = None, + key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, + to_apply: Union[bool, ivy.Container] = True, + prune_unapplied: Union[bool, ivy.Container] = False, + map_sequences: Union[bool, ivy.Container] = False, + out: Optional[ivy.Container] = None, + ): + """ivy.Container static method variant of ivy.min. This method simply + wraps the function, and so the docstring for ivy.min also applies to + this method with minimal changes. + + Parameters + ---------- + self + Input container. Should have a real-valued data type. + axis + axis or axes along which minimum values must be computed. + By default, the minimum value must be computed over the + entire array. If a tuple of integers, minimum values must + be computed over multiple axes. Default: ``None``. + keepdims + optional boolean, if ``True``, the reduced axes + (dimensions) must be included in the result as + singleton dimensions, and, accordingly, the result + must be compatible with the input array + (see :ref:`broadcasting`). Otherwise, if ``False``, the + reduced axes (dimensions) must not be included in the + result. Default: ``False``. + initial + The maximum value of an output element. + Must be present to allow computation on empty slice. + where + Elements to compare for minimum + out + optional output array, for writing the result to. + + Returns + ------- + ret + if the minimum value was computed over the entire array, + a zero-dimensional array containing the minimum value; + otherwise, a non-zero-dimensional array containing the + minimum values. The returned array must have the same data type + as ``x``. + + Examples + -------- + With :class:`ivy.Container` input: + >> > x = ivy.Container(a=ivy.array([1, 2, 3]), \ + b=ivy.array([2, 3, 4])) + >> > z = x.min() + >> > print(z) + { + a: ivy.array(1), + b: ivy.array(2) + } + >>> x = ivy.Container(a=ivy.array([[1, 2, 3],[-1,0,2]]), + ... b=ivy.array([[2, 3, 4], [0, 1, 2]])) + >>> z = x.min(axis=1) + >>> print(z) + { + a:ivy.array([1,-1]), + b:ivy.array([2,0]) + } + """ + return ContainerBase.cont_multi_map_in_function( + "min", + x, + axis=axis, + keepdims=keepdims, + initial=initial, + where=where, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, + out=out, + ) + def min( self: ivy.Container, /, *, axis: Optional[Union[int, Sequence[int], ivy.Container]] = None, keepdims: Union[bool, ivy.Container] = False, + initial: Optional[Union[int, float, complex, ivy.Container]] = None, + where: Optional[Union[ivy.Array, ivy.Container]] = None, key_chains: Optional[Union[List[str], Dict[str, str], ivy.Container]] = None, to_apply: Union[bool, ivy.Container] = True, prune_unapplied: Union[bool, ivy.Container] = False, @@ -42,6 +131,11 @@ def min( (see :ref:`broadcasting`). Otherwise, if ``False``, the reduced axes (dimensions) must not be included in the result. Default: ``False``. + initial + The maximum value of an output element. + Must be present to allow computation on empty slice. + where + Elements to compare for minimum out optional output array, for writing the result to. @@ -76,18 +170,16 @@ def min( b:ivy.array([2,0]) } """ - return self.cont_handle_inplace( - self.cont_map( - lambda x_, _: ( - ivy.min(x_, axis=axis, keepdims=keepdims) - if ivy.is_array(x_) - else x_ - ), - key_chains=key_chains, - to_apply=to_apply, - prune_unapplied=prune_unapplied, - map_sequences=map_sequences, - ), + return self._static_min( + self, + axis=axis, + keepdims=keepdims, + initial=initial, + where=where, + key_chains=key_chains, + to_apply=to_apply, + prune_unapplied=prune_unapplied, + map_sequences=map_sequences, out=out, ) diff --git a/ivy/data_classes/factorized_tensor/cp_tensor.py b/ivy/data_classes/factorized_tensor/cp_tensor.py index 7798966181f95..7def7d8288202 100644 --- a/ivy/data_classes/factorized_tensor/cp_tensor.py +++ b/ivy/data_classes/factorized_tensor/cp_tensor.py @@ -68,10 +68,12 @@ def to_unfolded(self, mode): return ivy.CPTensor.cp_to_unfolded(self, mode) def cp_copy(self): - return CPTensor(( - ivy.copy_array(self.weights), - [ivy.copy_array(self.factors[i]) for i in range(len(self.factors))], - )) + return CPTensor( + ( + ivy.copy_array(self.weights), + [ivy.copy_array(self.factors[i]) for i in range(len(self.factors))], + ) + ) def mode_dot(self, matrix_or_vector, mode, keep_dim=False, copy=True): """N-mode product of a CP tensor and a matrix or vector at the @@ -408,11 +410,11 @@ def cp_lstsq_grad(cp_tensor, tensor, return_loss=False, mask=None): .. math:: - \nabla 0.5 ||\\mathcal{X} - [\\mathbf{w}; \\mathbf{A}, \\mathbf{B}, \\mathbf{C}]||^2 # noqa + \nabla 0.5 ||\\mathcal{X} - [\\mathbf{w}; \\mathbf{A}, \\mathbf{B}, \\mathbf{C}]||^2 where :math:`[\\mathbf{w}; \\mathbf{A}, \\mathbf{B}, \\mathbf{C}]` is the CP decomposition with weights - :math:`\\mathbf{w}` and factor matrices :math:`\\mathbf{A}`, :math:`\\mathbf{B}` and :math:`\\mathbf{C}`. # noqa + :math:`\\mathbf{w}` and factor matrices :math:`\\mathbf{A}`, :math:`\\mathbf{B}` and :math:`\\mathbf{C}`. Note that this does not return the gradient with respect to the weights even if CP is normalized. @@ -444,7 +446,7 @@ def cp_lstsq_grad(cp_tensor, tensor, return_loss=False, mask=None): loss : float Scalar quantity of the loss function corresponding to cp_gradient. Only returned if return_loss = True. - """ + """ # noqa: E501 ivy.CPTensor.validate_cp_tensor(cp_tensor) _, factors = cp_tensor diff --git a/ivy/data_classes/factorized_tensor/parafac2_tensor.py b/ivy/data_classes/factorized_tensor/parafac2_tensor.py index 391467f6fb15f..78d07a91ff6ce 100644 --- a/ivy/data_classes/factorized_tensor/parafac2_tensor.py +++ b/ivy/data_classes/factorized_tensor/parafac2_tensor.py @@ -419,7 +419,7 @@ def parafac2_to_slices(parafac2_tensor, validate=True): weights = None decomposition = weights, (A, B, C), projections - I, _ = A.shape + I, _ = A.shape # noqa: E741 return [ ivy.Parafac2Tensor.parafac2_to_slice(decomposition, i, validate=False) for i in range(I) diff --git a/ivy/data_classes/factorized_tensor/tt_tensor.py b/ivy/data_classes/factorized_tensor/tt_tensor.py index 783fa8e6d6f15..c226155527441 100644 --- a/ivy/data_classes/factorized_tensor/tt_tensor.py +++ b/ivy/data_classes/factorized_tensor/tt_tensor.py @@ -108,7 +108,7 @@ def validate_tt_tensor(tt_tensor): def tt_to_tensor(factors): """Return the full tensor whose TT decomposition is given by 'factors'. - Re-assembles 'factors', which represent a tensor in TT/Matrix-Product-State format # noqa: E501 + Re-assembles 'factors', which represent a tensor in TT/Matrix-Product-State format into the corresponding full tensor Parameters @@ -120,7 +120,7 @@ def tt_to_tensor(factors): ------- output_tensor tensor whose TT/MPS decomposition was given by 'factors' - """ + """ # noqa: E501 if isinstance(factors, (float, int)): return factors @@ -213,8 +213,8 @@ def validate_tt_rank( shape of the tensor to decompose rank way to determine the rank, by default 'same' - if 'same': rank is computed to keep the number of parameters (at most) the same # noqa: E501 - if float, computes a rank so as to keep rank percent of the original number of parameters # noqa: E501 + if 'same': rank is computed to keep the number of parameters (at most) the same + if float, computes a rank so as to keep rank percent of the original number of parameters if int or tuple, just returns rank constant_rank if True, the *same* rank will be chosen for each modes @@ -233,7 +233,7 @@ def validate_tt_rank( ------- rank rank of the decomposition - """ + """ # noqa: E501 if rounding == "ceil": rounding_fn = ivy.ceil elif rounding == "floor": diff --git a/ivy/data_classes/factorized_tensor/tucker_tensor.py b/ivy/data_classes/factorized_tensor/tucker_tensor.py index 17f5d27f6c0c3..5984be2efe365 100644 --- a/ivy/data_classes/factorized_tensor/tucker_tensor.py +++ b/ivy/data_classes/factorized_tensor/tucker_tensor.py @@ -83,10 +83,12 @@ def to_unfolded(self, mode): return TuckerTensor.tucker_to_unfolded(self, mode) def tucker_copy(self): - return TuckerTensor(( - deepcopy(self.core), - [deepcopy(self.factors[i]) for i in range(len(self.factors))], - )) + return TuckerTensor( + ( + deepcopy(self.core), + [deepcopy(self.factors[i]) for i in range(len(self.factors))], + ) + ) def to_vec(self): return TuckerTensor.tucker_to_vec(self) diff --git a/ivy/func_wrapper.py b/ivy/func_wrapper.py index f008c017fd784..5e02cb26cde62 100644 --- a/ivy/func_wrapper.py +++ b/ivy/func_wrapper.py @@ -174,9 +174,13 @@ def try_array_function_override(func, overloaded_args, types, args, kwargs): def _get_first_array(*args, **kwargs): # ToDo: make this more efficient, with function ivy.nested_nth_index_where - array_fn = lambda x: ( - ivy.is_array(x) if not hasattr(x, "_ivy_array") else ivy.is_array(x.ivy_array) - ) + def array_fn(x): + return ( + ivy.is_array(x) + if not hasattr(x, "_ivy_array") + else ivy.is_array(x.ivy_array) + ) + array_fn = array_fn if "array_fn" not in kwargs else kwargs["array_fn"] arr = None if args: @@ -998,6 +1002,29 @@ def _to_ivy_array(x): return _temp_asarray_wrapper +# Download compiled cython wrapper wrapper + + +def download_cython_wrapper_wrapper(fn: Callable) -> Callable: + @functools.wraps(fn) + def _download_cython_wrapper_wrapper(*args, **kwargs): + """Wrap the function to download compiled cython wrapper for the + function and re- wraps it with the downloaded wrapper. + + Download the compiled cython wrapper by calling + ivy.wrappers.get_wrapper(func_name: str) and then wrap the + function with the downloaded wrapper. + """ + ivy.wrappers.download_cython_wrapper(fn.__name__) + ivy.wrappers.load_one_wrapper(fn.__name__) + ivy.functional.__dict__[fn.__name__] = getattr( + ivy.wrappers, fn.__name__ + "_wrapper" + )(fn) + return ivy.functional.__dict__[fn.__name__](*args, **kwargs) + + return _download_cython_wrapper_wrapper + + # Functions # @@ -1042,6 +1069,12 @@ def _wrap_function( ) return to_wrap if isinstance(to_wrap, FunctionType): + if ivy.cython_wrappers_mode and ivy.wrappers.wrapper_exists(to_wrap.__name__): + if to_wrap.__name__ + "_wrapper" in ivy.wrappers.__all__: + to_wrap = getattr(ivy.wrappers, to_wrap.__name__ + "_wrapper")(to_wrap) + return to_wrap + else: + return download_cython_wrapper_wrapper(to_wrap) # set attributes for attr in original.__dict__.keys(): # private attribute or decorator @@ -1625,14 +1658,16 @@ def __exit__(self, *exec): if globals_getter_func().get(item, None): if isinstance(globals_getter_func()[item], FunctionType): # we need to add the decorator - globals_getter_func([ - item, - ( - _dtype_device_wrapper_creator("unsupported_dtypes", tuple)( - *self.args, **self.kwargs - ) - )(globals_getter_func()[item]), - ]) + globals_getter_func( + [ + item, + ( + _dtype_device_wrapper_creator( + "unsupported_dtypes", tuple + )(*self.args, **self.kwargs) + )(globals_getter_func()[item]), + ] + ) class with_supported_dtypes(contextlib.ContextDecorator): @@ -1659,14 +1694,16 @@ def __exit__(self, *exec): if globals_getter_func().get(item, None): if isinstance(globals_getter_func()[item], FunctionType): # we need to add the decorator - globals_getter_func([ - item, - ( - _dtype_device_wrapper_creator("supported_dtypes", tuple)( - *self.args, **self.kwargs - ) - )(globals_getter_func()[item]), - ]) + globals_getter_func( + [ + item, + ( + _dtype_device_wrapper_creator( + "supported_dtypes", tuple + )(*self.args, **self.kwargs) + )(globals_getter_func()[item]), + ] + ) class with_unsupported_devices(contextlib.ContextDecorator): @@ -1693,14 +1730,16 @@ def __exit__(self, *exec): if globals_getter_func().get(item, None): if isinstance(globals_getter_func()[item], FunctionType): # we need to add the decorator - globals_getter_func([ - item, - ( - _dtype_device_wrapper_creator("unsupported_devices", tuple)( - *self.args, **self.kwargs - ) - )(globals_getter_func()[item]), - ]) + globals_getter_func( + [ + item, + ( + _dtype_device_wrapper_creator( + "unsupported_devices", tuple + )(*self.args, **self.kwargs) + )(globals_getter_func()[item]), + ] + ) class with_supported_devices(contextlib.ContextDecorator): @@ -1727,14 +1766,16 @@ def __exit__(self, *exec): if globals_getter_func().get(item, None): if isinstance(globals_getter_func()[item], FunctionType): # we need to add the decorator - globals_getter_func([ - item, - ( - _dtype_device_wrapper_creator("supported_devices", tuple)( - *self.args, **self.kwargs - ) - )(globals_getter_func()[item]), - ]) + globals_getter_func( + [ + item, + ( + _dtype_device_wrapper_creator( + "supported_devices", tuple + )(*self.args, **self.kwargs) + )(globals_getter_func()[item]), + ] + ) class with_unsupported_device_and_dtypes(contextlib.ContextDecorator): @@ -1783,14 +1824,16 @@ def __exit__(self, *exec): if globals_getter_func().get(item, None): if isinstance(globals_getter_func()[item], FunctionType): # we need to add the decorator - globals_getter_func([ - item, - ( - _dtype_device_wrapper_creator( - "unsupported_device_and_dtype", tuple - )(*self.args, **self.kwargs) - )(globals_getter_func()[item]), - ]) + globals_getter_func( + [ + item, + ( + _dtype_device_wrapper_creator( + "unsupported_device_and_dtype", tuple + )(*self.args, **self.kwargs) + )(globals_getter_func()[item]), + ] + ) class with_supported_device_and_dtypes(contextlib.ContextDecorator): @@ -1839,14 +1882,16 @@ def __exit__(self, *exec): if globals_getter_func().get(item, None): if isinstance(globals_getter_func()[item], FunctionType): # we need to add the decorator - globals_getter_func([ - item, - ( - _dtype_device_wrapper_creator( - "supported_device_and_dtype", tuple - )(*self.args, **self.kwargs) - )(globals_getter_func()[item]), - ]) + globals_getter_func( + [ + item, + ( + _dtype_device_wrapper_creator( + "supported_device_and_dtype", tuple + )(*self.args, **self.kwargs) + )(globals_getter_func()[item]), + ] + ) class override(contextlib.ContextDecorator): diff --git a/ivy/functional/backends/jax/__init__.py b/ivy/functional/backends/jax/__init__.py index b0d52c4819e6d..6168ec1b4ac84 100644 --- a/ivy/functional/backends/jax/__init__.py +++ b/ivy/functional/backends/jax/__init__.py @@ -4,6 +4,7 @@ import jaxlib import jax import jax.numpy as jnp +import importlib from typing import Union # make ivy.Container compatible with jax pytree traversal @@ -101,7 +102,7 @@ def _array_unflatten(aux_data, children): # update these to add new dtypes valid_dtypes = { - "0.4.23 and below": ( + "0.4.24 and below": ( ivy.int8, ivy.int16, ivy.int32, @@ -120,7 +121,7 @@ def _array_unflatten(aux_data, children): ) } valid_numeric_dtypes = { - "0.4.23 and below": ( + "0.4.24 and below": ( ivy.int8, ivy.int16, ivy.int32, @@ -139,7 +140,7 @@ def _array_unflatten(aux_data, children): } valid_int_dtypes = { - "0.4.23 and below": ( + "0.4.24 and below": ( ivy.int8, ivy.int16, ivy.int32, @@ -152,12 +153,12 @@ def _array_unflatten(aux_data, children): } valid_uint_dtypes = { - "0.4.23 and below": (ivy.uint8, ivy.uint16, ivy.uint32, ivy.uint64) + "0.4.24 and below": (ivy.uint8, ivy.uint16, ivy.uint32, ivy.uint64) } valid_float_dtypes = { - "0.4.23 and below": (ivy.bfloat16, ivy.float16, ivy.float32, ivy.float64) + "0.4.24 and below": (ivy.bfloat16, ivy.float16, ivy.float32, ivy.float64) } -valid_complex_dtypes = {"0.4.23 and below": (ivy.complex64, ivy.complex128)} +valid_complex_dtypes = {"0.4.24 and below": (ivy.complex64, ivy.complex128)} # leave these untouched @@ -172,12 +173,12 @@ def _array_unflatten(aux_data, children): # invalid data types # update these to add new dtypes -invalid_dtypes = {"0.4.23 and below": ()} -invalid_numeric_dtypes = {"0.4.23 and below": ()} -invalid_int_dtypes = {"0.4.23 and below": ()} -invalid_float_dtypes = {"0.4.23 and below": ()} -invalid_uint_dtypes = {"0.4.23 and below": ()} -invalid_complex_dtypes = {"0.4.23 and below": ()} +invalid_dtypes = {"0.4.24 and below": ()} +invalid_numeric_dtypes = {"0.4.24 and below": ()} +invalid_int_dtypes = {"0.4.24 and below": ()} +invalid_float_dtypes = {"0.4.24 and below": ()} +invalid_uint_dtypes = {"0.4.24 and below": ()} +invalid_complex_dtypes = {"0.4.24 and below": ()} # leave these untouched invalid_dtypes = _dtype_from_version(invalid_dtypes, backend_version) @@ -240,8 +241,22 @@ def closest_valid_dtype(type=None, /, as_native=False): from .experimental import * from . import control_flow_ops from .control_flow_ops import * +from . import module +from .module import * # sub-backends from . import sub_backends from .sub_backends import * + + +if importlib.util.find_spec("flax"): + import flax + + NativeModule = flax.linen.Module +elif importlib.util.find_spec("haiku"): + import haiku as hk + + NativeModule = hk.Module +else: + NativeModule = None diff --git a/ivy/functional/backends/jax/activations.py b/ivy/functional/backends/jax/activations.py index 08f4f42c88ebf..cdb9340436cf6 100644 --- a/ivy/functional/backends/jax/activations.py +++ b/ivy/functional/backends/jax/activations.py @@ -37,7 +37,7 @@ def leaky_relu( def relu( x: JaxArray, /, *, complex_mode="jax", out: Optional[JaxArray] = None ) -> JaxArray: - return jnp.maximum(x, 0) + return jax.nn.relu(x) def sigmoid( diff --git a/ivy/functional/backends/jax/control_flow_ops.py b/ivy/functional/backends/jax/control_flow_ops.py index ba981aadf58b4..3331fc7bef0c8 100644 --- a/ivy/functional/backends/jax/control_flow_ops.py +++ b/ivy/functional/backends/jax/control_flow_ops.py @@ -16,7 +16,8 @@ def body_fn_wrapper(loop_vars): def test_fn_wrapper(loop_vars): return test_fn(*loop_vars) - vars = list(vars.values()) + if isinstance(vars, dict): + vars = list(vars.values()) with jax.disable_jit(): final_loop_vars = jax.lax.while_loop(test_fn_wrapper, body_fn_wrapper, vars) return final_loop_vars diff --git a/ivy/functional/backends/jax/data_type.py b/ivy/functional/backends/jax/data_type.py index 5f2a13bb68113..1a84e9ad456e3 100644 --- a/ivy/functional/backends/jax/data_type.py +++ b/ivy/functional/backends/jax/data_type.py @@ -133,7 +133,7 @@ def broadcast_arrays(*arrays: JaxArray) -> List[JaxArray]: try: return jnp.broadcast_arrays(*arrays) except ValueError as e: - raise ivy.utils.exceptions.IvyBroadcastShapeError(e) + raise ivy.utils.exceptions.IvyBroadcastShapeError(e) from e def broadcast_to( diff --git a/ivy/functional/backends/jax/elementwise.py b/ivy/functional/backends/jax/elementwise.py index 8da329110a6d5..dc2089baf89ec 100644 --- a/ivy/functional/backends/jax/elementwise.py +++ b/ivy/functional/backends/jax/elementwise.py @@ -28,6 +28,7 @@ def abs( return jnp.where(x != 0, jnp.absolute(x), 0) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def acos(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.arccos(x) @@ -51,10 +52,12 @@ def add( return jnp.add(x1, x2) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def asin(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.arcsin(x) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def asinh(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.arcsinh(x) @@ -68,11 +71,12 @@ def atan2(x1: JaxArray, x2: JaxArray, /, *, out: Optional[JaxArray] = None) -> J return jnp.arctan2(x1, x2) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def atanh(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.arctanh(x) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def bitwise_and( x1: Union[int, JaxArray], x2: Union[int, JaxArray], @@ -84,14 +88,14 @@ def bitwise_and( return jnp.bitwise_and(x1, x2) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def bitwise_invert( x: Union[int, JaxArray], /, *, out: Optional[JaxArray] = None ) -> JaxArray: return jnp.bitwise_not(x) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def bitwise_left_shift( x1: Union[int, JaxArray], x2: Union[int, JaxArray], @@ -103,7 +107,7 @@ def bitwise_left_shift( return jnp.left_shift(x1, x2) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def bitwise_or( x1: Union[int, JaxArray], x2: Union[int, JaxArray], @@ -115,7 +119,7 @@ def bitwise_or( return jnp.bitwise_or(x1, x2) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def bitwise_right_shift( x1: Union[int, JaxArray], x2: Union[int, JaxArray], @@ -127,7 +131,7 @@ def bitwise_right_shift( return jnp.right_shift(x1, x2) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def bitwise_xor( x1: Union[int, JaxArray], x2: Union[int, JaxArray], @@ -139,7 +143,7 @@ def bitwise_xor( return jnp.bitwise_xor(x1, x2) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def ceil(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: if "int" in str(x.dtype): return x @@ -151,7 +155,7 @@ def cos(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.cos(x) -@with_unsupported_dtypes({"0.4.23 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("float16",)}, backend_version) def cosh(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.cosh(x) @@ -191,7 +195,7 @@ def expm1(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.expm1(x) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def floor(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: if "int" in str(x.dtype): return x @@ -199,7 +203,7 @@ def floor(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.floor(x) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def floor_divide( x1: Union[float, JaxArray], x2: Union[float, JaxArray], @@ -247,6 +251,7 @@ def isfinite(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.isfinite(x) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def isinf( x: JaxArray, /, @@ -427,7 +432,7 @@ def pow( return jnp.power(x1, x2) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def remainder( x1: Union[float, JaxArray], x2: Union[float, JaxArray], @@ -514,6 +519,9 @@ def trapz( return jnp.trapz(y, x=x, dx=dx, axis=axis) +@with_unsupported_dtypes( + {"0.4.24 and below": ("complex", "float16", "bfloat16")}, backend_version +) def tan(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.tan(x) @@ -524,7 +532,7 @@ def tanh( return jnp.tanh(x) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def trunc(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: if "int" in str(x.dtype): return x @@ -564,7 +572,7 @@ def angle( # ------# -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def erf(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jax.scipy.special.erf(x) @@ -615,7 +623,7 @@ def isreal(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.isreal(x) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def fmod( x1: JaxArray, x2: JaxArray, diff --git a/ivy/functional/backends/jax/experimental/activations.py b/ivy/functional/backends/jax/experimental/activations.py index f2e298cf4400c..f8a87fc7607f1 100644 --- a/ivy/functional/backends/jax/experimental/activations.py +++ b/ivy/functional/backends/jax/experimental/activations.py @@ -73,6 +73,7 @@ def silu(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return ret +@with_unsupported_dtypes({"0.4.14 and below": ("float16", "bfloat16")}, backend_version) def elu( x: JaxArray, /, *, alpha: float = 1.0, out: Optional[JaxArray] = None ) -> JaxArray: @@ -159,3 +160,11 @@ def hardshrink( if ivy.exists(out): return ivy.inplace_update(out, ret).astype(x.dtype) return ret + + +@with_unsupported_dtypes({"0.4.16 and below": ("float16", "bfloat16")}, backend_version) +def hardsilu(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: + ret = jax.nn.hard_silu(x) + if ivy.exists(out): + return ivy.inplace_update(out, ret).astype(x.dtype) + return ret diff --git a/ivy/functional/backends/jax/experimental/elementwise.py b/ivy/functional/backends/jax/experimental/elementwise.py index 1880fd049e412..8ea92a5094b85 100644 --- a/ivy/functional/backends/jax/experimental/elementwise.py +++ b/ivy/functional/backends/jax/experimental/elementwise.py @@ -50,7 +50,7 @@ def sinc(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: @with_supported_dtypes( - {"0.4.23 and below": ("float16", "float32", "float64")}, backend_version + {"0.4.24 and below": ("float16", "float32", "float64")}, backend_version ) def lgamma(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jlax.lgamma(x) @@ -499,3 +499,12 @@ def erfc( out: Optional[JaxArray] = None, ) -> JaxArray: return js.special.erfc(x) + + +def erfinv( + x: JaxArray, + /, + *, + out: Optional[JaxArray] = None, +) -> JaxArray: + return js.special.erfinv(x) diff --git a/ivy/functional/backends/jax/experimental/layers.py b/ivy/functional/backends/jax/experimental/layers.py index 3b66486a28dfe..335b0745e2ce2 100644 --- a/ivy/functional/backends/jax/experimental/layers.py +++ b/ivy/functional/backends/jax/experimental/layers.py @@ -440,7 +440,7 @@ def avg_pool3d( return res -@with_supported_dtypes({"0.4.23 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"0.4.24 and below": ("float32", "float64")}, backend_version) def dct( x: JaxArray, /, @@ -822,7 +822,7 @@ def ifftn( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, backend_version + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version ) def embedding( weights: JaxArray, @@ -870,7 +870,7 @@ def rfft( return ret -@with_unsupported_dtypes({"0.4.23 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("float16", "complex")}, backend_version) def rfftn( x: JaxArray, s: Optional[Sequence[int]] = None, diff --git a/ivy/functional/backends/jax/experimental/linear_algebra.py b/ivy/functional/backends/jax/experimental/linear_algebra.py index 0f1841e41f1a6..d5b6aa3d31174 100644 --- a/ivy/functional/backends/jax/experimental/linear_algebra.py +++ b/ivy/functional/backends/jax/experimental/linear_algebra.py @@ -2,14 +2,13 @@ from typing import Optional, Tuple, Sequence, Union import jax.numpy as jnp import jax.scipy.linalg as jla - +from collections import namedtuple from ivy.func_wrapper import with_supported_dtypes from ivy.functional.backends.jax import JaxArray import ivy from ivy.functional.ivy.experimental.linear_algebra import _check_valid_dimension_size -from ivy.utils.exceptions import IvyNotImplementedException from . import backend_version @@ -180,8 +179,22 @@ def lu_factor( *, pivot: Optional[bool] = True, out: Optional[JaxArray] = None, -) -> Tuple[JaxArray]: - raise IvyNotImplementedException() +) -> Tuple[JaxArray, JaxArray]: + ret = jla.lu(x) + ret_tuple = namedtuple("lu_factor", ["LU", "p"]) + ret_1 = ret[1] + return ret_tuple((ret_1 - jnp.eye(*ret_1.shape)) + ret[2], ret[0]) + + +def lu_solve( + lu: Tuple[JaxArray, JaxArray], + p: JaxArray, + b: JaxArray, + /, + *, + out: Optional[JaxArray] = None, +) -> JaxArray: + return jla.lu_solve((lu, p), b) def dot( diff --git a/ivy/functional/backends/jax/experimental/losses.py b/ivy/functional/backends/jax/experimental/losses.py index 24359a26366be..8456c3e1defcf 100644 --- a/ivy/functional/backends/jax/experimental/losses.py +++ b/ivy/functional/backends/jax/experimental/losses.py @@ -1,5 +1,4 @@ import jax.numpy as jnp -from typing import Optional from ivy.functional.backends.jax import JaxArray # local @@ -30,8 +29,8 @@ def smooth_l1_loss( target: JaxArray, /, *, - beta: Optional[float] = 1.0, - reduction: Optional[str] = "mean", + beta: float = 1.0, + reduction: str = "mean", ) -> JaxArray: if beta < 1e-5: loss = jnp.abs(input - target) @@ -52,7 +51,7 @@ def soft_margin_loss( target: JaxArray, /, *, - reduction: Optional[str] = "mean", + reduction: str = "mean", ) -> JaxArray: loss = jnp.sum(jnp.log1p(jnp.exp(-input * target))) / jnp.size(input) @@ -64,11 +63,11 @@ def soft_margin_loss( return loss -def _apply_loss_reduction(loss: JaxArray, reduction: str, axis=None) -> JaxArray: +def _apply_loss_reduction(loss: JaxArray, reduction: str) -> JaxArray: if reduction == "sum": - return jnp.sum(loss, axis=axis) + return jnp.sum(loss) elif reduction == "mean": - return jnp.mean(loss, axis=axis) + return jnp.mean(loss) else: # reduction == "none" return loss @@ -114,7 +113,7 @@ def _validate_poisson_nll_params( @with_supported_device_and_dtypes( { - "0.4.14 and below": { + "0.4.18 and below": { "cpu": ("float16", "float32", "float64"), } }, @@ -153,3 +152,28 @@ def poisson_nll_loss( cond = jnp.logical_and(target_arr >= zeroes, target_arr <= ones) loss = loss + jnp.where(cond, zeroes, striling_approx_term) return _apply_loss_reduction(loss, reduction) + + +@with_supported_device_and_dtypes( + { + "0.4.18 and below": { + "cpu": ("float32", "float64"), + } + }, + backend_version, +) +def hinge_embedding_loss( + input: JaxArray, + target: JaxArray, + *, + margin: float = 1.0, + reduction: str = "mean", +) -> JaxArray: + zero_ = jnp.zeros([1], dtype=input.dtype) + + relu_part = jnp.maximum(margin - input, 0) + + loss = jnp.where(target == 1.0, input, zero_) + jnp.where( + target == -1.0, relu_part, zero_ + ) + return _apply_loss_reduction(loss, reduction) diff --git a/ivy/functional/backends/jax/experimental/manipulation.py b/ivy/functional/backends/jax/experimental/manipulation.py index 1eb7c5ac75315..59ee341ab7870 100644 --- a/ivy/functional/backends/jax/experimental/manipulation.py +++ b/ivy/functional/backends/jax/experimental/manipulation.py @@ -15,6 +15,7 @@ import jax.lax as jlax from numbers import Number from collections import namedtuple +from ivy.func_wrapper import handle_out_argument # local import ivy @@ -442,11 +443,11 @@ def take( if ivy.exists(axis): try: x_shape = x.shape[axis] - except Exception: + except Exception as e: raise ValueError( f"axis {axis} is out of bounds for array of dimension" f" {len(x.shape)}" - ) + ) from e else: x_shape = jnp.prod(x.shape) @@ -462,9 +463,25 @@ def take( # clip, wrap, fill ret = jnp.take(x, indices, axis=axis, mode=mode, fill_value=fill_value) if ivy.exists(out): - ivy.inplace_update(out) + ivy.inplace_update(out, ret) return ret def trim_zeros(a: JaxArray, /, *, trim: Optional[str] = "bf") -> JaxArray: return jnp.trim_zeros(a, trim=trim) + + +@handle_out_argument +def unflatten( + x: JaxArray, + /, + shape: Tuple[int] = None, + dim: int = 0, + *, + out: Optional[JaxArray] = None, + order: Optional[str] = None, +) -> JaxArray: + dim = abs(len(x.shape) + dim) if dim < 0 else dim + res_shape = x.shape[:dim] + shape + x.shape[dim + 1 :] + res = jnp.reshape(x, res_shape) + return res diff --git a/ivy/functional/backends/jax/experimental/random.py b/ivy/functional/backends/jax/experimental/random.py index 17b2d54037a99..9dc36ed0fb3bb 100644 --- a/ivy/functional/backends/jax/experimental/random.py +++ b/ivy/functional/backends/jax/experimental/random.py @@ -56,7 +56,7 @@ def beta( return jax.random.beta(rng_input, a, b, shape, dtype) -@with_unsupported_dtypes({"0.4.23 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("bfloat16",)}, backend_version) def gamma( alpha: Union[float, JaxArray], beta: Union[float, JaxArray], @@ -117,6 +117,7 @@ def bernoulli( seed: Optional[int] = None, out: Optional[JaxArray] = None, ) -> JaxArray: + dtype = dtype if dtype is not None else probs.dtype if seed: rng_input = jax.random.PRNGKey(seed) else: @@ -126,4 +127,4 @@ def bernoulli( probs = jax.nn.softmax(logits, axis=-1) if hasattr(probs, "shape") and not _check_shapes_broadcastable(shape, probs.shape): shape = probs.shape - return jax.random.bernoulli(rng_input, probs, shape=shape) + return jax.random.bernoulli(rng_input, probs, shape=shape).astype(dtype) diff --git a/ivy/functional/backends/jax/experimental/sorting.py b/ivy/functional/backends/jax/experimental/sorting.py index c73727cc612c7..b6255d7919ef3 100644 --- a/ivy/functional/backends/jax/experimental/sorting.py +++ b/ivy/functional/backends/jax/experimental/sorting.py @@ -23,7 +23,7 @@ def invert_permutation( # lexsort -@with_unsupported_dtypes({"0.4.23 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("bfloat16",)}, backend_version) def lexsort( keys: JaxArray, /, diff --git a/ivy/functional/backends/jax/experimental/statistical.py b/ivy/functional/backends/jax/experimental/statistical.py index c2ac4780dcee9..0f67e8c5e7c28 100644 --- a/ivy/functional/backends/jax/experimental/statistical.py +++ b/ivy/functional/backends/jax/experimental/statistical.py @@ -10,7 +10,7 @@ @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16",)}, + {"0.4.24 and below": ("bfloat16",)}, backend_version, ) def histogram( @@ -121,7 +121,7 @@ def histogram( @with_unsupported_dtypes( - {"0.4.23 and below": ("complex64", "complex128")}, backend_version + {"0.4.24 and below": ("complex64", "complex128")}, backend_version ) def median( input: JaxArray, @@ -406,7 +406,7 @@ def __get_index(lst, indices=None, prefix=None): @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "bfloat16", "bool", ) diff --git a/ivy/functional/backends/jax/general.py b/ivy/functional/backends/jax/general.py index a21e94b23fc12..7bed7585f613b 100644 --- a/ivy/functional/backends/jax/general.py +++ b/ivy/functional/backends/jax/general.py @@ -58,8 +58,7 @@ def _mask_to_index(query, x): raise ivy.exceptions.IvyException("too many indices") elif not len(query.shape): query = jnp.tile(query, x.shape[0]) - expected_shape = x[query].shape - return jnp.where(query), expected_shape + return jnp.where(query) def get_item( @@ -75,7 +74,7 @@ def get_item( return jnp.array([], dtype=x.dtype) else: return jnp.expand_dims(x, 0) - query, _ = _mask_to_index(query, x) + query = _mask_to_index(query, x) elif isinstance(query, list): query = (query,) return x.__getitem__(query) @@ -90,7 +89,9 @@ def set_item( copy: Optional[bool] = False, ) -> JaxArray: if ivy.is_array(query) and ivy.is_bool_dtype(query): - query, expected_shape = _mask_to_index(query, x) + query = _mask_to_index(query, x) + expected_shape = x[query].shape + if ivy.is_array(val): val = _broadcast_to(val, expected_shape)._data ret = x.at[query].set(val) if copy: @@ -102,7 +103,7 @@ def array_equal(x0: JaxArray, x1: JaxArray, /) -> bool: return bool(jnp.array_equal(x0, x1)) -@with_unsupported_dtypes({"0.4.23 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("bfloat16",)}, backend_version) def to_numpy(x: JaxArray, /, *, copy: bool = True) -> np.ndarray: if copy: return np.array(_to_array(x)) @@ -421,7 +422,7 @@ def vmap( ) -@with_unsupported_dtypes({"0.4.23 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("float16", "bfloat16")}, backend_version) def isin( elements: JaxArray, test_elements: JaxArray, diff --git a/ivy/functional/backends/jax/layers.py b/ivy/functional/backends/jax/layers.py index 78a72fb2fb85b..146514399b07b 100644 --- a/ivy/functional/backends/jax/layers.py +++ b/ivy/functional/backends/jax/layers.py @@ -427,7 +427,7 @@ def conv_general_transpose( filter_format: str = "channel_last", data_format: str = "channel_last", dilations: Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int]] = 1, - feature_group_count: Optional[int] = 1, + feature_group_count: int = 1, bias: Optional[JaxArray] = None, out: Optional[JaxArray] = None, ): diff --git a/ivy/functional/backends/jax/linear_algebra.py b/ivy/functional/backends/jax/linear_algebra.py index 70cfd1c32047d..886d159961ef1 100644 --- a/ivy/functional/backends/jax/linear_algebra.py +++ b/ivy/functional/backends/jax/linear_algebra.py @@ -20,7 +20,7 @@ @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def cholesky( @@ -34,7 +34,7 @@ def cholesky( return ret -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def cross( x1: JaxArray, x2: JaxArray, @@ -51,14 +51,14 @@ def cross( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def det(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.linalg.det(x) -@with_unsupported_dtypes({"0.4.23 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("float16", "bfloat16")}, backend_version) def eig(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> Tuple[JaxArray]: result_tuple = NamedTuple( "eig", [("eigenvalues", JaxArray), ("eigenvectors", JaxArray)] @@ -67,7 +67,7 @@ def eig(x: JaxArray, /, *, out: Optional[JaxArray] = None) -> Tuple[JaxArray]: return result_tuple(eigenvalues, eigenvectors) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def diagonal( x: JaxArray, /, @@ -104,7 +104,7 @@ def tensorsolve( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def eigh( @@ -118,7 +118,7 @@ def eigh( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def eigvalsh( @@ -127,14 +127,14 @@ def eigvalsh( return jnp.linalg.eigvalsh(x, UPLO=UPLO) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def inner(x1: JaxArray, x2: JaxArray, /, *, out: Optional[JaxArray] = None) -> JaxArray: x1, x2 = ivy.promote_types_of_inputs(x1, x2) return jnp.inner(x1, x2) @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def inv( @@ -155,7 +155,7 @@ def inv( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def matmul( @@ -181,7 +181,7 @@ def matmul( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def matrix_norm( @@ -191,8 +191,11 @@ def matrix_norm( ord: Union[int, float, Literal[inf, -inf, "fro", "nuc"]] = "fro", axis: Tuple[int, int] = (-2, -1), keepdims: bool = False, + dtype: Optional[jnp.dtype] = None, out: Optional[JaxArray] = None, ) -> JaxArray: + if dtype is not None: + x = ivy.astype(x, dtype) if hasattr(axis, "__iter__"): if not isinstance(axis, tuple): axis = tuple(axis) @@ -202,13 +205,13 @@ def matrix_norm( return jnp.linalg.norm(x, ord=ord, axis=axis, keepdims=keepdims) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def matrix_power(x: JaxArray, n: int, /, *, out: Optional[JaxArray] = None) -> JaxArray: return jnp.linalg.matrix_power(x, n) @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def matrix_rank( @@ -239,7 +242,7 @@ def matrix_rank( @with_unsupported_dtypes( - {"0.4.23 and below": ("int", "float16", "complex")}, + {"0.4.24 and below": ("int", "float16", "complex")}, backend_version, ) def matrix_transpose( @@ -251,7 +254,7 @@ def matrix_transpose( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def outer( @@ -266,7 +269,7 @@ def outer( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def pinv( @@ -284,7 +287,7 @@ def pinv( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def qr( @@ -296,7 +299,7 @@ def qr( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def slogdet( @@ -309,7 +312,7 @@ def slogdet( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def solve( @@ -351,7 +354,7 @@ def solve( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def svd( @@ -368,7 +371,7 @@ def svd( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def svdvals( @@ -378,7 +381,7 @@ def svdvals( return jnp.linalg.svd(x, compute_uv=False) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def tensordot( x1: JaxArray, x2: JaxArray, @@ -392,7 +395,7 @@ def tensordot( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def trace( @@ -407,7 +410,7 @@ def trace( return jnp.trace(x, offset=offset, axis1=axis1, axis2=axis2, out=out) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def vecdot( x1: JaxArray, x2: JaxArray, /, *, axis: int = -1, out: Optional[JaxArray] = None ) -> JaxArray: @@ -415,7 +418,7 @@ def vecdot( return jnp.tensordot(x1, x2, axes=(axis, axis)) -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def vector_norm( x: JaxArray, /, @@ -445,7 +448,7 @@ def vector_norm( # ------# -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def diag( x: JaxArray, /, @@ -457,7 +460,7 @@ def diag( @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "complex")}, + {"0.4.24 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def vander( @@ -473,7 +476,7 @@ def vander( @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "complex", "unsigned", ) diff --git a/ivy/functional/backends/jax/manipulation.py b/ivy/functional/backends/jax/manipulation.py index 3d3b7c792a21c..360333e8a186c 100644 --- a/ivy/functional/backends/jax/manipulation.py +++ b/ivy/functional/backends/jax/manipulation.py @@ -39,7 +39,7 @@ def concat( try: return jnp.concatenate(xs, axis) except ValueError as error: - raise ivy.utils.exceptions.IvyIndexError(error) + raise ivy.utils.exceptions.IvyIndexError(error) from error def expand_dims( @@ -54,7 +54,7 @@ def expand_dims( ret = jnp.expand_dims(x, axis) return ret except ValueError as error: - raise ivy.utils.exceptions.IvyIndexError(error) + raise ivy.utils.exceptions.IvyIndexError(error) from error def flip( @@ -143,7 +143,7 @@ def stack( try: return jnp.stack(arrays, axis=axis) except ValueError as error: - raise ivy.utils.exceptions.IvyIndexError(error) + raise ivy.utils.exceptions.IvyIndexError(error) from error # Extra # @@ -226,7 +226,7 @@ def clip( return x -@with_unsupported_dtypes({"0.4.23 and below": ("uint64",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("uint64",)}, backend_version) def constant_pad( x: JaxArray, /, diff --git a/ivy/functional/backends/jax/module.py b/ivy/functional/backends/jax/module.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ivy/functional/backends/jax/random.py b/ivy/functional/backends/jax/random.py index c2e98759fe2c4..ef0555fabf6d7 100644 --- a/ivy/functional/backends/jax/random.py +++ b/ivy/functional/backends/jax/random.py @@ -83,7 +83,7 @@ def random_normal( return jax.random.normal(rng_input, shape, dtype=dtype) * std + mean -@with_unsupported_dtypes({"0.4.23 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("bfloat16",)}, backend_version) def multinomial( population_size: int, num_samples: int, @@ -106,10 +106,12 @@ def multinomial( if probs is None: probs = ( - jnp.ones(( - batch_size, - population_size, - )) + jnp.ones( + ( + batch_size, + population_size, + ) + ) / population_size ) orig_probs_shape = list(probs.shape) diff --git a/ivy/functional/backends/jax/searching.py b/ivy/functional/backends/jax/searching.py index 2e2a321aa26fb..b149e64cc38d1 100644 --- a/ivy/functional/backends/jax/searching.py +++ b/ivy/functional/backends/jax/searching.py @@ -12,7 +12,7 @@ # ------------------ # -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def argmax( x: JaxArray, /, @@ -38,7 +38,7 @@ def argmax( return ret -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def argmin( x: JaxArray, /, diff --git a/ivy/functional/backends/jax/sorting.py b/ivy/functional/backends/jax/sorting.py index fde2f9e9910df..acee3f979316d 100644 --- a/ivy/functional/backends/jax/sorting.py +++ b/ivy/functional/backends/jax/sorting.py @@ -78,7 +78,7 @@ def searchsorted( # msort -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, backend_version) def msort( a: Union[JaxArray, list, tuple], /, diff --git a/ivy/functional/backends/jax/statistical.py b/ivy/functional/backends/jax/statistical.py index 3ea7390120149..b9e0610698256 100644 --- a/ivy/functional/backends/jax/statistical.py +++ b/ivy/functional/backends/jax/statistical.py @@ -19,10 +19,14 @@ def min( *, axis: Optional[Union[int, Sequence[int]]] = None, keepdims: bool = False, + initial: Optional[Union[int, float, complex]] = None, + where: Optional[JaxArray] = None, out: Optional[JaxArray] = None, ) -> JaxArray: axis = tuple(axis) if isinstance(axis, list) else axis - return jnp.min(a=jnp.asarray(x), axis=axis, keepdims=keepdims) + return jnp.min( + a=jnp.asarray(x), axis=axis, keepdims=keepdims, initial=initial, where=where + ) def max( @@ -38,7 +42,7 @@ def max( @with_unsupported_dtypes( - {"0.4.23 and below": "bfloat16"}, + {"0.4.24 and below": "bfloat16"}, backend_version, ) def mean( @@ -143,7 +147,7 @@ def var( # ------# -@with_unsupported_dtypes({"0.4.23 and below": "bfloat16"}, backend_version) +@with_unsupported_dtypes({"0.4.24 and below": ("bfloat16", "bool")}, backend_version) def cumprod( x: JaxArray, /, @@ -179,6 +183,7 @@ def cumprod( return jnp.flip(x, axis=axis) +@with_unsupported_dtypes({"0.4.24 and below": "bool"}, backend_version) def cumsum( x: JaxArray, axis: int = 0, diff --git a/ivy/functional/backends/jax/utility.py b/ivy/functional/backends/jax/utility.py index 8fac7a2afbca6..6d2293ef45913 100644 --- a/ivy/functional/backends/jax/utility.py +++ b/ivy/functional/backends/jax/utility.py @@ -19,7 +19,7 @@ def all( try: return jnp.all(x, axis, keepdims=keepdims) except ValueError as error: - raise ivy.utils.exceptions.IvyIndexError(error) + raise ivy.utils.exceptions.IvyIndexError(error) from error def any( @@ -34,4 +34,4 @@ def any( try: return jnp.any(x, axis, keepdims=keepdims, out=out) except ValueError as error: - raise ivy.utils.exceptions.IvyIndexError(error) + raise ivy.utils.exceptions.IvyIndexError(error) from error diff --git a/ivy/functional/backends/mxnet/__init__.py b/ivy/functional/backends/mxnet/__init__.py index 3e0bef791040a..9a73876faa148 100644 --- a/ivy/functional/backends/mxnet/__init__.py +++ b/ivy/functional/backends/mxnet/__init__.py @@ -201,3 +201,8 @@ def closest_valid_dtype(type=None, /, as_native=False): from .control_flow_ops import * from . import sub_backends from .sub_backends import * +from . import module +from .module import * + + +NativeModule = mx.gluon.nn.Block diff --git a/ivy/functional/backends/mxnet/creation.py b/ivy/functional/backends/mxnet/creation.py index 5da540614b9e3..d32d312efc394 100644 --- a/ivy/functional/backends/mxnet/creation.py +++ b/ivy/functional/backends/mxnet/creation.py @@ -35,16 +35,18 @@ def arange( @_asarray_handle_nestable @_asarray_inputs_to_native_shapes def asarray( - obj: Union[( - None, - mx.ndarray.NDArray, - bool, - int, - float, - NestedSequence, - SupportsBufferProtocol, - np.ndarray, - )], + obj: Union[ + ( + None, + mx.ndarray.NDArray, + bool, + int, + float, + NestedSequence, + SupportsBufferProtocol, + np.ndarray, + ) + ], /, *, copy: Optional[bool] = None, diff --git a/ivy/functional/backends/mxnet/experimental/gradients.py b/ivy/functional/backends/mxnet/experimental/gradients.py index e952f2264ccbb..bcd6d00b7e2e7 100644 --- a/ivy/functional/backends/mxnet/experimental/gradients.py +++ b/ivy/functional/backends/mxnet/experimental/gradients.py @@ -46,7 +46,7 @@ def vjpfun(x_in): ) return _rebuild_flattened_containers( - ivy.to_ivy(grads, nested=True, include_derived=True) + ivy.to_ivy(grads, nested=True, include_derived=True), ret_idxs ) return (ivy.to_ivy(primals_out, nested=True, include_derived=True), vjpfun) diff --git a/ivy/functional/backends/mxnet/experimental/linear_algebra.py b/ivy/functional/backends/mxnet/experimental/linear_algebra.py index 458c945791b83..dd31f5eeb070d 100644 --- a/ivy/functional/backends/mxnet/experimental/linear_algebra.py +++ b/ivy/functional/backends/mxnet/experimental/linear_algebra.py @@ -15,11 +15,13 @@ def eigh_tridiagonal( Union[(Tuple[(int, int)], List[int], None, mx.ndarray.NDArray)] ] = None, tol: Optional[float] = None, -) -> Union[( - None, - mx.ndarray.NDArray, - Tuple[(Union[(None, mx.ndarray.NDArray)], Union[(None, mx.ndarray.NDArray)])], -)]: +) -> Union[ + ( + None, + mx.ndarray.NDArray, + Tuple[(Union[(None, mx.ndarray.NDArray)], Union[(None, mx.ndarray.NDArray)])], + ) +]: raise IvyNotImplementedException() diff --git a/ivy/functional/backends/mxnet/experimental/norms.py b/ivy/functional/backends/mxnet/experimental/norms.py index da6b8b5311adf..19fea95289a8d 100644 --- a/ivy/functional/backends/mxnet/experimental/norms.py +++ b/ivy/functional/backends/mxnet/experimental/norms.py @@ -26,11 +26,13 @@ def batch_norm( eps: float = 1e-05, momentum: float = 0.1, out: Optional[None] = None, -) -> Tuple[( - Union[(None, mx.ndarray.NDArray)], - Union[(None, mx.ndarray.NDArray)], - Union[(None, mx.ndarray.NDArray)], -)]: +) -> Tuple[ + ( + Union[(None, mx.ndarray.NDArray)], + Union[(None, mx.ndarray.NDArray)], + Union[(None, mx.ndarray.NDArray)], + ) +]: raise IvyNotImplementedException() @@ -46,11 +48,13 @@ def instance_norm( eps: float = 1e-05, momentum: float = 0.1, out: Optional[None] = None, -) -> Tuple[( - Union[(None, mx.ndarray.NDArray)], - Union[(None, mx.ndarray.NDArray)], - Union[(None, mx.ndarray.NDArray)], -)]: +) -> Tuple[ + ( + Union[(None, mx.ndarray.NDArray)], + Union[(None, mx.ndarray.NDArray)], + Union[(None, mx.ndarray.NDArray)], + ) +]: raise IvyNotImplementedException() diff --git a/ivy/functional/backends/mxnet/module.py b/ivy/functional/backends/mxnet/module.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ivy/functional/backends/mxnet/set.py b/ivy/functional/backends/mxnet/set.py index 1617ed1539d12..cb9a9cc9906e6 100644 --- a/ivy/functional/backends/mxnet/set.py +++ b/ivy/functional/backends/mxnet/set.py @@ -6,12 +6,14 @@ def unique_all( x: Union[(None, mx.ndarray.NDArray)], /, *, axis: Optional[int] = None -) -> Tuple[( - Union[(None, mx.ndarray.NDArray)], - Union[(None, mx.ndarray.NDArray)], - Union[(None, mx.ndarray.NDArray)], - Union[(None, mx.ndarray.NDArray)], -)]: +) -> Tuple[ + ( + Union[(None, mx.ndarray.NDArray)], + Union[(None, mx.ndarray.NDArray)], + Union[(None, mx.ndarray.NDArray)], + Union[(None, mx.ndarray.NDArray)], + ) +]: raise IvyNotImplementedException() diff --git a/ivy/functional/backends/numpy/__init__.py b/ivy/functional/backends/numpy/__init__.py index 0939aa145f73c..d739b919131b9 100644 --- a/ivy/functional/backends/numpy/__init__.py +++ b/ivy/functional/backends/numpy/__init__.py @@ -81,7 +81,7 @@ def rep_method(self, ufunc, method, *inputs, **kwargs): # update these to add new dtypes valid_dtypes = { - "1.26.2 and below": ( + "1.26.3 and below": ( ivy.int8, ivy.int16, ivy.int32, @@ -99,7 +99,7 @@ def rep_method(self, ufunc, method, *inputs, **kwargs): ) } valid_numeric_dtypes = { - "1.26.2 and below": ( + "1.26.3 and below": ( ivy.int8, ivy.int16, ivy.int32, @@ -116,7 +116,7 @@ def rep_method(self, ufunc, method, *inputs, **kwargs): ) } valid_int_dtypes = { - "1.26.2 and below": ( + "1.26.3 and below": ( ivy.int8, ivy.int16, ivy.int32, @@ -127,11 +127,11 @@ def rep_method(self, ufunc, method, *inputs, **kwargs): ivy.uint64, ) } -valid_float_dtypes = {"1.26.2 and below": (ivy.float16, ivy.float32, ivy.float64)} +valid_float_dtypes = {"1.26.3 and below": (ivy.float16, ivy.float32, ivy.float64)} valid_uint_dtypes = { - "1.26.2 and below": (ivy.uint8, ivy.uint16, ivy.uint32, ivy.uint64) + "1.26.3 and below": (ivy.uint8, ivy.uint16, ivy.uint32, ivy.uint64) } -valid_complex_dtypes = {"1.26.2 and below": (ivy.complex64, ivy.complex128)} +valid_complex_dtypes = {"1.26.3 and below": (ivy.complex64, ivy.complex128)} # leave these untouched valid_dtypes = _dtype_from_version(valid_dtypes, backend_version) @@ -143,12 +143,12 @@ def rep_method(self, ufunc, method, *inputs, **kwargs): # invalid data types # update these to add new dtypes -invalid_dtypes = {"1.26.2 and below": (ivy.bfloat16,)} -invalid_numeric_dtypes = {"1.26.2 and below": (ivy.bfloat16,)} -invalid_int_dtypes = {"1.26.2 and below": ()} -invalid_float_dtypes = {"1.26.2 and below": (ivy.bfloat16,)} -invalid_uint_dtypes = {"1.26.2 and below": ()} -invalid_complex_dtypes = {"1.26.2 and below": ()} +invalid_dtypes = {"1.26.3 and below": (ivy.bfloat16,)} +invalid_numeric_dtypes = {"1.26.3 and below": (ivy.bfloat16,)} +invalid_int_dtypes = {"1.26.3 and below": ()} +invalid_float_dtypes = {"1.26.3 and below": (ivy.bfloat16,)} +invalid_uint_dtypes = {"1.26.3 and below": ()} +invalid_complex_dtypes = {"1.26.3 and below": ()} # leave these untouched @@ -213,9 +213,14 @@ def closest_valid_dtype(type=None, /, as_native=False): from .experimental import * from . import control_flow_ops from .control_flow_ops import * +from . import module +from .module import * # sub-backends from . import sub_backends from .sub_backends import * + + +NativeModule = None diff --git a/ivy/functional/backends/numpy/activations.py b/ivy/functional/backends/numpy/activations.py index 714056b4b34c0..7f396edb7da5d 100644 --- a/ivy/functional/backends/numpy/activations.py +++ b/ivy/functional/backends/numpy/activations.py @@ -8,8 +8,20 @@ # local import ivy from ivy.functional.backends.numpy.helpers import _scalar_output_to_0d_array +from ivy.func_wrapper import with_supported_dtypes +from . import backend_version +@with_supported_dtypes( + { + "1.26.3 and below": ( + "float", + "int", + "complex", + ) + }, + backend_version, +) @_scalar_output_to_0d_array def relu( x: np.ndarray, /, *, complex_mode="jax", out: Optional[np.ndarray] = None diff --git a/ivy/functional/backends/numpy/control_flow_ops.py b/ivy/functional/backends/numpy/control_flow_ops.py index 0a80ff33a461e..97d3b91dcc53e 100644 --- a/ivy/functional/backends/numpy/control_flow_ops.py +++ b/ivy/functional/backends/numpy/control_flow_ops.py @@ -14,7 +14,9 @@ def cond(*_): def while_loop(test_fn, body_fn, vars): - result = list(vars.values()) + result = vars + if isinstance(vars, dict): + result = list(vars.values()) while test_fn(*result): result = body_fn(*result) if not isinstance(result, tuple): diff --git a/ivy/functional/backends/numpy/data_type.py b/ivy/functional/backends/numpy/data_type.py index facd6d6f3b645..342eed678a793 100644 --- a/ivy/functional/backends/numpy/data_type.py +++ b/ivy/functional/backends/numpy/data_type.py @@ -130,10 +130,10 @@ def broadcast_arrays(*arrays: np.ndarray) -> List[np.ndarray]: try: return np.broadcast_arrays(*arrays) except ValueError as e: - raise ivy.utils.exceptions.IvyBroadcastShapeError(e) + raise ivy.utils.exceptions.IvyBroadcastShapeError(e) from e -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def broadcast_to( x: np.ndarray, /, @@ -216,7 +216,7 @@ def as_ivy_dtype( ) -@with_unsupported_dtypes({"1.26.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("bfloat16",)}, backend_version) def as_native_dtype(dtype_in: Union[np.dtype, str, bool, int, float], /) -> np.dtype: if dtype_in is int: return ivy.default_int_dtype(as_native=True) diff --git a/ivy/functional/backends/numpy/elementwise.py b/ivy/functional/backends/numpy/elementwise.py index 0d0c6e8ce9022..5275c963ffebf 100644 --- a/ivy/functional/backends/numpy/elementwise.py +++ b/ivy/functional/backends/numpy/elementwise.py @@ -83,7 +83,7 @@ def atan(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def atan2( x1: np.ndarray, x2: np.ndarray, /, *, out: Optional[np.ndarray] = None ) -> np.ndarray: @@ -103,7 +103,7 @@ def atanh(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def bitwise_and( x1: Union[int, bool, np.ndarray], x2: Union[int, bool, np.ndarray], @@ -119,7 +119,7 @@ def bitwise_and( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def bitwise_invert( x: Union[int, bool, np.ndarray], /, *, out: Optional[np.ndarray] = None ) -> np.ndarray: @@ -130,7 +130,7 @@ def bitwise_invert( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def bitwise_left_shift( x1: Union[int, bool, np.ndarray], x2: Union[int, bool, np.ndarray], @@ -146,7 +146,7 @@ def bitwise_left_shift( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def bitwise_or( x1: Union[int, bool, np.ndarray], x2: Union[int, bool, np.ndarray], @@ -162,7 +162,7 @@ def bitwise_or( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def bitwise_right_shift( x1: Union[int, bool, np.ndarray], x2: Union[int, bool, np.ndarray], @@ -178,7 +178,7 @@ def bitwise_right_shift( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def bitwise_xor( x1: Union[int, bool, np.ndarray], x2: Union[int, bool, np.ndarray], @@ -193,7 +193,7 @@ def bitwise_xor( bitwise_xor.support_native_out = True -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) @_scalar_output_to_0d_array def ceil(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: if "int" in str(x.dtype): @@ -216,7 +216,7 @@ def cos(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: cos.support_native_out = True -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) @_scalar_output_to_0d_array def cosh(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: return np.cosh(x, out=out) @@ -289,7 +289,7 @@ def expm1(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def floor(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: if "int" in str(x.dtype): ret = np.copy(x) @@ -304,7 +304,7 @@ def floor(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def floor_divide( x1: Union[float, np.ndarray], x2: Union[float, np.ndarray], @@ -378,6 +378,7 @@ def isfinite(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarra isfinite.support_native_out = True +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) @_scalar_output_to_0d_array def isinf( x: np.ndarray, @@ -486,7 +487,7 @@ def log2(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def logaddexp( x1: np.ndarray, x2: np.ndarray, /, *, out: Optional[np.ndarray] = None ) -> np.ndarray: @@ -623,7 +624,7 @@ def pow( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def remainder( x1: Union[float, np.ndarray], x2: Union[float, np.ndarray], @@ -865,7 +866,7 @@ def reciprocal( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def deg2rad(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: return np.deg2rad(x, out=out) @@ -874,7 +875,7 @@ def deg2rad(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def rad2deg(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: return np.rad2deg(x, out=out) @@ -891,7 +892,7 @@ def isreal(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def fmod( x1: np.ndarray, x2: np.ndarray, diff --git a/ivy/functional/backends/numpy/experimental/activations.py b/ivy/functional/backends/numpy/experimental/activations.py index e48bbedb99b28..3acf91898788c 100644 --- a/ivy/functional/backends/numpy/experimental/activations.py +++ b/ivy/functional/backends/numpy/experimental/activations.py @@ -55,7 +55,7 @@ def relu6( relu6.support_native_out = True -@with_unsupported_dtypes({"1.26.2 and below": ("bool",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("bool",)}, backend_version) @_scalar_output_to_0d_array def logsigmoid( input: np.ndarray, /, *, complex_mode="jax", out: Optional[np.ndarray] = None @@ -202,3 +202,15 @@ def hardshrink( hardshrink.support_native_out = True + + +@with_unsupported_dtypes({"2.14.0 and below": ("complex",)}, backend_version) +@_scalar_output_to_0d_array +def hardsilu(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: + ret = x * np.divide(relu6(x + 3), 6) + if ivy.exists(out): + return ivy.inplace_update(out, ret).astype(x.dtype) + return ivy.astype(ret, x.dtype) + + +hardsilu.support_native_out = True diff --git a/ivy/functional/backends/numpy/experimental/elementwise.py b/ivy/functional/backends/numpy/experimental/elementwise.py index 47fed86917172..821c287a722b5 100644 --- a/ivy/functional/backends/numpy/experimental/elementwise.py +++ b/ivy/functional/backends/numpy/experimental/elementwise.py @@ -42,7 +42,7 @@ def amin( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("bfloat16",)}, backend_version) def sinc(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: return np.sinc(x).astype(x.dtype) @@ -338,16 +338,18 @@ def modf( # ---digamma---# kLanczosGamma = 7 # aka g kBaseLanczosCoeff = 0.99999999999980993227684700473478 -kLanczosCoefficients = np.array([ - 676.520368121885098567009190444019, - -1259.13921672240287047156078755283, - 771.3234287776530788486528258894, - -176.61502916214059906584551354, - 12.507343278686904814458936853, - -0.13857109526572011689554707, - 9.984369578019570859563e-6, - 1.50563273514931155834e-7, -]) +kLanczosCoefficients = np.array( + [ + 676.520368121885098567009190444019, + -1259.13921672240287047156078755283, + 771.3234287776530788486528258894, + -176.61502916214059906584551354, + 12.507343278686904814458936853, + -0.13857109526572011689554707, + 9.984369578019570859563e-6, + 1.50563273514931155834e-7, + ] +) def digamma( @@ -397,36 +399,40 @@ def digamma( # --- LGAMMA --- # LANCZOS_N = 13 lanczos_g = 6.024680040776729583740234375 -lanczos_num_coeffs = np.array([ - 23531376880.410759688572007674451636754734846804940, - 42919803642.649098768957899047001988850926355848959, - 35711959237.355668049440185451547166705960488635843, - 17921034426.037209699919755754458931112671403265390, - 6039542586.3520280050642916443072979210699388420708, - 1439720407.3117216736632230727949123939715485786772, - 248874557.86205415651146038641322942321632125127801, - 31426415.585400194380614231628318205362874684987640, - 2876370.6289353724412254090516208496135991145378768, - 186056.26539522349504029498971604569928220784236328, - 8071.6720023658162106380029022722506138218516325024, - 210.82427775157934587250973392071336271166969580291, - 2.5066282746310002701649081771338373386264310793408, -]) -lanczos_den_coeffs = np.array([ - 0.0, - 39916800.0, - 120543840.0, - 150917976.0, - 105258076.0, - 45995730.0, - 13339535.0, - 2637558.0, - 357423.0, - 32670.0, - 1925.0, - 66.0, - 1.0, -]) +lanczos_num_coeffs = np.array( + [ + 23531376880.410759688572007674451636754734846804940, + 42919803642.649098768957899047001988850926355848959, + 35711959237.355668049440185451547166705960488635843, + 17921034426.037209699919755754458931112671403265390, + 6039542586.3520280050642916443072979210699388420708, + 1439720407.3117216736632230727949123939715485786772, + 248874557.86205415651146038641322942321632125127801, + 31426415.585400194380614231628318205362874684987640, + 2876370.6289353724412254090516208496135991145378768, + 186056.26539522349504029498971604569928220784236328, + 8071.6720023658162106380029022722506138218516325024, + 210.82427775157934587250973392071336271166969580291, + 2.5066282746310002701649081771338373386264310793408, + ] +) +lanczos_den_coeffs = np.array( + [ + 0.0, + 39916800.0, + 120543840.0, + 150917976.0, + 105258076.0, + 45995730.0, + 13339535.0, + 2637558.0, + 357423.0, + 32670.0, + 1925.0, + 66.0, + 1.0, + ] +) def sinpi(x): @@ -512,45 +518,53 @@ def func(x): # --- erfc --- # # Polynomials for computing erf/erfc. Originally from cephes library. # https://netlib.org/cephes/doubldoc.html -kErfcPCoefficient = np.array([ - 2.46196981473530512524e-10, - 5.64189564831068821977e-1, - 7.46321056442269912687e0, - 4.86371970985681366614e1, - 1.96520832956077098242e2, - 5.26445194995477358631e2, - 9.34528527171957607540e2, - 1.02755188689515710272e3, - 5.57535335369399327526e2, -]) -kErfcQCoefficient = np.array([ - 1.00000000000000000000e0, - 1.32281951154744992508e1, - 8.67072140885989742329e1, - 3.54937778887819891062e2, - 9.75708501743205489753e2, - 1.82390916687909736289e3, - 2.24633760818710981792e3, - 1.65666309194161350182e3, - 5.57535340817727675546e2, -]) -kErfcRCoefficient = np.array([ - 5.64189583547755073984e-1, - 1.27536670759978104416e0, - 5.01905042251180477414e0, - 6.16021097993053585195e0, - 7.40974269950448939160e0, - 2.97886665372100240670e0, -]) -kErfcSCoefficient = np.array([ - 1.00000000000000000000e0, - 2.26052863220117276590e0, - 9.39603524938001434673e0, - 1.20489539808096656605e1, - 1.70814450747565897222e1, - 9.60896809063285878198e0, - 3.36907645100081516050e0, -]) +kErfcPCoefficient = np.array( + [ + 2.46196981473530512524e-10, + 5.64189564831068821977e-1, + 7.46321056442269912687e0, + 4.86371970985681366614e1, + 1.96520832956077098242e2, + 5.26445194995477358631e2, + 9.34528527171957607540e2, + 1.02755188689515710272e3, + 5.57535335369399327526e2, + ] +) +kErfcQCoefficient = np.array( + [ + 1.00000000000000000000e0, + 1.32281951154744992508e1, + 8.67072140885989742329e1, + 3.54937778887819891062e2, + 9.75708501743205489753e2, + 1.82390916687909736289e3, + 2.24633760818710981792e3, + 1.65666309194161350182e3, + 5.57535340817727675546e2, + ] +) +kErfcRCoefficient = np.array( + [ + 5.64189583547755073984e-1, + 1.27536670759978104416e0, + 5.01905042251180477414e0, + 6.16021097993053585195e0, + 7.40974269950448939160e0, + 2.97886665372100240670e0, + ] +) +kErfcSCoefficient = np.array( + [ + 1.00000000000000000000e0, + 2.26052863220117276590e0, + 9.39603524938001434673e0, + 1.20489539808096656605e1, + 1.70814450747565897222e1, + 9.60896809063285878198e0, + 3.36907645100081516050e0, + ] +) # Evaluate the polynomial given coefficients and `x`. @@ -602,3 +616,15 @@ def is_pos_inf(op): return np.where(underflow, result_underflow, result_no_underflow).astype( input_dtype ) + + +# TODO: Remove this once native function is available. +# Compute an approximation of the error function complement (1 - erf(x)). +def erfinv( + x: np.ndarray, + /, + *, + out: Optional[np.ndarray] = None, +) -> np.ndarray: + with ivy.ArrayMode(False): + return np.sqrt(2) * erfc(x) diff --git a/ivy/functional/backends/numpy/experimental/general.py b/ivy/functional/backends/numpy/experimental/general.py index 2077d276631c9..acd4ba7321d4a 100644 --- a/ivy/functional/backends/numpy/experimental/general.py +++ b/ivy/functional/backends/numpy/experimental/general.py @@ -7,7 +7,7 @@ from ivy import with_unsupported_dtypes -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def reduce( operand: np.ndarray, init_value: Union[int, float], diff --git a/ivy/functional/backends/numpy/experimental/layers.py b/ivy/functional/backends/numpy/experimental/layers.py index 8672a0d49f587..8e8344a78d166 100644 --- a/ivy/functional/backends/numpy/experimental/layers.py +++ b/ivy/functional/backends/numpy/experimental/layers.py @@ -729,7 +729,7 @@ def fft( return np.fft.fft(x, n, dim, norm).astype(out_dtype) -@with_supported_dtypes({"1.26.2 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"1.26.3 and below": ("float32", "float64")}, backend_version) def dct( x: np.ndarray, /, @@ -994,7 +994,7 @@ def ifftn( return np.fft.ifftn(x, s, axes, norm).astype(x.dtype) -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def embedding( weights: np.ndarray, indices: np.ndarray, diff --git a/ivy/functional/backends/numpy/experimental/linear_algebra.py b/ivy/functional/backends/numpy/experimental/linear_algebra.py index 1fc7eb964c89e..2224dcad492e1 100644 --- a/ivy/functional/backends/numpy/experimental/linear_algebra.py +++ b/ivy/functional/backends/numpy/experimental/linear_algebra.py @@ -90,7 +90,7 @@ def kron( @with_supported_dtypes( - {"1.26.2 and below": ("float32", "float64", "complex64", "complex128")}, + {"1.26.3 and below": ("float32", "float64", "complex64", "complex128")}, backend_version, ) def matrix_exp( @@ -106,7 +106,7 @@ def matrix_exp( return exp_mat.astype(x.dtype) -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def eig( x: np.ndarray, /, @@ -120,7 +120,7 @@ def eig( eig.support_native_out = False -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def eigvals(x: np.ndarray, /) -> np.ndarray: e = np.linalg.eigvals(x) return e.astype(complex) @@ -217,6 +217,17 @@ def lu_factor( raise IvyNotImplementedException() +def lu_solve( + lu: Tuple[np.ndarray], + p: np.ndarray, + b: np.ndarray, + /, + *, + out: Optional[np.ndarray] = None, +) -> np.ndarray: + raise IvyNotImplementedException() + + def dot( a: np.ndarray, b: np.ndarray, diff --git a/ivy/functional/backends/numpy/experimental/losses.py b/ivy/functional/backends/numpy/experimental/losses.py index 35cc06af9c8c4..359d69c4f30e0 100644 --- a/ivy/functional/backends/numpy/experimental/losses.py +++ b/ivy/functional/backends/numpy/experimental/losses.py @@ -1,5 +1,4 @@ import numpy as np -from typing import Optional from ivy.functional.backends.numpy.helpers import _scalar_output_to_0d_array from ivy.func_wrapper import ( with_unsupported_dtypes, @@ -8,15 +7,15 @@ from . import backend_version -@with_unsupported_dtypes({"1.26.2 and below": ("bool",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("bool",)}, backend_version) @_scalar_output_to_0d_array def huber_loss( input: np.ndarray, target: np.ndarray, /, *, - delta: Optional[float] = 1.0, - reduction: Optional[str] = "mean", + delta: float = 1.0, + reduction: str = "mean", ) -> np.ndarray: abs_diff = np.abs(input - target) quadratic_loss = 0.5 * (abs_diff**2) @@ -32,15 +31,15 @@ def huber_loss( # Implementation of smooth_l1_loss in the given format -@with_unsupported_dtypes({"1.26.2 and below": ("bool",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("bool",)}, backend_version) @_scalar_output_to_0d_array def smooth_l1_loss( input: np.ndarray, target: np.ndarray, /, *, - beta: Optional[float] = 1.0, - reduction: Optional[str] = "mean", + beta: float = 1.0, + reduction: str = "mean", ) -> np.ndarray: if beta < 1e-5: loss = np.abs(input - target) @@ -56,14 +55,14 @@ def smooth_l1_loss( return loss -@with_unsupported_dtypes({"1.26.2 and below": ("bool",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("bool",)}, backend_version) @_scalar_output_to_0d_array def soft_margin_loss( input: np.ndarray, target: np.ndarray, /, *, - reduction: Optional[str] = "mean", + reduction: str = "mean", ) -> np.ndarray: loss = np.sum(np.log1p(np.exp(-input * target))) / input.size @@ -75,15 +74,12 @@ def soft_margin_loss( return loss -def _apply_loss_reduction(loss: np.ndarray, reduction: str, axis, out) -> np.ndarray: +def _apply_loss_reduction(loss: np.ndarray, reduction: str) -> np.ndarray: if reduction == "sum": - return np.sum(loss, axis=axis, out=out) + return np.sum(loss) elif reduction == "mean": - return np.mean(loss, axis=axis, out=out) + return np.mean(loss) else: # reduction == "none" - if out is not None: - out[...] = loss - return out return loss @@ -128,7 +124,7 @@ def _validate_poisson_nll_params( @with_supported_device_and_dtypes( { - "1.25.2 and below": { + "1.26.0 and below": { "cpu": ("float16", "float32", "float64"), } }, @@ -167,3 +163,29 @@ def poisson_nll_loss( cond = np.logical_and(target_arr >= zeroes, target_arr <= ones) loss = loss + np.where(cond, zeroes, striling_approx_term) return _apply_loss_reduction(loss, reduction) + + +@with_supported_device_and_dtypes( + { + "1.26.0 and below": { + "cpu": ("float32", "float64"), + } + }, + backend_version, +) +def hinge_embedding_loss( + input: np.ndarray, + target: np.ndarray, + *, + margin: float = 1.0, + reduction: str = "mean", +) -> np.ndarray: + zero_ = np.zeros([1], dtype=input.dtype) + + relu_part = np.maximum(margin - input, 0) + + loss = np.where(target == 1.0, input, zero_) + np.where( + target == -1.0, relu_part, zero_ + ) + + return _apply_loss_reduction(loss, reduction) diff --git a/ivy/functional/backends/numpy/experimental/manipulation.py b/ivy/functional/backends/numpy/experimental/manipulation.py index 9a86855d16ec6..17b57a75f0f33 100644 --- a/ivy/functional/backends/numpy/experimental/manipulation.py +++ b/ivy/functional/backends/numpy/experimental/manipulation.py @@ -18,7 +18,7 @@ # local import ivy from ivy.functional.backends.numpy.helpers import _scalar_output_to_0d_array -from ivy.func_wrapper import with_supported_dtypes +from ivy.func_wrapper import with_supported_dtypes, handle_out_argument # noinspection PyProtectedMember from . import backend_version @@ -402,6 +402,9 @@ def expand( out: Optional[np.ndarray] = None, ) -> np.ndarray: shape = list(shape) + n_extra_dims = len(shape) - x.ndim + if n_extra_dims > 0: + x = np.expand_dims(x, tuple(range(n_extra_dims))) for i, dim in enumerate(shape): if dim < 0: shape[i] = x.shape[i] @@ -598,3 +601,19 @@ def put_along_axis( put_along_axis.partial_mixed_handler = lambda *args, mode=None, **kwargs: mode in [ "replace", ] + + +@handle_out_argument +def unflatten( + x: np.ndarray, + /, + shape: Tuple[int] = None, + dim: Optional[int] = 0, + *, + out: Optional[np.ndarray] = None, + order: Optional[str] = None, +) -> np.ndarray: + dim = abs(len(x.shape) + dim) if dim < 0 else dim + res_shape = x.shape[:dim] + shape + x.shape[dim + 1 :] + res = np.reshape(x, res_shape) + return res diff --git a/ivy/functional/backends/numpy/experimental/norms.py b/ivy/functional/backends/numpy/experimental/norms.py index a8f2ec9b6a8a3..54a7bfe5362f5 100644 --- a/ivy/functional/backends/numpy/experimental/norms.py +++ b/ivy/functional/backends/numpy/experimental/norms.py @@ -4,7 +4,7 @@ from . import backend_version -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def l1_normalize( x: np.ndarray, /, diff --git a/ivy/functional/backends/numpy/experimental/random.py b/ivy/functional/backends/numpy/experimental/random.py index 16293d4eac407..34960431a3210 100644 --- a/ivy/functional/backends/numpy/experimental/random.py +++ b/ivy/functional/backends/numpy/experimental/random.py @@ -99,6 +99,7 @@ def bernoulli( seed: Optional[int] = None, out: Optional[np.ndarray] = None, ) -> np.ndarray: + dtype = dtype if dtype is not None else probs.dtype if seed is not None: np.random.seed(seed) if logits is not None: diff --git a/ivy/functional/backends/numpy/experimental/searching.py b/ivy/functional/backends/numpy/experimental/searching.py index f49b9c9c3a8fd..191e15681caf9 100644 --- a/ivy/functional/backends/numpy/experimental/searching.py +++ b/ivy/functional/backends/numpy/experimental/searching.py @@ -7,7 +7,7 @@ from . import backend_version -@with_supported_dtypes({"1.26.2 and below": ("int32", "int64")}, backend_version) +@with_supported_dtypes({"1.26.3 and below": ("int32", "int64")}, backend_version) def unravel_index( indices: np.ndarray, shape: Tuple[int], diff --git a/ivy/functional/backends/numpy/experimental/statistical.py b/ivy/functional/backends/numpy/experimental/statistical.py index a69b2a58bd10e..e2dffa696bc2a 100644 --- a/ivy/functional/backends/numpy/experimental/statistical.py +++ b/ivy/functional/backends/numpy/experimental/statistical.py @@ -9,7 +9,7 @@ @with_unsupported_dtypes( - {"1.26.2 and below": ("bfloat16",)}, + {"1.26.3 and below": ("bfloat16",)}, backend_version, ) def histogram( @@ -534,7 +534,7 @@ def __get_index(lst, indices=None, prefix=None): return indices -@with_unsupported_dtypes({"1.26.2 and below": "bfloat16"}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": "bfloat16"}, backend_version) def cummin( x: np.ndarray, /, diff --git a/ivy/functional/backends/numpy/general.py b/ivy/functional/backends/numpy/general.py index 803e582bbbfaf..7db6a0c320298 100644 --- a/ivy/functional/backends/numpy/general.py +++ b/ivy/functional/backends/numpy/general.py @@ -47,7 +47,7 @@ def set_item( val: np.ndarray, /, *, - copy: Optional[bool] = False, + copy: bool = False, ) -> np.ndarray: if copy: x = np.copy(x) @@ -435,7 +435,7 @@ def _vmap(*args): return _vmap -@with_unsupported_dtypes({"1.26.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("bfloat16",)}, backend_version) def isin( elements: np.ndarray, test_elements: np.ndarray, diff --git a/ivy/functional/backends/numpy/linear_algebra.py b/ivy/functional/backends/numpy/linear_algebra.py index d5fe77211f752..98b5096a7c33c 100644 --- a/ivy/functional/backends/numpy/linear_algebra.py +++ b/ivy/functional/backends/numpy/linear_algebra.py @@ -18,7 +18,7 @@ # -------------------# -@with_unsupported_dtypes({"1.26.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16", "complex")}, backend_version) def cholesky( x: np.ndarray, /, *, upper: bool = False, out: Optional[np.ndarray] = None ) -> np.ndarray: @@ -30,7 +30,7 @@ def cholesky( return ret -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def cross( x1: np.ndarray, x2: np.ndarray, @@ -46,7 +46,7 @@ def cross( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def det(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> np.ndarray: return np.linalg.det(x) @@ -63,7 +63,7 @@ def diagonal( return np.diagonal(x, offset=offset, axis1=axis1, axis2=axis2) -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def eigh( x: np.ndarray, /, *, UPLO: str = "L", out: Optional[np.ndarray] = None ) -> Tuple[np.ndarray]: @@ -74,7 +74,7 @@ def eigh( return result_tuple(eigenvalues, eigenvectors) -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def eigvalsh( x: np.ndarray, /, *, UPLO: str = "L", out: Optional[np.ndarray] = None ) -> np.ndarray: @@ -90,7 +90,7 @@ def inner( @with_unsupported_dtypes( - {"1.26.2 and below": ("bfloat16", "float16", "complex")}, + {"1.26.3 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def inv( @@ -110,7 +110,7 @@ def inv( return np.linalg.inv(x) -@with_unsupported_dtypes({"1.26.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16", "bfloat16")}, backend_version) def matmul( x1: np.ndarray, x2: np.ndarray, @@ -140,7 +140,7 @@ def matmul( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16", "bfloat16")}, backend_version) def matrix_norm( x: np.ndarray, /, @@ -148,8 +148,11 @@ def matrix_norm( ord: Union[int, float, Literal[inf, -inf, "fro", "nuc"]] = "fro", axis: Tuple[int, int] = (-2, -1), keepdims: bool = False, + dtype: Optional[np.dtype] = None, out: Optional[np.ndarray] = None, ) -> np.ndarray: + if dtype is not None: + x = ivy.astype(x, dtype) if not isinstance(axis, tuple): axis = tuple(axis) return np.linalg.norm(x, ord=ord, axis=axis, keepdims=keepdims) @@ -162,7 +165,7 @@ def matrix_power( @with_unsupported_dtypes( - {"1.26.2 and below": ("float16", "bfloat16", "complex")}, + {"1.26.3 and below": ("float16", "bfloat16", "complex")}, backend_version, ) @_scalar_output_to_0d_array @@ -201,7 +204,7 @@ def matrix_transpose( return np.swapaxes(x, -1, -2) -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def outer( x1: np.ndarray, x2: np.ndarray, @@ -216,7 +219,7 @@ def outer( outer.support_native_out = True -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def pinv( x: np.ndarray, /, @@ -230,7 +233,7 @@ def pinv( return np.linalg.pinv(x, rtol) -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def qr( x: np.ndarray, /, @@ -243,7 +246,7 @@ def qr( return res(q, r) -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def slogdet( x: np.ndarray, /, @@ -258,7 +261,7 @@ def slogdet( return results(sign, logabsdet) -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def solve( x1: np.ndarray, x2: np.ndarray, @@ -283,7 +286,7 @@ def solve( return ret -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def svd( x: np.ndarray, /, *, compute_uv: bool = True, full_matrices: bool = True ) -> Union[np.ndarray, Tuple[np.ndarray, ...]]: @@ -297,7 +300,7 @@ def svd( return results(D) -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def svdvals( x: np.ndarray, /, *, driver: Optional[str] = None, out: Optional[np.ndarray] = None ) -> np.ndarray: @@ -330,7 +333,7 @@ def tensordot( @_scalar_output_to_0d_array -@with_unsupported_dtypes({"1.26.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16", "bfloat16")}, backend_version) def trace( x: np.ndarray, /, @@ -358,7 +361,7 @@ def vecdot( return np.tensordot(x1, x2, axes=(axis, axis)) -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, backend_version) def eig(x: np.ndarray, /, *, out: Optional[np.ndarray] = None) -> Tuple[np.ndarray]: result_tuple = NamedTuple( "eig", [("eigenvalues", np.ndarray), ("eigenvectors", np.ndarray)] @@ -435,7 +438,7 @@ def vander( @with_unsupported_dtypes( { - "1.26.2 and below": ( + "1.26.3 and below": ( "complex", "unsigned", ) diff --git a/ivy/functional/backends/numpy/manipulation.py b/ivy/functional/backends/numpy/manipulation.py index 0f59794f34ad9..19023b3a23ab9 100644 --- a/ivy/functional/backends/numpy/manipulation.py +++ b/ivy/functional/backends/numpy/manipulation.py @@ -1,12 +1,14 @@ # global import math from numbers import Number -from typing import Union, Tuple, Optional, List, Sequence +from typing import List, Optional, Sequence, Tuple, Union + import numpy as np # local import ivy from ivy.func_wrapper import with_unsupported_dtypes + from . import backend_version @@ -70,7 +72,7 @@ def flip( return x if axis is None: axis = list(range(num_dims)) - if type(axis) is int: + if isinstance(axis, int): axis = [axis] axis = [item + num_dims if item < 0 else item for item in axis] return np.flip(x, axis) @@ -189,7 +191,7 @@ def split( return np.split(x, num_or_size_splits, axis) -@with_unsupported_dtypes({"1.26.2 and below": ("uint64",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("uint64",)}, backend_version) def repeat( x: np.ndarray, /, @@ -233,6 +235,8 @@ def swapaxes( copy: Optional[bool] = None, out: Optional[np.ndarray] = None, ) -> np.ndarray: + if copy: + x = x.copy() return np.swapaxes(x, axis0, axis1) diff --git a/ivy/functional/backends/numpy/module.py b/ivy/functional/backends/numpy/module.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ivy/functional/backends/numpy/random.py b/ivy/functional/backends/numpy/random.py index 3df9936a21769..17a9d19fc4698 100644 --- a/ivy/functional/backends/numpy/random.py +++ b/ivy/functional/backends/numpy/random.py @@ -52,7 +52,7 @@ def random_normal( return np.asarray(np.random.normal(mean, std, shape), dtype=dtype) -@with_unsupported_dtypes({"1.26.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("bfloat16",)}, backend_version) def multinomial( population_size: int, num_samples: int, @@ -69,10 +69,12 @@ def multinomial( np.random.seed(seed) if probs is None: probs = ( - np.ones(( - batch_size, - population_size, - )) + np.ones( + ( + batch_size, + population_size, + ) + ) / population_size ) orig_probs_shape = list(probs.shape) diff --git a/ivy/functional/backends/numpy/sorting.py b/ivy/functional/backends/numpy/sorting.py index bbc49f1076797..78fb8f5d6c925 100644 --- a/ivy/functional/backends/numpy/sorting.py +++ b/ivy/functional/backends/numpy/sorting.py @@ -42,7 +42,7 @@ def sort( # msort -@with_unsupported_dtypes({"1.26.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("complex",)}, backend_version) def msort( a: Union[np.ndarray, list, tuple], /, *, out: Optional[np.ndarray] = None ) -> np.ndarray: diff --git a/ivy/functional/backends/numpy/statistical.py b/ivy/functional/backends/numpy/statistical.py index e2028c726d2b5..bffc814767cc3 100644 --- a/ivy/functional/backends/numpy/statistical.py +++ b/ivy/functional/backends/numpy/statistical.py @@ -14,16 +14,25 @@ # -------------------# +@_scalar_output_to_0d_array def min( x: np.ndarray, /, *, axis: Optional[Union[int, Sequence[int]]] = None, keepdims: bool = False, + initial: Optional[Union[int, float, complex]] = None, + where: Optional[np.ndarray] = None, out: Optional[np.ndarray] = None, ) -> np.ndarray: axis = tuple(axis) if isinstance(axis, list) else axis - return np.asarray(np.amin(a=x, axis=axis, keepdims=keepdims, out=out)) + if where is not None: + ret = np.amin( + a=x, axis=axis, keepdims=keepdims, initial=initial, where=where, out=out + ) + else: + ret = np.amin(a=x, axis=axis, keepdims=keepdims, initial=initial, out=out) + return np.asarray(ret) min.support_native_out = True @@ -169,7 +178,7 @@ def var( # ------# -@with_unsupported_dtypes({"1.26.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"1.26.3 and below": ("bfloat16", "bool")}, backend_version) def cumprod( x: np.ndarray, /, diff --git a/ivy/functional/backends/numpy/utility.py b/ivy/functional/backends/numpy/utility.py index de5597f952940..bba2ef86e03a7 100644 --- a/ivy/functional/backends/numpy/utility.py +++ b/ivy/functional/backends/numpy/utility.py @@ -17,7 +17,7 @@ def all( try: return np.asarray(np.all(x, axis=axis, keepdims=keepdims, out=out)) except np.AxisError as error: - raise ivy.utils.exceptions.IvyIndexError(error) + raise ivy.utils.exceptions.IvyIndexError(error) from error all.support_native_out = True diff --git a/ivy/functional/backends/paddle/__init__.py b/ivy/functional/backends/paddle/__init__.py index 86deeb0c9b9d6..0e5f0fa31e9ee 100644 --- a/ivy/functional/backends/paddle/__init__.py +++ b/ivy/functional/backends/paddle/__init__.py @@ -175,7 +175,7 @@ def rep_method(*args, **kwargs): ), } valid_int_dtypes = { - "2.5.2 and below": ( + "2.6.0 and below": ( ivy.int8, ivy.int16, ivy.int32, @@ -187,8 +187,8 @@ def rep_method(*args, **kwargs): "2.4.2 and below": (ivy.float16, ivy.float32, ivy.float64), "2.5.0 and above": (ivy.bfloat16, ivy.float16, ivy.float32, ivy.float64), } -valid_uint_dtypes = {"2.5.2 and below": (ivy.uint8,)} -valid_complex_dtypes = {"2.5.2 and below": (ivy.complex64, ivy.complex128)} +valid_uint_dtypes = {"2.6.0 and below": (ivy.uint8,)} +valid_complex_dtypes = {"2.6.0 and below": (ivy.complex64, ivy.complex128)} # leave these untouched valid_dtypes = _dtype_from_version(valid_dtypes, backend_version) @@ -228,10 +228,10 @@ def rep_method(*args, **kwargs): ), } -invalid_int_dtypes = {"2.5.2 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} +invalid_int_dtypes = {"2.6.0 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} invalid_float_dtypes = {"2.4.2 and below": (ivy.bfloat16,), "2.5.0 and above": ()} -invalid_uint_dtypes = {"2.5.2 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} -invalid_complex_dtypes = {"2.5.2 and below": ()} +invalid_uint_dtypes = {"2.6.0 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} +invalid_complex_dtypes = {"2.6.0 and below": ()} # leave these untouched invalid_dtypes = _dtype_from_version(invalid_dtypes, backend_version) @@ -297,8 +297,14 @@ def closest_valid_dtype(type=None, /, as_native=False): from .experimental import * from . import control_flow_ops from .control_flow_ops import * +from . import module +from .module import * + # sub-backends from . import sub_backends from .sub_backends import * + + +NativeModule = paddle.nn.Layer diff --git a/ivy/functional/backends/paddle/activations.py b/ivy/functional/backends/paddle/activations.py index 59c421f43ae6b..88975658f1fee 100644 --- a/ivy/functional/backends/paddle/activations.py +++ b/ivy/functional/backends/paddle/activations.py @@ -22,17 +22,25 @@ @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "complex")}, + { + "2.6.0 and below": ( + "float32", + "float64", + "complex64", + ) + }, backend_version, ) -def relu(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: +def relu( + x: paddle.Tensor, /, *, complex_mode="jax", out: Optional[paddle.Tensor] = None +) -> paddle.Tensor: if paddle.is_complex(x): return paddle.complex(F.relu(x.real()), F.relu(x.imag())) return F.relu(x) @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "complex")}}, backend_version, ) def leaky_relu( @@ -52,7 +60,7 @@ def leaky_relu( @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "complex")}}, backend_version, ) def gelu( @@ -76,7 +84,7 @@ def gelu( @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "complex")}}, backend_version, ) def sigmoid( @@ -88,7 +96,7 @@ def sigmoid( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("bfloat16", "float16")}}, backend_version + {"2.6.0 and below": {"cpu": ("bfloat16", "float16")}}, backend_version ) def softmax( x: paddle.Tensor, @@ -138,7 +146,7 @@ def softplus( # Softsign @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16", "bfloat16")}}, backend_version + {"2.6.0 and below": {"cpu": ("float16", "bfloat16")}}, backend_version ) def softsign( x: paddle.Tensor, @@ -152,7 +160,7 @@ def softsign( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16", "bfloat16")}}, backend_version + {"2.6.0 and below": {"cpu": ("float16", "bfloat16")}}, backend_version ) def log_softmax( x: paddle.Tensor, @@ -171,7 +179,7 @@ def log_softmax( @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "complex")}}, backend_version, ) def mish( @@ -187,7 +195,7 @@ def mish( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, backend_version + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version ) def hardswish( x: paddle.Tensor, diff --git a/ivy/functional/backends/paddle/control_flow_ops.py b/ivy/functional/backends/paddle/control_flow_ops.py index 9d14c8233819a..221625819eb89 100644 --- a/ivy/functional/backends/paddle/control_flow_ops.py +++ b/ivy/functional/backends/paddle/control_flow_ops.py @@ -12,6 +12,10 @@ def if_else(cond, body_fn, orelse_fn, vars): def while_loop(test_fn, body_fn, vars): result = vars + if isinstance(vars, dict): + result = list(vars.values()) while test_fn(*result): result = body_fn(*result) + if not isinstance(result, tuple): + result = (result,) return result diff --git a/ivy/functional/backends/paddle/creation.py b/ivy/functional/backends/paddle/creation.py index e91fcc479ba5d..e3b802febecae 100644 --- a/ivy/functional/backends/paddle/creation.py +++ b/ivy/functional/backends/paddle/creation.py @@ -11,6 +11,7 @@ import ivy from ivy.func_wrapper import ( with_unsupported_device_and_dtypes, + with_supported_device_and_dtypes, ) from ivy.functional.ivy.creation import ( _asarray_to_native_arrays_and_back, @@ -142,7 +143,7 @@ def empty_like( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "uint8", "int8", @@ -356,7 +357,7 @@ def _slice_at_axis(sl, axis): @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("uint16", "bfloat16", "float16")}}, backend_version + {"2.6.0 and below": {"cpu": ("uint16", "bfloat16", "float16")}}, backend_version ) def linspace( start: Union[paddle.Tensor, float], @@ -414,7 +415,7 @@ def linspace( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -471,6 +472,22 @@ def ones( return paddle.ones(shape=shape).cast(dtype) +@with_supported_device_and_dtypes( + { + "2.6.0 and below": { + "cpu": ( + "int32", + "int64", + "float64", + "float32", + "complex128", + "complex64", + "bool", + ) + } + }, + backend_version, +) def ones_like( x: paddle.Tensor, /, @@ -484,7 +501,7 @@ def ones_like( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -503,7 +520,7 @@ def tril( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -530,6 +547,10 @@ def zeros( return paddle.zeros(shape=shape).cast(dtype) +@with_unsupported_device_and_dtypes( + {"2.6.0 and below": {"cpu": ("uint8", "int8", "int16", "float16", "bfloat16")}}, + backend_version, +) def zeros_like( x: paddle.Tensor, /, @@ -551,7 +572,7 @@ def zeros_like( def copy_array( x: paddle.Tensor, *, - to_ivy_array: Optional[bool] = True, + to_ivy_array: bool = True, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: if 0 in x.shape: @@ -616,14 +637,14 @@ def one_hot( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def frombuffer( buffer: bytes, - dtype: Optional[paddle.dtype] = float, - count: Optional[int] = -1, - offset: Optional[int] = 0, + dtype: paddle.dtype = float, + count: int = -1, + offset: int = 0, ) -> paddle.Tensor: dtype_bytes = int(ivy.Dtype(dtype).dtype_bits / 8) if str(dtype) == "bool": @@ -658,7 +679,7 @@ def frombuffer( def triu_indices( n_rows: int, n_cols: Optional[int] = None, - k: Optional[int] = 0, + k: int = 0, /, *, device: core.Place = None, diff --git a/ivy/functional/backends/paddle/data_type.py b/ivy/functional/backends/paddle/data_type.py index 6112117f2e6d5..48833be5155de 100644 --- a/ivy/functional/backends/paddle/data_type.py +++ b/ivy/functional/backends/paddle/data_type.py @@ -143,7 +143,7 @@ def broadcast_arrays(*arrays: paddle.Tensor) -> List[paddle.Tensor]: @with_unsupported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "uint8", "int8", "int16", @@ -231,7 +231,7 @@ def as_ivy_dtype(dtype_in: Union[paddle.dtype, str, bool, int, float], /) -> ivy def as_native_dtype( - dtype_in: Union[paddle.dtype, str, bool, int, float] + dtype_in: Union[paddle.dtype, str, bool, int, float], ) -> paddle.dtype: if dtype_in is int: return ivy.default_int_dtype(as_native=True) diff --git a/ivy/functional/backends/paddle/elementwise.py b/ivy/functional/backends/paddle/elementwise.py index 146d7e53ee102..f7ee481f872c7 100644 --- a/ivy/functional/backends/paddle/elementwise.py +++ b/ivy/functional/backends/paddle/elementwise.py @@ -1,15 +1,16 @@ # global -from typing import Union, Optional - import math +from typing import Optional, Union + import paddle -import ivy.functional.backends.paddle as paddle_backend + import ivy +import ivy.functional.backends.paddle as paddle_backend from ivy import promote_types_of_inputs from ivy.func_wrapper import ( - with_unsupported_device_and_dtypes, with_supported_device_and_dtypes, with_supported_dtypes, + with_unsupported_device_and_dtypes, with_unsupported_dtypes, ) @@ -28,7 +29,7 @@ def _elementwise_helper(x1, x2): @with_unsupported_dtypes( - {"2.5.1 and below": ("int8", "uint8", "float16", "bool", "bfloat16")}, + {"2.6.0 and below": ("int8", "int16", "uint8", "float16", "bool", "bfloat16")}, backend_version, ) def add( @@ -59,7 +60,7 @@ def bitwise_xor( @with_supported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "float16", "float32", "float64", @@ -79,7 +80,7 @@ def bitwise_invert( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -98,6 +99,10 @@ def isfinite( return paddle.isfinite(x) +@with_unsupported_dtypes( + {"2.6.0 and below": ("complex", "uint8")}, + backend_version, +) def isinf( x: paddle.Tensor, /, @@ -116,6 +121,10 @@ def isinf( return paddle.zeros(shape=x.shape, dtype=bool) +@with_unsupported_dtypes( + {"2.6.0 and below": ("bfloat16",)}, + backend_version, +) def equal( x1: Union[float, paddle.Tensor], x2: Union[float, paddle.Tensor], @@ -124,20 +133,15 @@ def equal( out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: x1, x2, ret_dtype = _elementwise_helper(x1, x2) - diff = paddle_backend.subtract(x1, x2) - ret = paddle_backend.logical_and( - paddle_backend.less_equal(diff, 0), paddle_backend.greater_equal(diff, 0) - ) - # ret result is sufficient for all cases except where the value is +/-INF of NaN - return paddle_backend.where( - paddle_backend.isnan(diff), - ~paddle_backend.logical_or(paddle_backend.isnan(x1), paddle_backend.isnan(x2)), - ret, - ) + if paddle.is_complex(x1): + real = paddle.equal(x1.real(), x2.real()) + imag = paddle.equal(x1.imag(), x2.imag()) + return paddle_backend.logical_and(real, imag) + return paddle.equal(x1, x2) -@with_unsupported_dtypes( - {"2.5.1 and below": ("int8", "int16", "bfloat16", "unsigned", "float16")}, +@with_supported_dtypes( + {"2.6.0 and below": ("bool", "float32", "float64", "int32", "int64", "complex")}, backend_version, ) def less_equal( @@ -148,8 +152,8 @@ def less_equal( out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: x1, x2, ret_dtype = _elementwise_helper(x1, x2) - if paddle.is_complex(x1): - if paddle.is_complex(x1): + if isinstance(x1, paddle.Tensor) and isinstance(x2, paddle.Tensor): + if paddle.is_complex(x1) and paddle.is_complex(x2): real = paddle.less_equal(x1.real(), x2.real()) imag = paddle.less_equal(x1.imag(), x2.imag()) return paddle_backend.logical_and(real, imag) @@ -169,7 +173,7 @@ def bitwise_and( @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "complex")}, + {"2.6.0 and below": ("float32", "float64", "complex")}, backend_version, ) def ceil(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -179,7 +183,7 @@ def ceil(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_dtypes( - {"2.5.1 and below": ("float16", "float32", "float64", "complex")}, + {"2.6.0 and below": ("float32", "float64", "complex")}, backend_version, ) def floor(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -190,7 +194,7 @@ def floor(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float32", "float64", @@ -205,8 +209,7 @@ def asin(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_dtypes( { - "2.5.2 and below": ( - "float16", + "2.6.0 and below": ( "float32", "float64", ) @@ -218,7 +221,7 @@ def asinh(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16", "float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float16", "float32", "float64", "complex")}}, backend_version, ) def sign( @@ -232,7 +235,7 @@ def sign( @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "complex")}, backend_version + {"2.6.0 and below": ("float32", "float64", "complex")}, backend_version ) def sqrt(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: """Calculate the square root with type handling.""" @@ -247,7 +250,7 @@ def sqrt(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float32", "float64", @@ -261,7 +264,7 @@ def cosh(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "complex")}, backend_version + {"2.6.0 and below": ("float32", "float64", "complex")}, backend_version ) def log10(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: if paddle.is_complex(x): @@ -273,7 +276,7 @@ def log10(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "complex")}, + {"2.6.0 and below": ("float32", "float64", "complex")}, backend_version, ) def log2(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -286,7 +289,7 @@ def log2(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "complex")}, + {"2.6.0 and below": ("float32", "float64", "complex")}, backend_version, ) def log1p(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -297,7 +300,7 @@ def log1p(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle @with_supported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "float", "int32", "int64", @@ -314,7 +317,7 @@ def isnan(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle @with_unsupported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "int8", "uint8", ) @@ -329,23 +332,17 @@ def less( out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: x1, x2, ret_dtype = _elementwise_helper(x1, x2) - if paddle.is_complex(x1): - real = paddle.less_than(x1.real(), x2.real()) - imag = paddle.less_than(x1.imag(), x2.imag()) - return logical_and(real, imag) + if isinstance(x1, paddle.Tensor) and isinstance(x2, paddle.Tensor): + if paddle.is_complex(x1) and paddle.is_complex(x2): + real = paddle.less_than(x1.real(), x2.real()) + imag = paddle.less_than(x1.imag(), x2.imag()) + return logical_and(real, imag) return paddle.less_than(x1, x2) -@with_unsupported_dtypes( - { - "2.5.1 and below": ( - "int8", - "int16", - "uint8", - "float16", - ) - }, +@with_supported_dtypes( + {"2.6.0 and below": ("bool", "int32", "int64", "float32", "float64", "complex")}, backend_version, ) def multiply( @@ -356,12 +353,20 @@ def multiply( out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: x1, x2, ret_dtype = _elementwise_helper(x1, x2) + if isinstance(x1, paddle.Tensor) and isinstance(x2, paddle.Tensor): + if paddle.is_complex(x1) or paddle.is_complex(x2): + a, b = x1.real(), x1.imag() + c, d = x2.real(), x2.imag() + real = a * c - b * d + imag = a * d + b * c + return paddle.complex(real, imag) + return paddle.multiply(x1, x2).astype(ret_dtype) @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float32", "float64", @@ -374,7 +379,7 @@ def cos(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.T return paddle.cos(x) -@with_unsupported_dtypes({"2.5.1 and below": ("uint", "float16")}, backend_version) +@with_unsupported_dtypes({"2.6.0 and below": ("uint8", "float16")}, backend_version) def logical_not( x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None ) -> paddle.Tensor: @@ -386,7 +391,7 @@ def logical_not( @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "int32", "int64", "complex")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64", "complex")}, backend_version, ) def divide( @@ -396,18 +401,19 @@ def divide( *, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: - if paddle.is_complex(x1) or paddle.is_complex(x2): - angle_value = paddle.angle(x1) - paddle.angle(x2) - abs_value = paddle.abs(x1) / paddle.abs(x2) - return paddle.complex( - abs_value * paddle.cos(angle_value), abs_value * paddle.sin(angle_value) - ) - x1, x2, ret_dtype = _elementwise_helper(x1, x2) - return (x1 / x2).astype(ret_dtype) + if isinstance(x1, paddle.Tensor) and isinstance(x2, paddle.Tensor): + if paddle.is_complex(x1) or paddle.is_complex(x2): + angle_value = paddle.angle(x1) - paddle.angle(x2) + abs_value = paddle.abs(x1) / paddle.abs(x2) + return paddle.complex( + abs_value * paddle.cos(angle_value), abs_value * paddle.sin(angle_value) + ) + x1, x2, _ = _elementwise_helper(x1, x2) + return x1 / x2 @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version, ) def fmin( @@ -431,7 +437,7 @@ def _apply_for_real_and_imag(fn, x1, x2): @with_supported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "bool", "float32", "float64", @@ -451,8 +457,8 @@ def greater( out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: x1, x2, ret_dtype = _elementwise_helper(x1, x2) - if paddle.is_complex(x1): - if paddle.is_complex(x1): + if isinstance(x1, paddle.Tensor) and isinstance(x2, paddle.Tensor): + if paddle.is_complex(x1) and paddle.is_complex(x2): real = paddle.greater_than(x1.real(), x2.real()) imag = paddle.greater_than(x1.imag(), x2.imag()) return paddle.logical_and(real, imag) @@ -461,7 +467,7 @@ def greater( @with_supported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "bool", "float32", "float64", @@ -481,8 +487,8 @@ def greater_equal( out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: x1, x2, ret_dtype = _elementwise_helper(x1, x2) - if paddle.is_complex(x1): - if paddle.is_complex(x1): + if isinstance(x1, paddle.Tensor) and isinstance(x2, paddle.Tensor): + if paddle.is_complex(x1) and paddle.is_complex(x2): real = paddle.greater_equal(x1.real(), x2.real()) imag = paddle.greater_equal(x1.imag(), x2.imag()) return paddle.logical_and(real, imag) @@ -491,7 +497,7 @@ def greater_equal( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float32", "float64", @@ -515,7 +521,7 @@ def acos(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("bool", "float32", "int32", "float64", "int64", "complex") } }, @@ -526,13 +532,14 @@ def logical_xor( ) -> paddle.Tensor: x1, x2, ret_dtype = _elementwise_helper(x1, x2) if paddle.is_complex(x1): - return _apply_for_real_and_imag(paddle.logical_xor, x1, x2) + x1 = paddle.cast(x1, paddle.bool) + x2 = paddle.cast(x2, paddle.bool) return paddle.logical_xor(x1, x2) @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("bool", "float32", "int32", "float64", "int64", "complex") } }, @@ -548,7 +555,7 @@ def logical_and( @with_supported_dtypes( - {"2.5.1 and below": ("bool", "float32", "int32", "float64", "int64", "complex")}, + {"2.6.0 and below": ("bool", "float32", "int32", "float64", "int64", "complex")}, backend_version, ) def logical_or( @@ -562,7 +569,7 @@ def logical_or( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float32", "float64", @@ -585,7 +592,7 @@ def acosh(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "complex")}}, backend_version, ) def sin(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -599,7 +606,7 @@ def sin(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.T @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "int8", "int16", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int8", "int16", "int32", "int64")}, backend_version, ) def negative( @@ -608,6 +615,10 @@ def negative( return paddle.neg(x) +@with_supported_dtypes( + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, + backend_version, +) def not_equal( x1: Union[float, paddle.Tensor], x2: Union[float, paddle.Tensor], @@ -619,7 +630,7 @@ def not_equal( @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("bfloat16", "float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "complex")}}, backend_version, ) def tanh(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -638,7 +649,7 @@ def tanh(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "uint8", "int8", "int32", @@ -663,7 +674,7 @@ def floor_divide( @with_supported_dtypes( - {"2.5.1 and below": ("bool", "uint8", "int8", "int16", "int32", "int64")}, + {"2.6.0 and below": ("bool", "uint8", "int8", "int16", "int32", "int64")}, backend_version, ) def bitwise_or( @@ -678,7 +689,7 @@ def bitwise_or( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "complex")}, backend_version + {"2.6.0 and below": ("float32", "float64", "complex")}, backend_version ) def sinh(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: if paddle.is_complex(x): @@ -702,7 +713,7 @@ def positive( @with_supported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "int32", "int64", "float32", @@ -719,7 +730,7 @@ def square( @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "int32", "int64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "int32", "int64", "complex")}}, backend_version, ) def pow( @@ -760,7 +771,7 @@ def _round_half_to_even(x): # This function aims to mimic the behavior of np.round similar to how tf.experimental.numpy.round does # noqa: E501 # Reference for tf.experimental.numpy.round:https://github.com/tensorflow/tensorflow/blob/v2.13.0/tensorflow/python/ops/numpy_ops/np_array_ops.py#L724 # noqa: E501 @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("bfloat16", "float16", "complex")}}, backend_version + {"2.6.0 and below": {"cpu": ("bfloat16", "float16", "complex")}}, backend_version ) def round( x: paddle.Tensor, /, *, decimals: int = 0, out: Optional[paddle.Tensor] = None @@ -786,7 +797,7 @@ def round( @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "complex")}, backend_version + {"2.6.0 and below": ("float32", "float64", "complex")}, backend_version ) def trunc(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: if paddle.is_complex(x): @@ -794,7 +805,7 @@ def trunc(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle return paddle.trunc(x) -@with_supported_dtypes({"2.5.2 and below": ("float64", "float32")}, backend_version) +@with_supported_dtypes({"2.6.0 and below": ("float64", "float32")}, backend_version) def trapz( y: paddle.Tensor, /, @@ -841,6 +852,10 @@ def trapz( return ret +@with_supported_device_and_dtypes( + {"2.6.0 and below": {"cpu": ("float32", "float64", "int32", "int64", "complex")}}, + backend_version, +) def abs( x: Union[float, paddle.Tensor], /, @@ -853,7 +868,7 @@ def abs( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, backend_version + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version ) def logaddexp( x1: paddle.Tensor, x2: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None @@ -866,7 +881,7 @@ def logaddexp( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, backend_version + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version ) def logaddexp2( x1: Union[paddle.Tensor, float, list, tuple], @@ -881,7 +896,7 @@ def logaddexp2( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -902,7 +917,7 @@ def real(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "complex")}}, backend_version, ) def tan(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -913,7 +928,7 @@ def tan(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.T @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "complex")}}, backend_version, ) def atan(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -925,7 +940,7 @@ def atan(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int32", "int64", @@ -944,7 +959,7 @@ def atan2( @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "complex")}, + {"2.6.0 and below": ("float32", "float64", "complex")}, backend_version, ) def log(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -954,7 +969,7 @@ def log(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.T @with_supported_dtypes( - {"2.5.1 and below": ("int32", "int64", "float32", "float64", "complex")}, + {"2.6.0 and below": ("int32", "int64", "float32", "float64", "complex")}, backend_version, ) def exp(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -966,6 +981,10 @@ def exp(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.T return paddle.exp(x) +@with_supported_dtypes( + {"2.6.0 and below": ("int32", "int64", "float32", "float64", "complex")}, + backend_version, +) def exp2( x: Union[paddle.Tensor, float, list, tuple], /, @@ -977,7 +996,7 @@ def exp2( @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def subtract( x1: Union[float, paddle.Tensor], @@ -995,7 +1014,7 @@ def subtract( @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "int32", "int64")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "int32", "int64")}}, backend_version, ) def remainder( @@ -1021,7 +1040,7 @@ def remainder( @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64", "complex")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64", "complex")}}, backend_version, ) def atanh(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -1060,13 +1079,13 @@ def bitwise_left_shift( # ------# -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, backend_version) def erf(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: return paddle.erf(x) @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "int32", "int64", "complex")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64", "complex")}, backend_version, ) def minimum( @@ -1079,7 +1098,13 @@ def minimum( ) -> paddle.Tensor: x1, x2, ret_dtype = _elementwise_helper(x1, x2) if paddle.is_complex(x1): - use_where = True + real_comparison = paddle.real(x1) < paddle.real(x2) + imag_comparison = paddle_backend.logical_and( + paddle.real(x1) == paddle.real(x2), paddle.imag(x1) < paddle.imag(x2) + ) + return paddle_backend.where( + paddle_backend.logical_or(real_comparison, imag_comparison), x1, x2 + ).astype(ret_dtype) if use_where: return paddle_backend.where(paddle_backend.less_equal(x1, x2), x1, x2).astype( @@ -1090,7 +1115,7 @@ def minimum( @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "int32", "int64", "complex")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64", "complex")}, backend_version, ) def maximum( @@ -1103,7 +1128,13 @@ def maximum( ) -> paddle.Tensor: x1, x2, ret_dtype = _elementwise_helper(x1, x2) if paddle.is_complex(x1): - use_where = True + real_comparison = paddle.real(x1) > paddle.real(x2) + imag_comparison = paddle_backend.logical_and( + paddle.real(x1) == paddle.real(x2), paddle.imag(x1) > paddle.imag(x2) + ) + return paddle_backend.where( + paddle_backend.logical_or(real_comparison, imag_comparison), x1, x2 + ).astype(ret_dtype) if use_where: return paddle_backend.where( paddle_backend.greater_equal(x1, x2), x1, x2 @@ -1113,7 +1144,7 @@ def maximum( @with_supported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "float32", "float64", ) @@ -1127,7 +1158,7 @@ def reciprocal( @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def deg2rad( x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None @@ -1136,7 +1167,7 @@ def deg2rad( @with_supported_dtypes( - {"2.5.1 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def rad2deg( x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None @@ -1163,6 +1194,10 @@ def isreal( return paddle.ones_like(x, dtype="bool") +@with_supported_dtypes( + {"2.6.0 and below": ("float32", "float64", "int32", "int64", "complex")}, + backend_version, +) def fmod( x1: paddle.Tensor, x2: paddle.Tensor, @@ -1175,7 +1210,7 @@ def fmod( return paddle_backend.where(paddle_backend.less(x1, 0), -res, res) -@with_supported_dtypes({"2.5.2 and below": ("int32", "int64")}, backend_version) +@with_supported_dtypes({"2.6.0 and below": ("int32", "int64")}, backend_version) def lcm( x1: paddle.Tensor, x2: paddle.Tensor, @@ -1188,7 +1223,7 @@ def lcm( @with_supported_dtypes( { - "2.5.1 and below": ( + "2.6.0 and below": ( "float32", "float64", "complex", @@ -1210,7 +1245,7 @@ def angle( @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int32", "int64")}}, backend_version + {"2.6.0 and below": {"cpu": ("int32", "int64")}}, backend_version ) def gcd( x1: Union[paddle.Tensor, int, list, tuple], @@ -1223,7 +1258,7 @@ def gcd( return paddle.gcd(x1, x2) -@with_supported_dtypes({"2.5.2 and below": ("complex",)}, backend_version) +@with_supported_dtypes({"2.6.0 and below": ("complex",)}, backend_version) def imag( val: paddle.Tensor, /, diff --git a/ivy/functional/backends/paddle/experimental/activations.py b/ivy/functional/backends/paddle/experimental/activations.py index 8d13b487369da..ca193162facc0 100644 --- a/ivy/functional/backends/paddle/experimental/activations.py +++ b/ivy/functional/backends/paddle/experimental/activations.py @@ -14,7 +14,7 @@ @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16", "bfloat16")}}, backend_version + {"2.6.0 and below": {"cpu": ("float16", "bfloat16")}}, backend_version ) def logit( x: paddle.Tensor, @@ -44,7 +44,7 @@ def logit( ).cast(x.dtype) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, backend_version) def thresholded_relu( x: paddle.Tensor, /, @@ -56,18 +56,21 @@ def thresholded_relu( @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64")}, backend_version + {"2.6.0 and below": ("complex", "float32", "float64")}, backend_version ) def relu6( x: paddle.Tensor, /, *, complex_mode="jax", out: Optional[paddle.Tensor] = None ) -> paddle.Tensor: if paddle.is_complex(x): - return paddle.complex(F.relu6(x.real()), F.relu6(x.imag())) + if x.real > 0 and x.real <= 6: + return x.astype(x.dtype) + else: + return paddle_backend.zeros_like(x).astype(x.dtype) return F.relu6(x) @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64")}, backend_version + {"2.6.0 and below": ("complex", "float32", "float64")}, backend_version ) def logsigmoid( input: paddle.Tensor, /, *, complex_mode="jax", out: Optional[paddle.Tensor] = None @@ -82,7 +85,7 @@ def logsigmoid( @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64")}, backend_version + {"2.6.0 and below": ("complex", "float32", "float64")}, backend_version ) def selu(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: if paddle.is_complex(x): @@ -101,7 +104,7 @@ def selu(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64")}, backend_version + {"2.6.0 and below": ("complex", "float32", "float64")}, backend_version ) def silu(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: if paddle.is_complex(x): @@ -110,7 +113,7 @@ def silu(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64")}, backend_version + {"2.6.0 and below": ("complex", "float32", "float64")}, backend_version ) def elu( x: paddle.Tensor, /, *, alpha: float = 1.0, out: Optional[paddle.Tensor] = None @@ -128,7 +131,7 @@ def elu( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("bfloat16", "float16")}}, backend_version + {"2.6.0 and below": {"cpu": ("bfloat16", "float16")}}, backend_version ) def hardtanh( x: paddle.Tensor, @@ -154,7 +157,7 @@ def hardtanh( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("bfloat16", "float16")}}, backend_version + {"2.6.0 and below": {"cpu": ("bfloat16", "float16")}}, backend_version ) def tanhshrink( x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None @@ -167,7 +170,7 @@ def tanhshrink( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("bfloat16", "float16")}}, backend_version + {"2.6.0 and below": {"cpu": ("bfloat16", "float16")}}, backend_version ) def threshold( x: paddle.Tensor, @@ -188,7 +191,7 @@ def threshold( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("bfloat16", "float16")}}, backend_version + {"2.6.0 and below": {"cpu": ("bfloat16", "float16")}}, backend_version ) def softshrink( x: paddle.Tensor, /, *, lambd: float = 0.5, out: Optional[paddle.Tensor] = None @@ -204,7 +207,7 @@ def softshrink( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("bfloat16", "float16")}}, backend_version + {"2.6.0 and below": {"cpu": ("bfloat16", "float16")}}, backend_version ) def celu( x: paddle.Tensor, @@ -219,7 +222,7 @@ def celu( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("float32", "float64"), "gpu": ("uint16", "float16", "float32", "float64"), } @@ -238,7 +241,7 @@ def scaled_tanh( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16", "bfloat16")}}, + {"2.6.0 and below": {"cpu": ("float16", "bfloat16")}}, backend_version, ) def hardshrink( @@ -252,3 +255,10 @@ def hardshrink( F.hardshrink(x.img(), threshold=lambd), ) return F.hardshrink(x.cast("float32"), threshold=lambd).cast(x.dtype) + + +@with_supported_dtypes({"2.5.1 and below": ("float32", "float64")}, backend_version) +def hardsilu( + x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None +) -> paddle.Tensor: + return F.hardswish(x) diff --git a/ivy/functional/backends/paddle/experimental/creation.py b/ivy/functional/backends/paddle/experimental/creation.py index 6dedf411c06a7..dda4e9820a368 100644 --- a/ivy/functional/backends/paddle/experimental/creation.py +++ b/ivy/functional/backends/paddle/experimental/creation.py @@ -183,7 +183,7 @@ def unsorted_segment_sum( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -257,7 +257,7 @@ def unsorted_segment_mean( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("float16", "int8", "int16", "uint8", "complex", "bool") } }, diff --git a/ivy/functional/backends/paddle/experimental/elementwise.py b/ivy/functional/backends/paddle/experimental/elementwise.py index 1d9802da6c154..c26898376ea69 100644 --- a/ivy/functional/backends/paddle/experimental/elementwise.py +++ b/ivy/functional/backends/paddle/experimental/elementwise.py @@ -20,7 +20,7 @@ @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "float32", "float64", "int32", @@ -42,7 +42,7 @@ def amax( @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "float32", "float64", "int32", @@ -63,7 +63,7 @@ def amin( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, backend_version, ) def lgamma( @@ -73,7 +73,7 @@ def lgamma( @with_supported_dtypes( - {"2.5.2 and below": ("float64", "float32", "int32", "int64")}, + {"2.6.0 and below": ("float64", "float32", "int32", "int64")}, backend_version, ) def fmax( @@ -89,7 +89,7 @@ def fmax( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, backend_version + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version ) def sinc(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: y = ivy.pi * paddle.where(x == 0, paddle.to_tensor(1.0e-20, dtype=x.dtype), x) @@ -137,6 +137,9 @@ def ldexp( return ivy.astype(ret, out_dtype, copy=False) +@with_unsupported_device_and_dtypes( + {"2.6.0 and below": {"cpu": ("float16", "bfloat16")}}, backend_version +) def copysign( x1: Union[paddle.Tensor, Number], x2: Union[paddle.Tensor, Number], @@ -153,7 +156,7 @@ def copysign( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("uint8", "int8", "int16", "float16")}}, + {"2.6.0 and below": {"cpu": ("uint8", "int8", "int16", "float16")}}, backend_version, ) def nansum( @@ -162,7 +165,7 @@ def nansum( *, axis: Optional[Union[Tuple[int, ...], int]] = None, dtype: Optional[paddle.dtype] = None, - keepdims: Optional[bool] = False, + keepdims: bool = False, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: result = paddle.nansum(x, axis=axis, dtype=dtype, keepdim=keepdims) @@ -172,23 +175,23 @@ def nansum( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, backend_version + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version ) def isclose( a: paddle.Tensor, b: paddle.Tensor, /, *, - rtol: Optional[float] = 1e-05, - atol: Optional[float] = 1e-08, - equal_nan: Optional[bool] = False, + rtol: float = 1e-05, + atol: float = 1e-08, + equal_nan: bool = False, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: return paddle.isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan) @with_unsupported_dtypes( - {"2.5.2 and below": ("float16", "int16", "int8", "uint8")}, backend_version + {"2.6.0 and below": ("float16", "int16", "int8", "uint8")}, backend_version ) def diff( x: Union[paddle.Tensor, list, tuple], @@ -214,6 +217,9 @@ def _tensor(val): ) +@with_unsupported_device_and_dtypes( + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version +) def signbit( x: Union[paddle.Tensor, float, int, list, tuple], /, @@ -237,7 +243,7 @@ def hypot( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -258,14 +264,15 @@ def allclose( x2: paddle.Tensor, /, *, - rtol: Optional[float] = 1e-05, - atol: Optional[float] = 1e-08, - equal_nan: Optional[bool] = False, + rtol: float = 1e-05, + atol: float = 1e-08, + equal_nan: bool = False, out: Optional[paddle.Tensor] = None, ) -> bool: return paddle.allclose(x1, x2, rtol=rtol, atol=atol, equal_nan=equal_nan).squeeze(0) +@with_unsupported_dtypes({"2.6.0 and below": ("float16",)}, backend_version) def fix( x: paddle.Tensor, /, @@ -277,7 +284,7 @@ def fix( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, backend_version + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version ) def nextafter( x1: paddle.Tensor, @@ -318,7 +325,7 @@ def nextafter( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -396,16 +403,16 @@ def _np_ndim(x): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, backend_version, ) def gradient( x: paddle.Tensor, /, *, - spacing: Optional[Union[int, list, tuple]] = 1, + spacing: Union[int, list, tuple] = 1, axis: Optional[Union[int, list, tuple]] = None, - edge_order: Optional[int] = 1, + edge_order: int = 1, ) -> Union[paddle.Tensor, List[paddle.Tensor]]: """Https://github.com/numpy/numpy/blob/v1.24.3/numpy/lib/ function_base.py#L969-L1312.""" @@ -644,7 +651,7 @@ def count_nonzero( /, *, axis: Optional[Union[int, list, tuple]] = None, - keepdims: Optional[bool] = False, + keepdims: bool = False, dtype: Optional[paddle.dtype] = None, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: @@ -654,7 +661,7 @@ def count_nonzero( @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "complex64", "complex128", "float32", @@ -669,11 +676,22 @@ def conj(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle. return paddle.conj(x) +@with_supported_dtypes( + { + "2.5.0 and below": ( + "float32", + "float64", + ) + }, + backend_version, +) def modf( x: paddle.Tensor, /, *, out: Optional[Tuple[paddle.Tensor, paddle.Tensor]] = None ) -> Tuple[paddle.Tensor, paddle.Tensor]: with ivy.ArrayMode(False): - return paddle.modf(x, out=out) + integer_part = paddle.floor(x) + fractional_part = x - integer_part + return fractional_part, integer_part @with_supported_dtypes( @@ -697,45 +715,53 @@ def digamma( # --- erfc --- # # Polynomials for computing erf/erfc. Originally from cephes library. # https://netlib.org/cephes/doubldoc.html -kErfcPCoefficient = paddle.to_tensor([ - 2.46196981473530512524e-10, - 5.64189564831068821977e-1, - 7.46321056442269912687e0, - 4.86371970985681366614e1, - 1.96520832956077098242e2, - 5.26445194995477358631e2, - 9.34528527171957607540e2, - 1.02755188689515710272e3, - 5.57535335369399327526e2, -]) -kErfcQCoefficient = paddle.to_tensor([ - 1.00000000000000000000e0, - 1.32281951154744992508e1, - 8.67072140885989742329e1, - 3.54937778887819891062e2, - 9.75708501743205489753e2, - 1.82390916687909736289e3, - 2.24633760818710981792e3, - 1.65666309194161350182e3, - 5.57535340817727675546e2, -]) -kErfcRCoefficient = paddle.to_tensor([ - 5.64189583547755073984e-1, - 1.27536670759978104416e0, - 5.01905042251180477414e0, - 6.16021097993053585195e0, - 7.40974269950448939160e0, - 2.97886665372100240670e0, -]) -kErfcSCoefficient = paddle.to_tensor([ - 1.00000000000000000000e0, - 2.26052863220117276590e0, - 9.39603524938001434673e0, - 1.20489539808096656605e1, - 1.70814450747565897222e1, - 9.60896809063285878198e0, - 3.36907645100081516050e0, -]) +kErfcPCoefficient = paddle.to_tensor( + [ + 2.46196981473530512524e-10, + 5.64189564831068821977e-1, + 7.46321056442269912687e0, + 4.86371970985681366614e1, + 1.96520832956077098242e2, + 5.26445194995477358631e2, + 9.34528527171957607540e2, + 1.02755188689515710272e3, + 5.57535335369399327526e2, + ] +) +kErfcQCoefficient = paddle.to_tensor( + [ + 1.00000000000000000000e0, + 1.32281951154744992508e1, + 8.67072140885989742329e1, + 3.54937778887819891062e2, + 9.75708501743205489753e2, + 1.82390916687909736289e3, + 2.24633760818710981792e3, + 1.65666309194161350182e3, + 5.57535340817727675546e2, + ] +) +kErfcRCoefficient = paddle.to_tensor( + [ + 5.64189583547755073984e-1, + 1.27536670759978104416e0, + 5.01905042251180477414e0, + 6.16021097993053585195e0, + 7.40974269950448939160e0, + 2.97886665372100240670e0, + ] +) +kErfcSCoefficient = paddle.to_tensor( + [ + 1.00000000000000000000e0, + 2.26052863220117276590e0, + 9.39603524938001434673e0, + 1.20489539808096656605e1, + 1.70814450747565897222e1, + 9.60896809063285878198e0, + 3.36907645100081516050e0, + ] +) # Evaluate the polynomial given coefficients and `x`. @@ -764,7 +790,7 @@ def _is_scalar(x): # TODO: Repalce once native function becomes available. # Compute an approximation of the error function complement (1 - erf(x)). @with_supported_dtypes( - {"2.5.2 and below": ("float64", "float32")}, + {"2.6.0 and below": ("float64", "float32")}, backend_version, ) def erfc(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -803,3 +829,13 @@ def is_pos_inf(op): result = paddle.squeeze(result, axis=-1) return result + + +@with_supported_dtypes( + {"2.6.0 and below": ("float32", "float64")}, + backend_version, +) +def erfinv( + x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None +) -> paddle.Tensor: + return paddle.erfinv(x) diff --git a/ivy/functional/backends/paddle/experimental/layers.py b/ivy/functional/backends/paddle/experimental/layers.py index 4adb2e37d3a9b..a1942a5b4d120 100644 --- a/ivy/functional/backends/paddle/experimental/layers.py +++ b/ivy/functional/backends/paddle/experimental/layers.py @@ -30,7 +30,7 @@ def _determine_depth_max_pooling(x, kernel, strides, dims, data_format="channel_ @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("float32", "float64"), "gpu": ("bfloat16", "float16", "float32", "float64"), } @@ -97,7 +97,7 @@ def max_pool1d( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("float32", "float64"), "gpu": ("bfloat16", "float16", "float32", "float64"), } @@ -168,7 +168,7 @@ def max_pool2d( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("float32", "float64"), "gpu": ("bfloat16", "float16", "float32", "float64"), } @@ -301,7 +301,7 @@ def dct( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "bool", "float16")}, backend_version + {"2.6.0 and below": ("bfloat16", "bool", "float16")}, backend_version ) def fft( x: paddle.Tensor, @@ -345,7 +345,7 @@ def fft( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("bfloat16", "float32", "float64"), "gpu": ("bfloat16", "float16", "float32", "float64"), } @@ -367,7 +367,7 @@ def dropout1d( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("bfloat16", "float32", "float64"), "gpu": ("bfloat16", "float16", "float32", "float64"), } @@ -389,7 +389,7 @@ def dropout2d( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("bfloat16", "float32", "float64"), "gpu": ("bfloat16", "float16", "float32", "float64"), } @@ -422,7 +422,7 @@ def ifft( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("int8", "float32", "float64"), "gpu": ("int8", "bfloat16", "float16", "float32", "float64"), }, @@ -514,7 +514,7 @@ def rfft( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "float16", "complex64", "complex128", "bool")}, + {"2.6.0 and below": ("bfloat16", "float16", "complex64", "complex128", "bool")}, backend_version, ) def rfftn( @@ -531,7 +531,7 @@ def rfftn( @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "complex64", "complex128", ) @@ -553,7 +553,7 @@ def fft2( # stft @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "complex64", "complex128", ) diff --git a/ivy/functional/backends/paddle/experimental/linear_algebra.py b/ivy/functional/backends/paddle/experimental/linear_algebra.py index aa76b96d31996..df21c54ab3a69 100644 --- a/ivy/functional/backends/paddle/experimental/linear_algebra.py +++ b/ivy/functional/backends/paddle/experimental/linear_algebra.py @@ -13,7 +13,7 @@ @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int8", "int16", "uint8", "float16", "bfloat16")}}, + {"2.6.0 and below": {"cpu": ("int8", "int16", "uint8", "float16", "bfloat16")}}, backend_version, ) def diagflat( @@ -47,7 +47,7 @@ def diagflat( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int8", "uint8", "int16")}}, backend_version + {"2.6.0 and below": {"cpu": ("int8", "uint8", "int16")}}, backend_version ) def kron( a: paddle.Tensor, @@ -91,7 +91,7 @@ def adjoint( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int8", "uint8", "int16", "float16")}}, + {"2.6.0 and below": {"cpu": ("int8", "uint8", "int16", "float16")}}, backend_version, ) def solve_triangular( @@ -131,9 +131,20 @@ def lu_factor( raise IvyNotImplementedException() +def lu_solve( + lu: paddle.Tensor, + p: paddle.Tensor, + b: paddle.Tensor, + /, + *, + out: Optional[paddle.Tensor] = None, +) -> paddle.Tensor: + raise IvyNotImplementedException() + + @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float32", "float64", @@ -168,7 +179,7 @@ def dot( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float32", "float64", diff --git a/ivy/functional/backends/paddle/experimental/losses.py b/ivy/functional/backends/paddle/experimental/losses.py index 7e3d245bbed72..ebb90d24898aa 100644 --- a/ivy/functional/backends/paddle/experimental/losses.py +++ b/ivy/functional/backends/paddle/experimental/losses.py @@ -14,7 +14,7 @@ @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float16", "int8", @@ -42,7 +42,7 @@ def l1_loss( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -66,13 +66,13 @@ def smooth_l1_loss( reduction: Optional[str] = "mean", ) -> paddle.Tensor: return paddle.nn.functional.smooth_l1_loss( - input, target, reduction=reduction, beta=beta + input, target, reduction=reduction, delta=beta ) @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float16", "int8", @@ -100,7 +100,7 @@ def huber_loss( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float16", "int8", @@ -127,7 +127,7 @@ def soft_margin_loss( @with_supported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float32", "float64")}}, + {"2.6.0 and below": {"cpu": ("float32", "float64")}}, backend_version, ) def kl_div( @@ -195,7 +195,7 @@ def _validate_poisson_nll_params( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("float32", "float64"), "gpu": ("bfloat16", "float16", "float32", "float64"), } @@ -239,3 +239,27 @@ def poisson_nll_loss( cond = paddle.logical_and(target_arr >= zeroes, target_arr <= ones) loss = loss + paddle.where(cond, zeroes, striling_approx_term) return _apply_loss_reduction(loss, reduction) + + +@with_supported_device_and_dtypes( + { + "2.6.0 and below": { + "cpu": ("float32", "float64"), + "gpu": ("float16", "float32", "float64"), + } + }, + backend_version, +) +def hinge_embedding_loss( + input: paddle.Tensor, + target: paddle.Tensor, + *, + margin: float = 1.0, + reduction: str = "mean", +) -> paddle.Tensor: + return paddle.nn.functional.hinge_embedding_loss( + input, + target, + margin=margin, + reduction=reduction, + ) diff --git a/ivy/functional/backends/paddle/experimental/manipulation.py b/ivy/functional/backends/paddle/experimental/manipulation.py index 61fdaae94fd93..8c7f314743d64 100644 --- a/ivy/functional/backends/paddle/experimental/manipulation.py +++ b/ivy/functional/backends/paddle/experimental/manipulation.py @@ -20,6 +20,7 @@ with_unsupported_device_and_dtypes, with_supported_dtypes, with_unsupported_dtypes, + handle_out_argument, ) import paddle import ivy @@ -95,7 +96,7 @@ @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int16", "int8", "uint8", @@ -121,7 +122,7 @@ def moveaxis( @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, backend_version, ) def pad( @@ -187,7 +188,7 @@ def pad( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -212,7 +213,7 @@ def heaviside( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, + {"2.6.0 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, backend_version, ) def flipud( @@ -237,7 +238,7 @@ def vstack( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int16", "bfloat16")}}, + {"2.6.0 and below": {"cpu": ("int16", "bfloat16")}}, backend_version, ) def hstack( @@ -254,7 +255,7 @@ def hstack( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, + {"2.6.0 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, backend_version, ) def rot90( @@ -270,7 +271,7 @@ def rot90( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def top_k( @@ -297,7 +298,7 @@ def top_k( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, + {"2.6.0 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, backend_version, ) def fliplr( @@ -310,6 +311,10 @@ def fliplr( return paddle.flip(m, axis=1) +@with_unsupported_dtypes( + {"2.6.0 and below": ("bfloat16", "float16")}, + backend_version, +) def i0( x: paddle.Tensor, /, @@ -465,7 +470,7 @@ def atleast_2d( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version, ) def atleast_3d( @@ -490,7 +495,7 @@ def atleast_3d( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "bool", "float16", "int16", "int8", "uint8")}, + {"2.6.0 and below": ("bfloat16", "bool", "float16", "int16", "int8", "uint8")}, backend_version, ) def take_along_axis( @@ -612,7 +617,7 @@ def concat_from_sequence( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int8", "int16", "uint8")}}, backend_version + {"2.6.0 and below": {"cpu": ("int8", "int16", "uint8")}}, backend_version ) def unique_consecutive( x: paddle.Tensor, @@ -675,7 +680,7 @@ def unique_consecutive( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int8", "int16", "uint8", "float16")}}, + {"2.6.0 and below": {"cpu": ("int8", "int16", "uint8", "float16")}}, backend_version, ) def fill_diagonal( @@ -741,7 +746,7 @@ def _take_with_axis( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("int64", "float64", "int32", "uint8", "float32", "bool") } }, @@ -774,7 +779,7 @@ def take( if ivy.exists(axis): try: x_shape = x.shape[axis] - except Exception: + except Exception as e: rank = len(x.shape) raise IndexError( "(OutOfRange) Attr(axis) is out of range, " @@ -784,7 +789,7 @@ def take( "(0 - input_dim.size()) == true, " "but received axis < input_dim.size() && axis >= " "(0 - input_dim.size()):0 != true:1.]" - ) + ) from e else: x_shape = paddle.prod(paddle.to_tensor(x.shape)) @@ -878,7 +883,7 @@ def trim_zeros(a: paddle.Tensor, /, *, trim: Optional[str] = "bf") -> paddle.Ten @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def put_along_axis( arr: paddle.Tensor, @@ -905,3 +910,30 @@ def put_along_axis( "sum", "mul", ] + + +@with_supported_dtypes( + { + "2.6.0 and below": ( + "int32", + "int64", + "float64", + "complex128", + "float32", + "complex64", + "bool", + ) + }, + backend_version, +) +@handle_out_argument +def unflatten( + x: paddle.Tensor, + /, + shape: Tuple[int] = None, + dim: int = 0, + *, + out: Optional[paddle.Tensor] = None, +) -> paddle.Tensor: + res = paddle.unflatten(x, dim, shape) + return res diff --git a/ivy/functional/backends/paddle/experimental/norms.py b/ivy/functional/backends/paddle/experimental/norms.py index c36bf0dda786f..bfef54ffae551 100644 --- a/ivy/functional/backends/paddle/experimental/norms.py +++ b/ivy/functional/backends/paddle/experimental/norms.py @@ -12,7 +12,7 @@ # use numpy implementation with ivy functions @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -55,11 +55,11 @@ def batch_norm( if data_format[-1] == "C" else data_formats[0:4][x.ndim - 2] ) - except IndexError: + except IndexError as e: raise IndexError( "data_format must be one of 'NC', 'NCL', 'NCHW', 'NCDHW', 'NLC', 'NHWC'," f" 'NDHWC' but receive {data_format}" - ) + ) from e with ivy.ArrayMode(False): if training: @@ -105,7 +105,7 @@ def batch_norm( ) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, backend_version) def l1_normalize( x: paddle.Tensor, /, *, axis: Optional[int] = None, out: paddle.Tensor = None ) -> paddle.Tensor: diff --git a/ivy/functional/backends/paddle/experimental/random.py b/ivy/functional/backends/paddle/experimental/random.py index 9e1d00a6d3262..e5095b76bc297 100644 --- a/ivy/functional/backends/paddle/experimental/random.py +++ b/ivy/functional/backends/paddle/experimental/random.py @@ -16,7 +16,7 @@ @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -91,8 +91,8 @@ def poisson( lam: Union[float, paddle.Tensor], *, shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None, - device: core.Place, - dtype: paddle.dtype, + device: core.Place = None, + dtype: paddle.dtype = None, seed: Optional[int] = None, fill_value: Optional[Union[float, int]] = 0, out: Optional[paddle.Tensor] = None, @@ -127,6 +127,7 @@ def bernoulli( seed: Optional[int] = None, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: + dtype = dtype if dtype is not None else probs.dtype if seed is not None: paddle.seed(seed) if probs is not None: @@ -134,7 +135,9 @@ def bernoulli( elif logits is not None: probs = ivy.softmax(logits) probs = paddle.cast(probs, dtype) - probs = paddle.unsqueeze(probs, 0) if len(probs.shape) == 0 else probs + squeeze = len(probs.shape) == 0 + probs = paddle.unsqueeze(probs, 0) if squeeze else probs probs = paddle.maximum(probs, paddle.full_like(probs, 1e-6)) sample = paddle.bernoulli(probs) + sample = paddle.squeeze(sample, 0) if squeeze else sample return sample diff --git a/ivy/functional/backends/paddle/experimental/sparse_array.py b/ivy/functional/backends/paddle/experimental/sparse_array.py index 9a1f7870a323d..453ee5568e96a 100644 --- a/ivy/functional/backends/paddle/experimental/sparse_array.py +++ b/ivy/functional/backends/paddle/experimental/sparse_array.py @@ -19,7 +19,7 @@ def is_native_sparse_array(x: paddle.Tensor) -> bool: @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int8",)}}, backend_version + {"2.6.0 and below": {"cpu": ("int8",)}}, backend_version ) def native_sparse_array( data=None, diff --git a/ivy/functional/backends/paddle/experimental/statistical.py b/ivy/functional/backends/paddle/experimental/statistical.py index 7572b28f0e8d0..84425deeee725 100644 --- a/ivy/functional/backends/paddle/experimental/statistical.py +++ b/ivy/functional/backends/paddle/experimental/statistical.py @@ -14,7 +14,7 @@ @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("complex", "float32", "float64", "int32", "int64")}, backend_version, ) def median( @@ -32,7 +32,7 @@ def median( ) else: ret = paddle.median(input, axis=axis, keepdim=True) - # keepdims is set to True because in versions up to 2.5.2 + # keepdims is set to True because in versions up to 2.6.0 # there was a problem when the axis was defined, and it was the # only axis in the tensor, so it needs to be handled manually if not keepdims: @@ -48,7 +48,7 @@ def median( @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64", "int64")}, backend_version + {"2.6.0 and below": ("complex", "float32", "float64", "int64")}, backend_version ) def nanmean( a: paddle.Tensor, @@ -101,7 +101,7 @@ def _validate_quantile(q): @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -140,7 +140,7 @@ def nanmin( return result -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, backend_version) def nanprod( a: paddle.Tensor, /, @@ -308,7 +308,7 @@ def _compute_quantile_wrapper( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -382,7 +382,7 @@ def histogram( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def nanmedian( input: paddle.Tensor, @@ -401,7 +401,7 @@ def nanmedian( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -433,7 +433,7 @@ def unravel_index( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -556,7 +556,7 @@ def cov( @with_supported_dtypes( - {"2.5.2 and below": ("complex", "bool", "float32", "float64")}, + {"2.6.0 and below": ("complex", "bool", "float32", "float64")}, backend_version, ) def cummax( @@ -681,7 +681,7 @@ def __get_index(lst, indices=None, prefix=None): @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("uint8", "int8", "int16")}}, + {"2.6.0 and below": {"cpu": ("uint8", "int8", "int16")}}, backend_version, ) def cummin( diff --git a/ivy/functional/backends/paddle/general.py b/ivy/functional/backends/paddle/general.py index 60f32855f4992..0f9747fe6353e 100644 --- a/ivy/functional/backends/paddle/general.py +++ b/ivy/functional/backends/paddle/general.py @@ -70,11 +70,13 @@ def _squeeze_helper(query, x_ndim): ) if any(slice_squeeze): - squeeze_indices = tuple([ - idx - for idx, val in enumerate(slice_squeeze) - if (val is False and query[idx] is not None) - ]) + squeeze_indices = tuple( + [ + idx + for idx, val in enumerate(slice_squeeze) + if (val is False and query[idx] is not None) + ] + ) elif return_scalar: squeeze_indices = () else: @@ -85,7 +87,7 @@ def _squeeze_helper(query, x_ndim): @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("int8", "int16", "float16", "complex64", "complex128") } }, @@ -227,6 +229,10 @@ def _gather(params1): return _gather(params) +@with_unsupported_device_and_dtypes( + {"2.6.0 and below": {"cpu": ("bfloat16", "float16")}}, + backend_version, +) def gather_nd( params: paddle.Tensor, indices: paddle.Tensor, @@ -269,6 +275,8 @@ def gather_nd( indices_shape = indices.shape batch_shape = params_shape[:batch_dims] batch_size = paddle.prod(batch_shape, [0]).numpy().tolist() + if isinstance(batch_size, int): + batch_size = [batch_size] index_internal_ndims = indices.ndim - batch_dims - 1 indices_internal_shape = indices_shape[batch_dims:-1] @@ -647,7 +655,11 @@ def _vmap(*args, **kwargs): # vectorisation - applying map_fn if only one arg provided as reduce requires # two elements to begin with. - arr_results = [func(*arrays) for arrays in zip(*args)] + arr_results = [] + for arrays in zip(*args): + arrays = [a if a.shape != [] else a.unsqueeze(0) for a in arrays] + arr_results.append(func(*arrays)) + res = paddle_backend.concat(arr_results) if out_axes: diff --git a/ivy/functional/backends/paddle/gradients.py b/ivy/functional/backends/paddle/gradients.py index c39ef078758b1..925e49c865bc1 100644 --- a/ivy/functional/backends/paddle/gradients.py +++ b/ivy/functional/backends/paddle/gradients.py @@ -103,7 +103,7 @@ def grad_(x): @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, backend_version + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version ) def execute_with_gradients( func, xs, /, *, retain_grads=False, xs_grad_idxs=((0,),), ret_grad_idxs=((0,),) @@ -116,10 +116,12 @@ def execute_with_gradients( xs = xs1 if isinstance(xs, ivy.Container): duplicate_indices = list( - chain.from_iterable([ - map(lambda x: x.split("/"), duplicate_index_chain[1:]) - for duplicate_index_chain in required_duplicate_index_chains - ]) + chain.from_iterable( + [ + map(lambda x: x.split("/"), duplicate_index_chain[1:]) + for duplicate_index_chain in required_duplicate_index_chains + ] + ) ) xs = ivy.set_nest_at_indices(xs, duplicate_indices, None, shallow=False) diff --git a/ivy/functional/backends/paddle/layers.py b/ivy/functional/backends/paddle/layers.py index ad78d3d041b50..fb20e6ae75272 100644 --- a/ivy/functional/backends/paddle/layers.py +++ b/ivy/functional/backends/paddle/layers.py @@ -30,10 +30,11 @@ def _convert_to_list(value, n, name="padding", _type=int): else: try: value_list = list(value) - except TypeError: - raise ValueError( - f"The input {name}'s type must be list or tuple. Received: {value}" - ) + except TypeError as e: + raise TypeError( + f"The input {value}'s type must be list or tuple. Received:" + f" {type(value)}" + ) from e else: return value_list @@ -148,8 +149,8 @@ def conv1d( /, *, data_format: str = "NWC", - filter_format: Optional[str] = "channel_last", - x_dilations: Optional[Union[int, Tuple[int]]] = 1, + filter_format: str = "channel_last", + x_dilations: Union[int, Tuple[int]] = 1, dilations: Union[int, Tuple[int]] = 1, bias: Optional[paddle.Tensor] = None, out: Optional[paddle.Tensor] = None, @@ -158,7 +159,7 @@ def conv1d( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16", "bfloat16")}}, + {"2.6.0 and below": {"cpu": ("float16", "bfloat16")}}, backend_version, ) def conv1d_transpose( @@ -209,8 +210,8 @@ def conv2d( /, *, data_format: str = "NHWC", - filter_format: Optional[str] = "channel_last", - x_dilations: Optional[Union[int, Tuple[int, int]]] = 1, + filter_format: str = "channel_last", + x_dilations: Union[int, Tuple[int, int]] = 1, dilations: Union[int, Tuple[int, int]] = 1, bias: Optional[paddle.Tensor] = None, out: Optional[paddle.Tensor] = None, @@ -219,7 +220,7 @@ def conv2d( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16", "bfloat16")}}, + {"2.6.0 and below": {"cpu": ("float16", "bfloat16")}}, backend_version, ) def conv2d_transpose( @@ -231,8 +232,8 @@ def conv2d_transpose( *, output_shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None, filter_format: str = "channel_last", - data_format: Optional[str] = "NHWC", - dilations: Optional[Union[int, Tuple[int, int]]] = 1, + data_format: str = "NHWC", + dilations: Union[int, Tuple[int, int]] = 1, bias: Optional[paddle.Tensor] = None, out: Optional[paddle.Tensor] = None, ): @@ -272,15 +273,15 @@ def depthwise_conv2d( padding: Union[str, int, Sequence[Tuple[int, int]]], /, *, - data_format: Optional[str] = "NHWC", - dilations: Optional[Union[int, Tuple[int, int]]] = 1, + data_format: str = "NHWC", + dilations: Union[int, Tuple[int, int]] = 1, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: raise IvyNotImplementedException() @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version, ) def conv3d( @@ -290,10 +291,10 @@ def conv3d( padding: Union[str, int, Sequence[Tuple[int, int]]], /, *, - data_format: Optional[str] = "NDHWC", - filter_format: Optional[str] = "channel_last", - x_dilations: Optional[Union[int, Tuple[int, int, int]]] = 1, - dilations: Optional[Union[int, Tuple[int, int, int]]] = 1, + data_format: str = "NDHWC", + filter_format: str = "channel_last", + x_dilations: Union[int, Tuple[int, int, int]] = 1, + dilations: Union[int, Tuple[int, int, int]] = 1, bias: Optional[paddle.Tensor] = None, out: Optional[paddle.Tensor] = None, ): @@ -331,8 +332,8 @@ def conv3d_transpose( *, output_shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None, filter_format: str = "channel_last", - data_format: Optional[str] = "NDHWC", - dilations: Optional[Union[int, Tuple[int, int, int]]] = 1, + data_format: str = "NDHWC", + dilations: Union[int, Tuple[int, int, int]] = 1, bias: Optional[paddle.Tensor] = None, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: @@ -340,7 +341,7 @@ def conv3d_transpose( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("float16",)}}, + {"2.6.0 and below": {"cpu": ("float16",)}}, backend_version, ) def conv_general_dilated( @@ -350,16 +351,12 @@ def conv_general_dilated( padding: Union[str, int, Sequence[Tuple[int, int]]], /, *, - dims: Optional[int] = 2, - data_format: Optional[str] = "channel_last", - filter_format: Optional[str] = "channel_last", - feature_group_count: Optional[int] = 1, - x_dilations: Optional[ - Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int]] - ] = 1, - dilations: Optional[ - Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int]] - ] = 1, + dims: int = 2, + data_format: str = "channel_last", + filter_format: str = "channel_last", + feature_group_count: int = 1, + x_dilations: Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int]] = 1, + dilations: Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int]] = 1, bias: Optional[paddle.Tensor] = None, out: Optional[paddle.Tensor] = None, ): @@ -431,14 +428,12 @@ def conv_general_transpose( padding: Union[str, Sequence[Tuple[int, int]]], /, *, - dims: Optional[int] = 2, + dims: int = 2, output_shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None, filter_format: str = "channel_last", - data_format: Optional[str] = "NDHWC", - dilations: Optional[ - Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int]] - ] = 1, - feature_group_count: Optional[int] = 1, + data_format: str = "NDHWC", + dilations: Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int]] = 1, + feature_group_count: int = 1, bias: Optional[paddle.Tensor] = None, out: Optional[paddle.Tensor] = None, ): diff --git a/ivy/functional/backends/paddle/linear_algebra.py b/ivy/functional/backends/paddle/linear_algebra.py index 16592ed2f4e1d..ddf447a62e946 100644 --- a/ivy/functional/backends/paddle/linear_algebra.py +++ b/ivy/functional/backends/paddle/linear_algebra.py @@ -14,6 +14,7 @@ with_unsupported_device_and_dtypes, with_unsupported_dtypes, with_supported_dtypes, + with_supported_device_and_dtypes, ) from .elementwise import _elementwise_helper @@ -24,7 +25,7 @@ @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -91,7 +92,7 @@ def _cross(x1, x2, axisa, axisb, axisc, axis): @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def det(x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None) -> paddle.Tensor: @@ -144,7 +145,7 @@ def eigh( x: paddle.Tensor, /, *, - UPLO: Optional[str] = "L", + UPLO: str = "L", out: Optional[paddle.Tensor] = None, ) -> Tuple[paddle.Tensor]: result_tuple = NamedTuple( @@ -158,7 +159,7 @@ def eigvalsh( x: paddle.Tensor, /, *, - UPLO: Optional[str] = "L", + UPLO: str = "L", out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: return paddle.linalg.eigvalsh(x, UPLO=UPLO) @@ -183,7 +184,7 @@ def inner( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def inv( @@ -252,18 +253,21 @@ def matmul( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def matrix_norm( x: paddle.Tensor, /, *, - ord: Optional[Union[int, float, Literal[inf, -inf, "fro", "nuc"]]] = "fro", - axis: Optional[Tuple[int, int]] = (-2, -1), + ord: Union[int, float, Literal[inf, -inf, "fro", "nuc"]] = "fro", + axis: Tuple[int, int] = (-2, -1), keepdims: bool = False, + dtype: Optional[paddle.dtype] = None, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: + if dtype is not None: + x = ivy.astype(x, dtype=dtype) axis_ = list(axis) # paddle.moveaxis doesn't support tuple axes if ord == "nuc": x = paddle.moveaxis(x, axis_, [-2, -1]) @@ -334,7 +338,7 @@ def eig( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def matrix_power( @@ -344,7 +348,7 @@ def matrix_power( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def matrix_rank( @@ -353,7 +357,7 @@ def matrix_rank( *, atol: Optional[Union[float, Tuple[float]]] = None, rtol: Optional[Union[float, Tuple[float]]] = None, - hermitian: Optional[bool] = False, + hermitian: bool = False, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: if (x.ndim < 2) or (0 in x.shape): @@ -398,6 +402,14 @@ def matrix_transpose( return paddle.transpose(x, perm=perm) +@with_supported_device_and_dtypes( + { + "2.6.0 and below": { + "cpu": ("int32", "int64", "float64", "complex128" "float32", "complex64") + } + }, + backend_version, +) def outer( x1: paddle.Tensor, x2: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None ) -> paddle.Tensor: @@ -441,7 +453,7 @@ def tensorsolve( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def qr( @@ -457,7 +469,7 @@ def qr( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def slogdet( @@ -476,7 +488,7 @@ def slogdet( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def solve( @@ -503,7 +515,7 @@ def solve( return ret -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, backend_version) def svd( x: paddle.Tensor, /, *, full_matrices: bool = True, compute_uv: bool = True ) -> Union[paddle.Tensor, Tuple[paddle.Tensor, ...]]: @@ -517,7 +529,7 @@ def svd( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("complex64", "complex128")}}, backend_version, ) def svdvals( @@ -532,7 +544,7 @@ def svdvals( @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64")}, backend_version + {"2.6.0 and below": ("complex", "float32", "float64")}, backend_version ) def tensordot( x1: paddle.Tensor, @@ -548,7 +560,7 @@ def tensordot( @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "int8", "int16", @@ -592,8 +604,8 @@ def vector_norm( /, *, axis: Optional[Union[int, Sequence[int]]] = None, - keepdims: Optional[bool] = False, - ord: Optional[Union[int, float, Literal[inf, -inf]]] = 2, + keepdims: bool = False, + ord: Union[int, float, Literal[inf, -inf]] = 2, dtype: Optional[paddle.dtype] = None, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: @@ -624,7 +636,7 @@ def vector_norm( @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, backend_version, ) def diag( @@ -638,7 +650,7 @@ def diag( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("uint8", "int8", "int16", "complex64", "complex128")}}, + {"2.6.0 and below": {"cpu": ("uint8", "int8", "int16", "complex64", "complex128")}}, backend_version, ) def vander( @@ -660,7 +672,7 @@ def vander( @with_unsupported_dtypes( - {"2.5.2 and below": ("unsigned", "int8", "int16", "float16")}, + {"2.6.0 and below": ("unsigned", "int8", "int16", "float16")}, backend_version, ) def vector_to_skew_symmetric_matrix( diff --git a/ivy/functional/backends/paddle/manipulation.py b/ivy/functional/backends/paddle/manipulation.py index f3bb163807d58..44271c6400601 100644 --- a/ivy/functional/backends/paddle/manipulation.py +++ b/ivy/functional/backends/paddle/manipulation.py @@ -22,6 +22,10 @@ # -------------------# +@with_unsupported_dtypes( + {"2.6.0 and below": ("bfloat16", "float16")}, + backend_version, +) def concat( xs: Union[Tuple[paddle.Tensor, ...], List[paddle.Tensor]], /, @@ -58,6 +62,20 @@ def concat( return ret +@with_supported_dtypes( + { + "2.6.0 and below": ( + "int32", + "int64", + "float64", + "complex128", + "float32", + "complex64", + "bool", + ) + }, + backend_version, +) def expand_dims( x: paddle.Tensor, /, @@ -74,7 +92,7 @@ def expand_dims( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, + {"2.6.0 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, backend_version, ) def flip( @@ -90,8 +108,19 @@ def flip( return paddle.flip(x, axis) -@with_unsupported_dtypes( - {"2.5.2 and below": ("int16", "int8", "uint8", "bfloat16")}, backend_version +@with_supported_dtypes( + { + "2.6.0 and below": ( + "int32", + "int64", + "float64", + "complex128", + "float32", + "complex64", + "bool", + ) + }, + backend_version, ) def permute_dims( x: paddle.Tensor, @@ -159,7 +188,7 @@ def reshape( @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("complex", "float32", "float64", "int32", "int64")}, backend_version, ) def roll( @@ -174,7 +203,7 @@ def roll( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "float16", "int16")}, backend_version + {"2.6.0 and below": ("bfloat16", "float16", "int16")}, backend_version ) def squeeze( x: paddle.Tensor, @@ -201,7 +230,7 @@ def squeeze( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int16", "uint8", "int8", "float16")}}, + {"2.6.0 and below": {"cpu": ("int16", "uint8", "int8", "float16")}}, backend_version, ) def stack( @@ -249,7 +278,7 @@ def stack( # ------# -@with_unsupported_dtypes({"2.5.2 and below": ("int16",)}, backend_version) +@with_unsupported_dtypes({"2.6.0 and below": ("int16",)}, backend_version) def split( x: paddle.Tensor, /, @@ -299,7 +328,7 @@ def split( @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("complex", "float32", "float64", "int32", "int64")}, backend_version, ) def repeat( @@ -335,7 +364,7 @@ def repeat( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, + {"2.6.0 and below": ("bfloat16", "float16", "int16", "int8", "uint8")}, backend_version, ) def tile( @@ -378,7 +407,7 @@ def tile( @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bfloat16", "float16", "int8", @@ -417,6 +446,22 @@ def zero_pad( return paddle_backend.constant_pad(x, pad_width=pad_width, value=0) +@with_supported_dtypes( + { + "2.6.0 and below": ( + "bool", + "int32", + "int64", + "float16", + "bfloat16", + "float32", + "float64", + "complex64", + "complex128", + ) + }, + backend_version, +) def swapaxes( x: paddle.Tensor, axis0: int, @@ -462,7 +507,7 @@ def clip( @with_unsupported_dtypes( - {"2.5.2 and below": ("int16", "int8", "uint8", "bfloat16")}, backend_version + {"2.6.0 and below": ("int16", "int8", "uint8", "bfloat16")}, backend_version ) def unstack( x: paddle.Tensor, diff --git a/ivy/functional/backends/paddle/module.py b/ivy/functional/backends/paddle/module.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ivy/functional/backends/paddle/random.py b/ivy/functional/backends/paddle/random.py index 3579c42c8bbb7..15c10f366a1a7 100644 --- a/ivy/functional/backends/paddle/random.py +++ b/ivy/functional/backends/paddle/random.py @@ -8,7 +8,7 @@ # local import ivy -from paddle.fluid.libpaddle import Place +from paddle.device import core from ivy.functional.ivy.random import ( _check_bounds_and_get_shape, _randint_check_dtype_and_bound, @@ -26,7 +26,7 @@ @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int8",)}}, + {"2.6.0 and below": {"cpu": ("int8",)}}, backend_version, ) def random_uniform( @@ -35,7 +35,7 @@ def random_uniform( high: Union[float, paddle.Tensor] = 1.0, shape: Optional[Union[paddle.Tensor, ivy.NativeShape, Sequence[int]]] = None, dtype: paddle.dtype, - device: Place = None, + device: core.Place = None, seed=None, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: @@ -57,7 +57,7 @@ def random_uniform( @with_unsupported_dtypes( - {"2.5.2 and below": ("float16", "int16", "int8")}, backend_version + {"2.6.0 and below": ("float16", "int16", "int8")}, backend_version ) def random_normal( *, @@ -66,7 +66,7 @@ def random_normal( shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None, dtype: paddle.dtype, seed: Optional[int] = None, - device: Place = None, + device: core.Place = None, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: _check_valid_scale(std) @@ -78,7 +78,7 @@ def random_normal( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "float32", "float64", @@ -95,7 +95,7 @@ def multinomial( batch_size: int = 1, probs: Optional[paddle.Tensor] = None, replace: bool = True, - device: Place = None, + device: core.Place = None, seed: Optional[int] = None, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: @@ -109,7 +109,7 @@ def multinomial( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int8",)}}, + {"2.6.0 and below": {"cpu": ("int8",)}}, backend_version, ) def randint( @@ -118,7 +118,7 @@ def randint( /, *, shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None, - device: Place = None, + device: core.Place = None, dtype: Optional[Union[paddle.dtype, ivy.Dtype]] = None, seed: Optional[int] = None, out: Optional[paddle.Tensor] = None, diff --git a/ivy/functional/backends/paddle/searching.py b/ivy/functional/backends/paddle/searching.py index d5c6a6ffbb9da..f64c9c97288ba 100644 --- a/ivy/functional/backends/paddle/searching.py +++ b/ivy/functional/backends/paddle/searching.py @@ -16,7 +16,7 @@ @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int16", "int32", "int64", "uint8")}, + {"2.6.0 and below": ("float32", "float64", "int16", "int32", "int64", "uint8")}, backend_version, ) def argmax( @@ -48,7 +48,7 @@ def argmax( @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "bool", "complex", "float16", "int8")}, + {"2.6.0 and below": ("bfloat16", "bool", "complex", "float16", "int8")}, backend_version, ) def argmin( @@ -80,7 +80,7 @@ def argmin( @with_unsupported_dtypes( - {"2.5.2 and below": ("float16", "int8", "uint8")}, backend_version + {"2.6.0 and below": ("float16", "int8", "uint8")}, backend_version ) def nonzero( x: paddle.Tensor, @@ -161,7 +161,7 @@ def where( @with_unsupported_dtypes( - {"2.5.2 and below": ("float16", "int8", "uint8")}, backend_version + {"2.6.0 and below": ("float16", "int8", "uint8")}, backend_version ) def argwhere( x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None diff --git a/ivy/functional/backends/paddle/set.py b/ivy/functional/backends/paddle/set.py index aeedd6bae6d05..1d73d6b200496 100644 --- a/ivy/functional/backends/paddle/set.py +++ b/ivy/functional/backends/paddle/set.py @@ -10,7 +10,7 @@ @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def unique_all( x: paddle.Tensor, @@ -63,12 +63,14 @@ def unique_all( axis = 0 values_ = paddle.moveaxis(values, axis, 0) values_ = paddle.reshape(values_, (values_.shape[0], -1)) - sort_idx = paddle.to_tensor([ - i[0] - for i in sorted( - enumerate(values_.numpy().tolist()), key=lambda x: tuple(x[1]) - ) - ]) + sort_idx = paddle.to_tensor( + [ + i[0] + for i in sorted( + enumerate(values_.numpy().tolist()), key=lambda x: tuple(x[1]) + ) + ] + ) values = paddle.gather(values, sort_idx, axis=axis) counts = paddle.gather(counts, sort_idx) indices = paddle.gather(indices, sort_idx) @@ -86,7 +88,7 @@ def unique_all( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def unique_counts(x: paddle.Tensor, /) -> Tuple[paddle.Tensor, paddle.Tensor]: unique, counts = paddle.unique(x, return_counts=True) @@ -109,7 +111,7 @@ def unique_counts(x: paddle.Tensor, /) -> Tuple[paddle.Tensor, paddle.Tensor]: @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def unique_inverse( x: paddle.Tensor, @@ -135,7 +137,7 @@ def unique_inverse( x.dtype ) unique = paddle.concat( - input=[unique.astype(x.dtype), paddle.reshape(unique_nan, [nan_count])], + [unique.astype(x.dtype), paddle.reshape(unique_nan, [nan_count])], axis=-1, ) inverse_val = paddle.reshape(inverse_val, shape=x.shape) @@ -144,7 +146,7 @@ def unique_inverse( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def unique_values( x: paddle.Tensor, /, *, out: Optional[paddle.Tensor] = None diff --git a/ivy/functional/backends/paddle/sorting.py b/ivy/functional/backends/paddle/sorting.py index 26d78dbe0cc06..f67aa6bece1b4 100644 --- a/ivy/functional/backends/paddle/sorting.py +++ b/ivy/functional/backends/paddle/sorting.py @@ -9,7 +9,7 @@ @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def argsort( x: paddle.Tensor, @@ -24,7 +24,7 @@ def argsort( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def sort( x: paddle.Tensor, @@ -39,7 +39,7 @@ def sort( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def searchsorted( x: paddle.Tensor, @@ -74,7 +74,7 @@ def searchsorted( @with_unsupported_device_and_dtypes( - {"2.5.2 and below": {"cpu": ("int8", "uint8", "int16", "float16", "complex")}}, + {"2.6.0 and below": {"cpu": ("int8", "uint8", "int16", "float16", "complex")}}, backend_version, ) def msort( diff --git a/ivy/functional/backends/paddle/statistical.py b/ivy/functional/backends/paddle/statistical.py index 9cc49c2733942..4a0376cd2cf17 100644 --- a/ivy/functional/backends/paddle/statistical.py +++ b/ivy/functional/backends/paddle/statistical.py @@ -8,7 +8,6 @@ import ivy from ivy.func_wrapper import ( with_supported_dtypes, - with_unsupported_dtypes, with_supported_device_and_dtypes, ) import ivy.functional.backends.paddle as paddle_backend @@ -22,7 +21,7 @@ @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("complex", "float32", "float64", "int32", "int64")}, backend_version, ) def min( @@ -31,6 +30,8 @@ def min( *, axis: Optional[Union[int, Sequence[int]]] = None, keepdims: bool = False, + initial: Optional[Union[int, float, complex]] = None, + where: Optional[paddle.Tensor] = None, out: Optional[paddle.Tensor] = None, ) -> paddle.Tensor: ret_dtype = x.dtype @@ -39,6 +40,18 @@ def min( imag = paddle.amin(x.imag(), axis=axis, keepdim=keepdims) ret = paddle.complex(real, imag) else: + if where is not None: + max_val = ( + ivy.iinfo(x.dtype).max + if ivy.is_int_dtype(x.dtype) + else ivy.finfo(x.dtype).max + ) + max_val = max_val / 10 + # max_val becomes negative after multiplying with paddle.ones_like(x) + # therefore reduced it + val = paddle.ones_like(x) * max_val + val = val.astype(ret_dtype) + x = paddle.where(where, x, val) ret = paddle.amin(x, axis=axis, keepdim=keepdims) # The following code is to simulate other frameworks # output shapes behaviour since min output dim is 1 in paddle @@ -47,11 +60,14 @@ def min( axis = None if (x.ndim == 1 or axis is None) and not keepdims: ret = ret.squeeze() + if initial is not None: + initial = paddle.to_tensor(initial, dtype=ret_dtype) + ret = paddle.minimum(ret, initial) return ret.astype(ret_dtype) @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("complex", "float32", "float64", "int32", "int64")}, backend_version, ) def max( @@ -89,7 +105,7 @@ def max( @with_supported_dtypes( - {"2.5.2 and below": ("bool", "complex", "float32", "float64")}, backend_version + {"2.6.0 and below": ("bool", "complex", "float32", "float64")}, backend_version ) def mean( x: paddle.Tensor, @@ -119,7 +135,7 @@ def mean( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def prod( x: paddle.Tensor, @@ -167,8 +183,8 @@ def std( return _std(x, axis, correction, keepdims).cast(x.dtype) -@with_unsupported_dtypes( - {"2.5.2 and below": ("int8", "int16", "uint8")}, +@with_supported_dtypes( + {"2.6.0 and below": ("bool", "float16", "float32", "float64", "int32", "int64")}, backend_version, ) def sum( @@ -209,7 +225,7 @@ def var( # Extra # # ----- # @with_supported_dtypes( - {"2.5.2 and below": ("complex", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("complex", "float32", "float64", "int32", "int64")}, backend_version, ) def cumprod( @@ -259,7 +275,7 @@ def cumprod( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, backend_version + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, backend_version ) def cumsum( x: paddle.Tensor, @@ -308,7 +324,7 @@ def cumsum( @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("float32", "float64", "complex64", "complex128"), "gpu": ( "bfloat16", diff --git a/ivy/functional/backends/tensorflow/__init__.py b/ivy/functional/backends/tensorflow/__init__.py index 786e8169f9139..6af4c4d36e712 100644 --- a/ivy/functional/backends/tensorflow/__init__.py +++ b/ivy/functional/backends/tensorflow/__init__.py @@ -265,3 +265,9 @@ def closest_valid_dtype(type=None, /, as_native=False): # sub-backends from . import sub_backends from .sub_backends import * + +from . import module +from .module import Model + + +NativeModule = Model diff --git a/ivy/functional/backends/tensorflow/activations.py b/ivy/functional/backends/tensorflow/activations.py index 5b757031a48c5..2e60ebe41688e 100644 --- a/ivy/functional/backends/tensorflow/activations.py +++ b/ivy/functional/backends/tensorflow/activations.py @@ -40,6 +40,16 @@ def leaky_relu( return tf.nn.leaky_relu(x, alpha) +@with_supported_dtypes( + { + "2.15.0 and below": ( + "float", + "int", + "complex", + ) + }, + backend_version, +) def relu(x: Tensor, /, *, complex_mode="jax", out: Optional[Tensor] = None) -> Tensor: return tf.nn.relu(x) diff --git a/ivy/functional/backends/tensorflow/control_flow_ops.py b/ivy/functional/backends/tensorflow/control_flow_ops.py index e56beb4e35731..375ca64e2de40 100644 --- a/ivy/functional/backends/tensorflow/control_flow_ops.py +++ b/ivy/functional/backends/tensorflow/control_flow_ops.py @@ -24,7 +24,7 @@ def test_fn_wrapper(*loop_vars): if not vars: vars = (0,) - else: + elif isinstance(vars, dict): vars = list(vars.values()) return tf.while_loop(test_fn_wrapper, body_fn_wrapper, loop_vars=vars) diff --git a/ivy/functional/backends/tensorflow/creation.py b/ivy/functional/backends/tensorflow/creation.py index 8f84e8e3cda1a..2b7f602d8a2dd 100644 --- a/ivy/functional/backends/tensorflow/creation.py +++ b/ivy/functional/backends/tensorflow/creation.py @@ -93,6 +93,13 @@ def asarray( with tf.device(device): if tf.is_tensor(obj): ret = tf.cast(obj, dtype) if obj.dtype != dtype else obj + elif ( + dtype is not None + and dtype.is_integer + and np.issubdtype(np.array(obj).dtype, np.floating) + ): + obj_np = np.array(obj) + ret = tf.convert_to_tensor(obj_np, dtype) else: ret = tf.convert_to_tensor(obj, dtype) return tf.identity(ret) if (copy or ret.device != device) else ret @@ -386,9 +393,9 @@ def one_hot( @with_unsupported_dtypes({"2.15.0 and below": ("uint32", "uint64")}, backend_version) def frombuffer( buffer: bytes, - dtype: Optional[tf.DType] = float, - count: Optional[int] = -1, - offset: Optional[int] = 0, + dtype: tf.DType = float, + count: int = -1, + offset: int = 0, ) -> Union[tf.Tensor, tf.Variable]: if isinstance(buffer, bytearray): buffer = bytes(buffer) diff --git a/ivy/functional/backends/tensorflow/data_type.py b/ivy/functional/backends/tensorflow/data_type.py index 8b7209debc852..558120c4af568 100644 --- a/ivy/functional/backends/tensorflow/data_type.py +++ b/ivy/functional/backends/tensorflow/data_type.py @@ -117,7 +117,7 @@ def broadcast_arrays( try: desired_shape = tf.broadcast_dynamic_shape(arrays[0].shape, arrays[1].shape) except tf.errors.InvalidArgumentError as e: - raise ivy.utils.exceptions.IvyBroadcastShapeError(e) + raise ivy.utils.exceptions.IvyBroadcastShapeError(e) from e if len(arrays) > 2: for i in range(2, len(arrays)): try: @@ -125,7 +125,7 @@ def broadcast_arrays( desired_shape, arrays[i].shape ) except tf.errors.InvalidArgumentError as e: - raise ivy.utils.exceptions.IvyBroadcastShapeError(e) + raise ivy.utils.exceptions.IvyBroadcastShapeError(e) from e else: return [arrays[0]] result = [] diff --git a/ivy/functional/backends/tensorflow/device.py b/ivy/functional/backends/tensorflow/device.py index dd7c4cea4f6c9..6805d3013ca4b 100644 --- a/ivy/functional/backends/tensorflow/device.py +++ b/ivy/functional/backends/tensorflow/device.py @@ -34,6 +34,7 @@ def dev( dv = x.device if as_native: return dv + dv = dv if dv else ivy.default_device(as_native=False) return as_ivy_dev(dv) diff --git a/ivy/functional/backends/tensorflow/elementwise.py b/ivy/functional/backends/tensorflow/elementwise.py index ff46eefbf34ed..5a86d3e29e637 100644 --- a/ivy/functional/backends/tensorflow/elementwise.py +++ b/ivy/functional/backends/tensorflow/elementwise.py @@ -2,7 +2,6 @@ from typing import Union, Optional import tensorflow as tf - # local import ivy from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes @@ -23,6 +22,7 @@ def abs( return tf.abs(x) +@with_unsupported_dtypes({"2.15.0 and below": ("unsigned", "bool")}, backend_version) def acos( x: Union[tf.Tensor, tf.Variable], /, @@ -50,6 +50,8 @@ def add( out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: x1, x2 = ivy.promote_types_of_inputs(x1, x2) + if x1.dtype.is_bool and x2.dtype.is_bool: + return tf.math.logical_or(x1, x2) if alpha not in (1, None): with ivy.ArrayMode(False): x2 = multiply(x2, alpha) @@ -199,6 +201,7 @@ def ceil( return tf.math.ceil(x) +@with_unsupported_dtypes({"2.15.0 and below": ("integer",)}, backend_version) def cos( x: Union[tf.Tensor, tf.Variable], /, @@ -245,6 +248,7 @@ def equal( return tf.math.equal(x1, x2) +@with_unsupported_dtypes({"2.15.0 and below": ("integer",)}, backend_version) def exp( x: Union[tf.Tensor, tf.Variable], /, @@ -431,6 +435,9 @@ def less_equal( return tf.math.less_equal(x1, x2) +@with_unsupported_dtypes( + {"2.15.0 and below": ("float16", "bfloat16", "integer")}, backend_version +) def log( x: Union[tf.Tensor, tf.Variable], /, @@ -849,19 +856,23 @@ def reciprocal( *, out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: + if x.dtype.is_integer: + x = tf.cast(x, tf.float32) return tf.math.reciprocal(x) -@with_unsupported_dtypes({"2.15.0 and below": ("bfloat16",)}, backend_version) +@with_supported_dtypes({"2.15.0 and below": ("float",)}, backend_version) def deg2rad( x: Union[tf.Tensor, tf.Variable], /, *, out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: - return tf.experimental.numpy.deg2rad(x) + radians = x * ivy.pi / 180.0 + return radians +@with_supported_dtypes({"2.15.0 and below": ("float",)}, backend_version) def rad2deg( x: Union[tf.Tensor, tf.Variable], /, diff --git a/ivy/functional/backends/tensorflow/experimental/activations.py b/ivy/functional/backends/tensorflow/experimental/activations.py index 11c67e78af3b5..259c82c3255ce 100644 --- a/ivy/functional/backends/tensorflow/experimental/activations.py +++ b/ivy/functional/backends/tensorflow/experimental/activations.py @@ -59,7 +59,7 @@ def selu(x: Tensor, /, *, out: Optional[Tensor] = None) -> Tensor: return ivy.astype(ret, x.dtype) -@with_unsupported_dtypes({"2.15.0 and below": ("complex",)}, backend_version) +@with_supported_dtypes({"2.15.0 and below": ("float",)}, backend_version) def silu( x: Tensor, /, @@ -74,8 +74,7 @@ def silu( @with_supported_dtypes({"2.15.0 and below": ("float",)}, backend_version) def elu(x: Tensor, /, *, alpha: float = 1.0, out: Optional[Tensor] = None) -> Tensor: - alpha = tf.cast(alpha, x.dtype) - ret = tf.cast(tf.where(x > 0, x, tf.multiply(alpha, tf.math.expm1(x))), x.dtype) + ret = tf.keras.activations.elu(x, alpha) if ivy.exists(out): return ivy.inplace_update(out, ret).astype(x.dtype) return ivy.astype(ret, x.dtype) @@ -186,3 +185,13 @@ def hardshrink( if ivy.exists(out): return ivy.inplace_update(out, ret).astype(x.dtype) return ivy.astype(ret, x.dtype) + + +@with_unsupported_dtypes({"2.14.0 and below": ("complex",)}, backend_version) +def hardsilu( + x: Tensor, /, *, complex_mode="jax", out: Optional[Tensor] = None +) -> Tensor: + ret = tf.multiply(x, tf.nn.relu6(tf.math.add(x, 3)) / 6) + if ivy.exists(out): + return ivy.inplace_update(out, ret).astype(x.dtype) + return ivy.astype(ret, x.dtype) diff --git a/ivy/functional/backends/tensorflow/experimental/elementwise.py b/ivy/functional/backends/tensorflow/experimental/elementwise.py index 62467bf853aac..977e0d0584c87 100644 --- a/ivy/functional/backends/tensorflow/experimental/elementwise.py +++ b/ivy/functional/backends/tensorflow/experimental/elementwise.py @@ -538,13 +538,16 @@ def frexp( return m, e +@with_supported_dtypes({"2.15.0 and below": ("float",)}, backend_version) def modf( x: Union[tf.Tensor, tf.Variable], /, *, out: Optional[Union[tf.Tensor, tf.Variable]] = None, -) -> Union[tf.Tensor, tf.Variable]: - return tf.math.modf(x) +) -> Tuple[Union[tf.Tensor, tf.Variable], Union[tf.Tensor, tf.Variable]]: + integer_part = tf.math.floor(x) + fractional_part = x - integer_part + return fractional_part, integer_part def digamma( @@ -563,3 +566,13 @@ def erfc( out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: return tf.math.erfc(x) + + +@with_supported_dtypes({"2.15.0 and below": ("float",)}, backend_version) +def erfinv( + x: Union[tf.Tensor, tf.Variable], + /, + *, + out: Optional[Union[tf.Tensor, tf.Variable]] = None, +) -> Union[tf.Tensor, tf.Variable]: + return tf.math.erfinv(x) diff --git a/ivy/functional/backends/tensorflow/experimental/layers.py b/ivy/functional/backends/tensorflow/experimental/layers.py index 722ea553bbe95..3aa7d1126f5fe 100644 --- a/ivy/functional/backends/tensorflow/experimental/layers.py +++ b/ivy/functional/backends/tensorflow/experimental/layers.py @@ -5,6 +5,8 @@ # local from ivy.func_wrapper import ( + inputs_to_ivy_arrays, + output_to_native_arrays, with_unsupported_dtypes, with_supported_dtypes, with_supported_device_and_dtypes, @@ -1206,11 +1208,13 @@ def shape_initialization(shape, axes, x): def rank_initialization(axes): rank = tf.size(axes) - with tf.control_dependencies([ - tf.debugging.assert_less_equal( - rank, 3, message="N-D FFT supported only up to 3-D." - ) - ]): + with tf.control_dependencies( + [ + tf.debugging.assert_less_equal( + rank, 3, message="N-D FFT supported only up to 3-D." + ) + ] + ): rank = tf.identity(rank) return rank @@ -1401,8 +1405,8 @@ def rfft_operations(x, rank, norm_factor): }, ) norm_factor = tf.cast(norm_factor, tf.complex128) - x = x / norm_factor x = tf.cast(x, tf.complex128) + x = x / norm_factor return x @@ -1540,7 +1544,7 @@ def rfftn( s: Optional[Union[int, Tuple[int]]] = None, axes: Optional[Union[int, Tuple[int]]] = None, *, - norm: Optional[str] = [("forward", "ortho", "backward")], + norm: str = "backward", out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: result = _rfftn_helper(x, s, axes, norm) @@ -1675,3 +1679,34 @@ def sliding_window( return tf.image.extract_patches( images=input, sizes=kernel_size, strides=stride, rates=dilation, padding=padding ) + + +def rnn( + step_function, + inputs, + initial_states, + /, + *, + go_backwards: bool = False, + mask: Optional[Union[tf.Tensor, tf.Variable]] = None, + constants: Optional[Union[tf.Tensor, tf.Variable]] = None, + unroll: bool = False, + input_length: Optional[int] = None, + time_major: bool = False, + zero_output_for_mask: bool = False, + return_all_outputs: bool = True, +): + step_function = inputs_to_ivy_arrays(output_to_native_arrays(step_function)) + return tf.keras.backend.rnn( + step_function, + inputs, + initial_states, + go_backwards=go_backwards, + mask=mask, + constants=constants, + unroll=unroll, + input_length=input_length, + time_major=time_major, + zero_output_for_mask=zero_output_for_mask, + return_all_outputs=return_all_outputs, + ) diff --git a/ivy/functional/backends/tensorflow/experimental/linear_algebra.py b/ivy/functional/backends/tensorflow/experimental/linear_algebra.py index 4d54923e2e850..10d2f1b2c1705 100644 --- a/ivy/functional/backends/tensorflow/experimental/linear_algebra.py +++ b/ivy/functional/backends/tensorflow/experimental/linear_algebra.py @@ -1,13 +1,12 @@ from typing import Union, Optional, Tuple, List, Sequence import tensorflow as tf from functools import reduce as _reduce - +from collections import namedtuple import ivy from ivy.functional.ivy.experimental.linear_algebra import _check_valid_dimension_size from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes -from ivy.utils.exceptions import IvyNotImplementedException from .. import backend_version @@ -187,7 +186,7 @@ def multi_dot( return dot_out -@with_unsupported_dtypes({"1.25.0 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.15.0 and below": ("float16", "bfloat16")}, backend_version) def cond( x: Union[tf.Tensor, tf.Variable], /, @@ -229,14 +228,30 @@ def cond( return k +@with_unsupported_dtypes( + {"2.15.0 and below": ("integer", "float16", "bfloat16")}, backend_version +) def lu_factor( x: Union[tf.Tensor, tf.Variable], /, *, pivot: Optional[bool] = True, out: Optional[Union[tf.Tensor, tf.Variable]] = None, -) -> Tuple[tf.Tensor]: - raise IvyNotImplementedException() +) -> Tuple[tf.Tensor, tf.Tensor]: + ret = tf.linalg.lu(x) + ret_tuple = namedtuple("lu_factor", ["LU", "p"]) + return ret_tuple(ret.lu, ret.p) + + +def lu_solve( + lu: Union[tf.Tensor, tf.Variable], + p: Union[tf.Tensor, tf.Variable], + b: Union[tf.Tensor, tf.Variable], + /, + *, + out: Optional[Union[tf.Tensor, tf.Variable]] = None, +) -> Union[tf.Tensor, tf.Variable]: + return tf.linalg.lu_solve(lu, p, b) @with_supported_dtypes( diff --git a/ivy/functional/backends/tensorflow/experimental/losses.py b/ivy/functional/backends/tensorflow/experimental/losses.py index ecc812b53c085..404e2764b8d61 100644 --- a/ivy/functional/backends/tensorflow/experimental/losses.py +++ b/ivy/functional/backends/tensorflow/experimental/losses.py @@ -68,11 +68,11 @@ def soft_margin_loss( return loss -def _apply_loss_reduction(loss: tf.Tensor, reduction: str, axis) -> tf.Tensor: +def _apply_loss_reduction(loss: tf.Tensor, reduction: str) -> tf.Tensor: if reduction == "sum": - return tf.math.reduce_sum(loss, axis=axis) + return tf.math.reduce_sum(loss) elif reduction == "mean": - return tf.reduce_mean(loss, axis=axis) + return tf.reduce_mean(loss) else: # reduction == "none" return loss @@ -156,3 +156,30 @@ def poisson_nll_loss( cond = tf.math.logical_and(target_tensor >= zeros, target_tensor <= ones) loss = loss + tf.where(cond, zeros, stirling_approx) return _apply_loss_reduction(loss, reduction) + + +@with_supported_device_and_dtypes( + { + "2.14.0 and below": { + "cpu": ("float32", "float64"), + "gpu": ("float32", "float64"), + } + }, + backend_version, +) +def hinge_embedding_loss( + input: tf.Tensor, + target: tf.Tensor, + *, + margin: float = 1.0, + reduction: str = "mean", +) -> tf.Tensor: + zero_ = tf.zeros([1], dtype=input.dtype) + + relu_part = tf.math.maximum(margin - input, 0) + + loss = tf.where(tf.equal(target, 1.0), input, zero_) + tf.where( + tf.equal(target, -1.0), relu_part, zero_ + ) + + return _apply_loss_reduction(loss, reduction) diff --git a/ivy/functional/backends/tensorflow/experimental/manipulation.py b/ivy/functional/backends/tensorflow/experimental/manipulation.py index 43e286e1eb0a8..e188f00a8aaae 100644 --- a/ivy/functional/backends/tensorflow/experimental/manipulation.py +++ b/ivy/functional/backends/tensorflow/experimental/manipulation.py @@ -16,7 +16,7 @@ import tensorflow as tf # local -from ivy.func_wrapper import with_unsupported_dtypes +from ivy.func_wrapper import with_unsupported_dtypes, handle_out_argument from .. import backend_version import ivy from ivy.functional.ivy.experimental.manipulation import _to_tf_padding @@ -347,6 +347,10 @@ def expand( out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: shape = list(shape) + n_extra_dims = len(shape) - len(x.shape) + if n_extra_dims > 0: + new_shape = (1,) * n_extra_dims + tuple(x.shape) + x = tf.reshape(x, new_shape) for i, dim in enumerate(shape): if dim < 0: shape[i] = x.shape[i] @@ -561,3 +565,19 @@ def trim_zeros(a: tf.Tensor, /, *, trim: Optional[str] = "bf") -> tf.Tensor: last = tf.minimum(last, tf.cast(tf.shape(a)[0], tf.int64)) return a[first:last] + + +@handle_out_argument +def unflatten( + x: tf.Tensor, + /, + shape: Tuple[int] = None, + dim: Optional[int] = 0, + *, + out: Optional[tf.Tensor] = None, + name: Optional[str] = None, +) -> tf.Tensor: + dim = abs(len(x.shape) + dim) if dim < 0 else dim + res_shape = x.shape[:dim] + tf.TensorShape(shape) + x.shape[dim + 1 :] + res = tf.reshape(x, res_shape, name) + return res diff --git a/ivy/functional/backends/tensorflow/experimental/random.py b/ivy/functional/backends/tensorflow/experimental/random.py index c2742785656e3..2a1bff81f7029 100644 --- a/ivy/functional/backends/tensorflow/experimental/random.py +++ b/ivy/functional/backends/tensorflow/experimental/random.py @@ -90,15 +90,20 @@ def poisson( return ret +@with_unsupported_dtypes({"2.15.0 and below": ("bfloat16",)}, backend_version) def bernoulli( probs: Union[float, tf.Tensor, tf.Variable], *, logits: Union[float, tf.Tensor, tf.Variable] = None, shape: Optional[Union[ivy.NativeShape, Sequence[int]]] = None, device: Optional[str] = None, - dtype: DType, + dtype: Optional[str] = None, seed: Optional[int] = None, out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: - pass - # TODO: Implement purely in tensorflow + dtype = dtype if dtype is not None else probs.dtype + if logits is not None: + probs = tf.nn.softmax(logits, -1) + if not _check_shapes_broadcastable(shape, probs.shape): + shape = probs.shape + return tf.keras.backend.random_bernoulli(shape, probs, dtype, seed) diff --git a/ivy/functional/backends/tensorflow/experimental/statistical.py b/ivy/functional/backends/tensorflow/experimental/statistical.py index 1febdbbf918a2..537dd72bcaf09 100644 --- a/ivy/functional/backends/tensorflow/experimental/statistical.py +++ b/ivy/functional/backends/tensorflow/experimental/statistical.py @@ -53,6 +53,15 @@ def median( # TODO: Implement in pure tensorflow +@with_supported_dtypes( + { + "2.15.0 and below": ( + "float", + "complex", + ) + }, + backend_version, +) def nanmean( a: Union[tf.Tensor, tf.Variable], /, @@ -301,7 +310,7 @@ def bincount( out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: return tf.math.bincount( - x.numpy().tolist(), + x, weights=weights, minlength=minlength, dtype=x.dtype if weights is None else weights.dtype, diff --git a/ivy/functional/backends/tensorflow/general.py b/ivy/functional/backends/tensorflow/general.py index 70db8f5b6d040..c093b475cac89 100644 --- a/ivy/functional/backends/tensorflow/general.py +++ b/ivy/functional/backends/tensorflow/general.py @@ -49,7 +49,7 @@ def current_backend_str() -> str: def _check_query(query): return not isinstance(query, list) and ( - not (ivy.is_array(query) and ivy.is_bool_dtype(query) and bool(query.ndim > 0)) + not (ivy.is_array(query) and bool(query.ndim > 0)) ) @@ -60,12 +60,15 @@ def get_item( *, copy: Optional[bool] = None, ) -> Union[tf.Tensor, tf.Variable]: + if ivy.is_array(query) and ivy.is_bool_dtype(query): + if not len(query.shape): + return tf.expand_dims(x, 0) return x.__getitem__(query) get_item.partial_mixed_handler = lambda x, query, **kwargs: ( all(_check_query(i) for i in query) - and len({i.shape for i in query if ivy.is_array(i)}) == 1 + and len({i.shape for i in query if ivy.is_array(i)}) <= 1 if isinstance(query, tuple) else _check_query(query) ) diff --git a/ivy/functional/backends/tensorflow/layers.py b/ivy/functional/backends/tensorflow/layers.py index a983821bd6a13..a9d3d7dd40f63 100644 --- a/ivy/functional/backends/tensorflow/layers.py +++ b/ivy/functional/backends/tensorflow/layers.py @@ -30,15 +30,11 @@ def linear( out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: # TODO: try to generalize this for >=2 dimensions - if len(x.shape) == 2 and len(weight.shape) == 2: - if x.shape[-1] == weight.shape[-2]: - result = tf.matmul(x, weight) - elif x.shape[-1] == weight.shape[-1]: - result = tf.matmul(x, weight, transpose_b=True) - else: - result = tf.einsum("...i,...ji->...j", x, weight) - else: - result = tf.einsum("...i,...ji->...j", x, weight) + result = ( + tf.matmul(x, weight, transpose_b=True) + if len(x.shape) == len(weight.shape) == 2 and x.shape[-1] == weight.shape[-1] + else tf.einsum("...i,...ji->...j", x, weight) + ) if bias is not None: return tf.add(result, bias) @@ -471,27 +467,17 @@ def conv_general_dilated( dilations=dilations, ) else: - res = tf.concat( - [ - tf.nn.conv2d( - x[..., i : i + filters.shape[-2]], - filters[..., j : j + filters.shape[-1] // feature_group_count], - strides, - padding, - data_format, - dilations, - ) - for i, j in zip( - range(0, x.shape[-1], filters.shape[-2]), - range( - 0, - filters.shape[-1], - filters.shape[-1] // feature_group_count, - ), - ) - ], - axis=-1, - ) + with ivy.ArrayMode(False): + if not isinstance(padding, str): + padding = padding[1:-1] + res = depthwise_conv2d( + x, + tf.transpose(filters, (0, 1, 3, 2)), + strides, + padding, + data_format=data_format, + dilations=dilations, + ) else: x, padding = _pad_before_conv(x, padding, dims, data_format) if dims == 1: @@ -720,8 +706,13 @@ def step(cell_inputs, cell_states): h_tm1 = cell_states[0] # previous memory state c_tm1 = cell_states[1] # previous carry state - z = tf.keras.backend.dot(cell_inputs, kernel) + bias - z += tf.keras.backend.dot(h_tm1, recurrent_kernel) + recurrent_bias + z = tf.keras.backend.dot(cell_inputs, kernel) + if bias is not None: + z += bias + + z += tf.keras.backend.dot(h_tm1, recurrent_kernel) + if recurrent_bias is not None: + z += recurrent_bias z0, z1, z2, z3 = tf.split(z, 4, axis=-1) diff --git a/ivy/functional/backends/tensorflow/linear_algebra.py b/ivy/functional/backends/tensorflow/linear_algebra.py index f6b412c9cb190..fc31085e3ba6f 100644 --- a/ivy/functional/backends/tensorflow/linear_algebra.py +++ b/ivy/functional/backends/tensorflow/linear_algebra.py @@ -288,8 +288,11 @@ def matrix_norm( ord: Union[int, float, Literal[inf, -inf, "fro", "nuc"]] = "fro", axis: Tuple[int, int] = (-2, -1), keepdims: bool = False, + dtype: Optional[tf.DType] = None, out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: + if dtype is not None: + x = ivy.astype(x, dtype) if ord == "nuc": x = tf.experimental.numpy.moveaxis(x, axis, (-2, -1)) ret = tf.reduce_sum( diff --git a/ivy/functional/backends/tensorflow/manipulation.py b/ivy/functional/backends/tensorflow/manipulation.py index 9ef86b5bc16bb..8635ca5ebb173 100644 --- a/ivy/functional/backends/tensorflow/manipulation.py +++ b/ivy/functional/backends/tensorflow/manipulation.py @@ -66,7 +66,7 @@ def expand_dims( ret = tf.reshape(x, shape=out_shape) return ret except (tf.errors.InvalidArgumentError, np.AxisError) as error: - raise ivy.utils.exceptions.IvyIndexError(error) + raise ivy.utils.exceptions.IvyIndexError(error) from error def flip( @@ -85,7 +85,7 @@ def flip( new_axis = list(range(num_dims)) else: new_axis = axis - if type(new_axis) is int: + if isinstance(new_axis, int): new_axis = [new_axis] else: new_axis = new_axis @@ -196,7 +196,7 @@ def stack( try: return tf.experimental.numpy.stack(arrays, axis) except ValueError as e: - raise ivy.utils.exceptions.IvyIndexError(e) + raise ivy.utils.exceptions.IvyIndexError(e) from e # Extra # @@ -226,7 +226,6 @@ def split( num_or_size_splits = int(dim_size) if isinstance(num_or_size_splits, (tf.Tensor, tf.Variable)): num_or_size_splits = tf.cast(num_or_size_splits, tf.int32) - num_or_size_splits = num_or_size_splits.numpy().tolist() elif isinstance(num_or_size_splits, int) and with_remainder: num_chunks = x.shape[axis] / num_or_size_splits num_chunks_int = math.floor(num_chunks) diff --git a/ivy/functional/backends/tensorflow/module.py b/ivy/functional/backends/tensorflow/module.py new file mode 100644 index 0000000000000..a6487f0377604 --- /dev/null +++ b/ivy/functional/backends/tensorflow/module.py @@ -0,0 +1,893 @@ +# global +from __future__ import annotations +import re +import os +import tensorflow as tf +import functools +import logging +from tensorflow.python.util import nest +from typing import NamedTuple, Callable, Any, Tuple, List, Dict, Type, Union + +# A NodeDef holds two callables: +# - flatten_fn should take the collection and return a flat list of values. +# It can also return some context that is used in reconstructing the +# collection. +# - unflatten_fn should take a flat list of values and some context +# (returned by flatten_fn). It returns the collection by reconstructing +# it from the list and the context. +Context = Any +PyTree = Any +FlattenFunc = Callable[[PyTree], Tuple[List, Context]] +UnflattenFunc = Callable[[List, Context], PyTree] + + +class NodeDef(NamedTuple): + flatten_fn: FlattenFunc + unflatten_fn: UnflattenFunc + + +SUPPORTED_NODES: Dict[Type[Any], NodeDef] = {} + + +def _register_pytree_node( + typ: Any, flatten_fn: FlattenFunc, unflatten_fn: UnflattenFunc +) -> None: + SUPPORTED_NODES[typ] = NodeDef(flatten_fn, unflatten_fn) + + +def _dict_flatten(d: Dict[Any, Any]) -> Tuple[List[Any], Context]: + return list(d.values()), list(d.keys()) + + +def _dict_unflatten(values: List[Any], context: Context) -> Dict[Any, Any]: + return {key: value for key, value in zip(context, values)} + + +_register_pytree_node(dict, _dict_flatten, _dict_unflatten) + + +def _get_node_type(pytree: Any) -> Any: + return type(pytree) + + +# A leaf is defined as anything that is not a Node. +def _is_leaf(pytree: PyTree) -> bool: + return _get_node_type(pytree) not in SUPPORTED_NODES.keys() + + +# A TreeSpec represents the structure of a pytree. It holds: +# "type": the type of root Node of the pytree +# context: some context that is useful in unflattening the pytree +# children_specs: specs for each child of the root Node +# num_leaves: the number of leaves +class TreeSpec: + def __init__(self, type, context, children_specs): + self.type: Any = type + self.context: Context = context + self.children_specs: List["TreeSpec"] = children_specs + self.num_leaves: int = sum([spec.num_leaves for spec in self.children_specs]) + + def get_keychains(self, prefix="", sep="/"): + keychains = [] + for key, child_spec in zip(self.context, self.children_specs): + new_prefix = prefix + key + sep if prefix else key + sep + if child_spec.children_specs: # Non-leaf node + keychains.extend(child_spec.get_keychains(new_prefix, sep)) + else: # Leaf node + keychains.append(new_prefix[: -len(sep)]) + return keychains + + def __repr__(self, indent: int = 0) -> str: + repr_prefix: str = f"TreeSpec({self.type.__name__}, {self.context}, [" + children_specs_str: str = "" + if len(self.children_specs): + indent += len(repr_prefix) + children_specs_str += self.children_specs[0].__repr__(indent) + children_specs_str += "," if len(self.children_specs) > 1 else "" + children_specs_str += ",".join( + [ + "\n" + " " * indent + child.__repr__(indent) + for child in self.children_specs[1:] + ] + ) + repr_suffix: str = f"{children_specs_str}])" + return repr_prefix + repr_suffix + + +class LeafSpec(TreeSpec): + def __init__(self) -> None: + super().__init__(None, None, []) + self.num_leaves = 1 + + def __repr__(self, indent: int = 0) -> str: + return "*" + + +def tree_flatten(pytree: PyTree) -> Tuple[List[Any], TreeSpec]: + """Flattens a pytree into a list of values and a TreeSpec that can be used + to reconstruct the pytree.""" + if _is_leaf(pytree): + return [pytree], LeafSpec() + + node_type = _get_node_type(pytree) + flatten_fn = _dict_flatten + child_pytrees, context = flatten_fn(pytree) + + # Recursively flatten the children + result: List[Any] = [] + children_specs: List["TreeSpec"] = [] + for child in child_pytrees: + flat, child_spec = tree_flatten(child) + result += flat + children_specs.append(child_spec) + + return result, TreeSpec(node_type, context, children_specs) + + +def tree_unflatten(values: List[Any], spec: TreeSpec) -> PyTree: + """Given a list of values and a TreeSpec, builds a pytree. + + This is the inverse operation of `tree_flatten`. + """ + if not isinstance(spec, TreeSpec): + raise TypeError( + f"tree_unflatten(values, spec): Expected `spec` to be instance of " + f"TreeSpec but got item of type {type(spec)}." + ) + if len(values) != spec.num_leaves: + raise TypeError( + f"tree_unflatten(values, spec): `values` has length {len(values)} " + f"but the spec refers to a pytree that holds {spec.num_leaves} " + f"items ({spec})." + ) + if isinstance(spec, LeafSpec): + return values[0] + + unflatten_fn = _dict_unflatten + + # Recursively unflatten the children + start = 0 + end = 0 + child_pytrees = [] + for child_spec in spec.children_specs: + end += child_spec.num_leaves + child_pytrees.append(tree_unflatten(values[start:end], child_spec)) + start = end + + return unflatten_fn(child_pytrees, spec.context) + + +class ModelHelpers: + @staticmethod + @tf.autograph.experimental.do_not_convert + def _get_first_array(*args, **kwargs): + arr = None + flattened_args = tf.nest.flatten((args, kwargs)) + arr_candidates = tf.nest.map_structure( + lambda x: x if isinstance(x, (tf.Tensor, tf.Variable)) else False, + flattened_args, + ) + for arr_candidate in arr_candidates: + if arr_candidate is not False: + arr = arr_candidate + break + return arr + + @staticmethod + @tf.autograph.experimental.do_not_convert + def _get_input_shapes(*args): + input_shapes = [] + for x in args: + if isinstance(x, (tf.Tensor, tf.Variable)): + input_shapes.append(x.shape) + else: + try: + x = tf.convert_to_tensor(x) + input_shapes.append(x.shape) + except Exception: + input_shapes.append(None) + return input_shapes + + @staticmethod + @tf.autograph.experimental.do_not_convert + def _extract_v(v, keychain_mappings: dict, orig_key_chain, /): + if ModelHelpers._dict_has_key_chain(v, orig_key_chain): + ret_cont = ModelHelpers._dict_at_key_chain(v, orig_key_chain) + else: + ret_cont = dict() + for old_kc, new_kc in keychain_mappings.items(): + if orig_key_chain in old_kc: + # Check if `v` contains `new_kc` before replacing in `ret_cont` + if ModelHelpers._dict_has_key_chain(v, new_kc): + ret_cont = ModelHelpers._dict_set_at_key_chain( + ret_cont, + "/".join(old_kc.split("/")[1:]), + ModelHelpers._dict_at_key_chain(v, new_kc), + ) + else: + continue + return ret_cont + + @staticmethod + @tf.autograph.experimental.do_not_convert + def _remove_duplicate_variables(vs, created, /): + created_ids = tf.nest.map_structure(lambda x: id(x), created) + vs_ids = tf.nest.map_structure(lambda x: id(x), vs) + ids = {} + duplicate_keychains = [] + keychain_mappings = {} + + def unique_callback(x, kc): + ids[x] = kc + return x + + def found_dup_callback(x, kc): + if ids[x] == kc: + return x + duplicate_keychains.append(kc) + keychain_mappings[kc] = ids[x] + return x + + created_ids = nest.map_structure_with_paths( + lambda kc, x: unique_callback(x, kc), created_ids + ) + vs_ids = nest.map_structure_with_paths( + lambda kc, x: ( + unique_callback(x, kc) if x not in ids else found_dup_callback(x, kc) + ), + vs_ids, + ) + for dup_kc in duplicate_keychains: + vs = ModelHelpers._dict_prune_key_chain(vs, dup_kc) + return vs, keychain_mappings + + @staticmethod + @tf.autograph.experimental.do_not_convert + def _dict_set_at_key_chain(in_dict, key_chain, val, inplace=False): + keys = re.split("[/.]", key_chain) + if inplace: + cont = in_dict + else: + cont = in_dict + sub_cont = cont + for key in keys[:-1]: + if key not in sub_cont: + sub_cont[key] = dict() + sub_cont = sub_cont[key] + sub_cont[keys[-1]] = val + return cont + + @staticmethod + @tf.autograph.experimental.do_not_convert + def _dict_at_key_chain(dict, key_chain, ignore_key_errors=False): + keys = re.split("[/.]", key_chain) + ret = dict + for key in keys: + try: + ret = ret[key] + except KeyError as e: + if ignore_key_errors: + return + raise Exception(repr(e)) + return ret + + @staticmethod + @tf.autograph.experimental.do_not_convert + def _dict_has_key_chain(dict, key_chain): + keys = re.split("[/.]", key_chain) + ret = dict + for key in keys: + try: + ret = ret[key] + except KeyError: + return False + return True + + @staticmethod + @tf.autograph.experimental.do_not_convert + def _dict_prune_key_chain(in_dict, key_chain): + keys_in_chain = re.split("[/.]", key_chain) + out_dict = {} + for key, value in in_dict.items(): + if isinstance(value, dict): + if key == keys_in_chain[0]: + if len(keys_in_chain) == 1: + new_val = [] + else: + new_val = ModelHelpers._dict_prune_key_chain( + value, + "/".join(keys_in_chain[1:]), + ) + if len(new_val) > 0: + out_dict[key] = new_val + else: + if len(value) > 0: + out_dict[key] = value + else: + if len(keys_in_chain) != 1 or key != keys_in_chain[0]: + out_dict[key] = value + return out_dict + + @staticmethod + @tf.autograph.experimental.do_not_convert + def _addindent(s_, numSpaces): + s = s_.split("\n") + # don't do anything for single-line stuff + if len(s) == 1: + return s_ + first = s.pop(0) + s = [(numSpaces * " ") + line for line in s] + s = "\n".join(s) + s = first + "\n" + s + return s + + +class Model(tf.keras.Model, ModelHelpers): + _build_mode = None + _with_partial_v = None + _store_vars = True + _built = False + _v = None + _buffers = None + _module_dict = None + _args = None + _kwargs = None + _module_graph = None + _target = None + _lazy_traced = False + _training = None + _dynamic_backend = None + _device = None + _dtype = None + + def __init__( + self, + /, + *args, + v=None, + buffers=None, + build_mode="on_init", + store_vars=True, + with_partial_v=False, + dynamic_backend=None, + training=True, + dtype=None, + device=None, + **kwargs, + ): + super(Model, self).__init__( + trainable=training, + dtype=dtype, + ) + self._build_mode = build_mode + self._with_partial_v = with_partial_v + self._store_vars = store_vars + self._built = False + self._v_from_constructor = v if isinstance(v, dict) or v is None else dict(v) + self._v = v if v is not None else dict() + self._buffers = dict(buffers or {}) + self._module_dict = dict() + self._args = args + self._kwargs = kwargs + self._module_graph = None + self._target = None + self._lazy_traced = False + self._training = training + self._dynamic_backend = dynamic_backend + self._device = device or "cpu" + self._dtype = dtype or tf.float32 + if build_mode != "on_init": + return + self.build(*args, dynamic_backend=dynamic_backend, **kwargs) + + @tf.autograph.experimental.do_not_convert + def _find_variables( + self, + /, + *, + obj=None, + without_initialisation=False, + _visited=None, + ): + _visited = _visited or {} + vs = dict() + if id(obj) in _visited: + return vs + _visited[id(obj)] = True + if isinstance(obj, Model) and obj is not self: + if not obj._built and without_initialisation: + return lambda: obj._build_and_return_v( + *obj._args, dynamic_backend=self._dynamic_backend, **obj._kwargs + ) + + return obj._build_and_return_v( + *obj._args, dynamic_backend=obj._dynamic_backend, **obj._kwargs + ) + elif isinstance(obj, (list, tuple)): + for i, v in enumerate(obj): + ret = self._find_variables( + obj=v, + without_initialisation=without_initialisation, + _visited=_visited, + ) + if ret: + vs[f"v{str(i)}"] = ret + return vs + elif isinstance(obj, dict): + for k, v in obj.items(): + ret = self._find_variables( + obj=v, + without_initialisation=without_initialisation, + _visited=_visited, + ) + if ret: + vs[k[1:] if k[0] == "_" else k] = ret + return vs + elif not hasattr(obj, "__dict__"): + return vs + for k, v in obj.__dict__.items(): + if ( + v is not None + and k[0:2] != "__" + and not k.startswith( + ( + "_module_dict", + "_self_", + ) + ) + ): + ret = self._find_variables( + obj=v, + without_initialisation=without_initialisation, + _visited=_visited, + ) + if ret: + vs[k[1:] if k[0] == "_" else k] = ret + return vs + + @tf.autograph.experimental.do_not_convert + def _find_buffers(self): + if hasattr(self, "_module_dict"): + for key, sub_module in self._module_dict.items(): + if len(sub_module._buffers) > 0: + self._buffers[key] = sub_module._buffers + + @tf.autograph.experimental.do_not_convert + def _build_and_return_v(self, *args, **kwargs): + if not self._built: + self.build(*args, **kwargs) + return self.v + + @tf.autograph.experimental.do_not_convert + def _assign_weights(self): + model_weights = {} + existing_ids = [id(w) for w in self.weights] + + # trainable weights + flattened_v, v_spec = tree_flatten(self.v) + flattened_kc = v_spec.get_keychains() + new_weights = [None] * len(flattened_v) + for i, (kc, x) in enumerate(zip(flattened_kc, flattened_v)): + new_weights[i] = ( + self.add_weight(name=kc, shape=x.shape, dtype=x.dtype, trainable=True) + if x is not None and id(x) not in existing_ids + else x + ) + if isinstance(x, tf.Variable): + new_weights[i].assign(x.value()) + if new_weights[i] is not None: + model_weights[id(new_weights[i])] = new_weights[i].numpy() + self.v = tree_unflatten(new_weights, v_spec) + + # non-trainable weights + flattened_buf, buf_spec = tree_flatten(self.buffers) + flattened_kc = buf_spec.get_keychains() + new_buf = [None] * len(flattened_buf) + for i, (kc, x) in enumerate(zip(flattened_kc, flattened_buf)): + new_buf[i] = ( + self.add_weight(name=kc, shape=x.shape, dtype=x.dtype, trainable=False) + if x is not None and id(x) not in existing_ids + else x + ) + if isinstance(x, tf.Variable): + new_buf[i].assign(x.value()) + if new_buf[i] is not None: + model_weights[id(new_buf[i])] = new_buf[i].numpy() + self.buffers = tree_unflatten(new_buf, buf_spec) + + def _sort_weights(model_weights, weights): + sorted_weights = [] + for weight in weights: + sorted_weights.append(model_weights[id(weight)]) + return sorted_weights + + if model_weights: + self.set_weights(_sort_weights(model_weights, self.weights)) + + @tf.autograph.experimental.do_not_convert + def build( + self, + *args, + from_call=False, + device=None, + dtype=None, + dynamic_backend=None, + **kwargs, + ): + self._device = device or self._device + self._dtype = dtype or self._dtype + self._dynamic_backend = dynamic_backend or self._dynamic_backend + # return False if not from_call but build_mode is on_call + if not from_call and self._build_mode == "on_call": + return self.v + + # build local Module, and any child modules flagged with "explicit" build mode + # this gets the child modules initialised at best, their weights + # remain un-generated + built = self._build(*args, **kwargs) or True + + # this creates weights for this Module only + created = self._create_variables(device=self._device, dtype=dtype) + created = ( + created.cont_to_dict() if hasattr(created, "cont_to_dict") else created + ) + + # build variables based on locally built layers, if v not passed in constructor + created_n_found = dict( + **self._find_variables( + obj=self, + without_initialisation=( + True + if self._v_from_constructor and not self._with_partial_v + else False + ), + ), + **created, + ) + if self._v_from_constructor: + # TODO: Add logic here for when `v` is passed in the constructor + raise Exception("TODO: Implement this logic") + else: + self._v = created_n_found + # remove duplicates + self._v, keychain_mappings = self._remove_duplicate_variables(self._v, created) + # build any child 'on_call' layers + if not built and from_call: + # TODO: Add logic for here + raise Exception("TODO: Implement this logic") + + # flag built and remove local variables if specified + self._built = bool(built) + v_ret = self.v + if not self._store_vars: + # ToDo: verify variables in self.v are released once this method exits + self._v = dict() + + # compute the module dict + self._compute_module_dict() + + # once all variables built, find and assign buffers + self._find_buffers() + + # also assign the keras model trainable and non-trainable weights now + self._assign_weights() + + # wrap call methods if the model is fully built + if built: + self._wrap_call_methods(keychain_mappings, obj=self) + + return v_ret if bool(v_ret) or isinstance(built, bool) else built + + @tf.autograph.experimental.do_not_convert + def _wrap_call_methods( + self, keychain_mappings, /, *, key="", obj=None, _visited=None + ): + _visited = _visited or {} + if id(obj) in _visited or not isinstance(key, str): + return + _visited[id(obj)] = True + if isinstance(obj, Model) and obj is not self: + orig_key_chain = key[1:] if key[0] == "_" else key + + obj.__call__ = self._fn_with_var_arg( + obj.__call__, self._extract_v, keychain_mappings, orig_key_chain + ) + return + elif isinstance(obj, (list, tuple)): + for i, val in enumerate(obj): + self._wrap_call_methods( + keychain_mappings, + key=f"{key}/v{str(i)}", + obj=val, + _visited=_visited, + ) + return + elif isinstance(obj, dict): + for k, val in obj.items(): + k = f"{key}/{k}" if key != "" and isinstance(k, str) else k + self._wrap_call_methods( + keychain_mappings, key=k, obj=val, _visited=_visited + ) + return + for k, val in obj.module_dict.items(): + if k.startswith(("__", "_self_")): + continue + k = f"{key}/{k}" if key != "" else k + if val is not None: + self._wrap_call_methods( + keychain_mappings, key=k, obj=val, _visited=_visited + ) + return + + @tf.autograph.experimental.do_not_convert + def _call(self, *args, v=None, buffers=None, **kwargs): + if not self._built or not self.built: + if not self._built: + first_arr = self._get_first_array(*args, **kwargs) + self.build( + *args, + **kwargs, + from_call=True, + dtype=first_arr.dtype if first_arr is not None else tf.float32, + ) + + if not self.built: + # Don't use `keras` build method + if os.environ.get("USE_KERAS_BUILD", "False").lower() == "false": + self.inputs = tf.nest.flatten(args) + + input_shapes = self._get_input_shapes(*args) + if len(input_shapes) == 0: + input_shapes = tf.TensorShape(None) + elif len(input_shapes) == 1: + input_shapes = input_shapes[0] + + super(Model, self).build(input_shapes) # noqa: UP008 + + # If `v` was provided, replace with the module's v + replace_v = False + if v is not None: + v_orig = self.v + self._v = v + replace_v = True + + # If `buffers` were provided, replace with the module's buffers + replace_buffers = False + if buffers is not None: + buffers_orig = self.buffers + self._buffers = buffers + replace_buffers = True + + if replace_v or replace_buffers: + # Call the forward pass + ret = super(Model, self).__call__(*args, **kwargs) # noqa: UP008 + # Replace v, buffers if needed + self._v = v_orig if replace_v else self._v + self._buffers = buffers_orig if replace_buffers else self._buffers + return ret + elif hasattr(self.__call__, "wrapped"): + return self.__call__(*args, **kwargs) + return super(Model, self).__call__(*args, **kwargs) # noqa: UP008 + + @tf.autograph.experimental.do_not_convert + def _rebuild(self): + logging.warning( + "Building the module again as a trainable module was modified, " + 'please use the "explicit" or "on_call" build_modes instead ' + 'of "on_init" to avoid repetitive building after each addition' + ) + self._v = dict() + self._built = False + self.build(*self._args, **self._kwargs) + + @tf.autograph.experimental.do_not_convert + def _compute_module_dict(self): + self._module_dict = dict() + for key, value in self.__dict__.items(): + if isinstance(value, Model): + if "stateful" in value.__module__ or hasattr(value, "_frontend_module"): + self._module_dict[key] = value + else: + self._module_dict[key] = value._module_dict + + @tf.autograph.experimental.do_not_convert + def _fn_with_var_arg_wrapper( + self, *a, fn, v_fn, keychain_mappings, orig_key_chain, **kw + ): + if "v" in kw: + del kw["v"] + v = v_fn(self.v, keychain_mappings, orig_key_chain) + return fn(*a, **kw, v=v) + + @tf.autograph.experimental.do_not_convert + def _fn_with_var_arg(self, fn, v_fn, /, keychain_mappings, orig_key_chain): + _fn_with_var_arg_wrapper = functools.partial( + self._fn_with_var_arg_wrapper, + fn=fn, + v_fn=v_fn, + keychain_mappings=keychain_mappings, + orig_key_chain=orig_key_chain, + ) + _fn_with_var_arg_wrapper.wrapped = True + return _fn_with_var_arg_wrapper + + @tf.autograph.experimental.do_not_convert + def register_buffer(self, name: str, value: Union[tf.Tensor, tf.Variable]): + if value is not None: + self._buffers.update({name: value}) + else: + self.__setattr__(name, value) + + @tf.autograph.experimental.do_not_convert + def register_parameter(self, name: str, value: Union[tf.Tensor, tf.Variable]): + self._v.update({name: value}) + + @tf.autograph.experimental.do_not_convert + def train(self, mode: bool = True): + self._training = mode + for module in self.children(): + module.train(mode) + self.trainable = mode + return self + + @tf.autograph.experimental.do_not_convert + def eval(self): + return self.train(mode=False) + + @tf.autograph.experimental.do_not_convert + def call(self, inputs, training=None, mask=None): + raise NotImplementedError( + "When subclassing the `Model` class, you should implement a `call` method." + ) + + # Methods to be Optionally Overridden # + # -----------------------------------# + + @tf.autograph.experimental.do_not_convert + def _create_variables(self, *, device=None, dtype=None): + return {} + + @tf.autograph.experimental.do_not_convert + def _build(self, *args, **kwargs) -> bool: + return True + + @tf.autograph.experimental.do_not_convert + def _forward(self, *args, **kwargs): + raise NotImplementedError( + "When subclassing the `Model` class, you should " + "implement a `_forward` method." + ) + + @tf.autograph.experimental.do_not_convert + def _extra_repr(self) -> str: + return "" + + # Properties # + # -----------# + + @property + def device(self): + return self._device + + @property + def dtype(self): + return self._dtype + + @property + def build_mode(self): + return self._build_mode + + @property + def training(self): + return self._training + + @property + def v(self): + return self._v + + @property + def buffers(self): + return self._buffers + + @property + def state_dict(self): + return {**self.v, **self.buffers} + + @property + def module_dict(self): + return self._module_dict + + # Dunder Methods # + # ---------------# + + @tf.autograph.experimental.do_not_convert + def __call__( + self, + *args, + v=None, + buffers=None, + **kwargs, + ): + # TODO: Temp workaround to avoid `call`` from being transformed by AutoGraph + if not hasattr(self.__class__.call, "autograph_info__"): + setattr(self.__class__.call, "autograph_info__", True) + ret = self._call(*args, v=v, buffers=buffers, **kwargs) + return ret + + @tf.autograph.experimental.do_not_convert + def __getattr__(self, name): + if name == "v": + if not super().__getattribute__("_v") and not getattr( # noqa: E501 + self, "_built", False + ): + return self._build_and_return_v( + *self._args, dynamic_backend=self._dynamic_backend, **self._kwargs + ) + + _dict = super().__getattribute__("__dict__") + if name in _dict: + return _dict[name] + + elif "_v" in _dict and name in _dict["_v"]: + return _dict["_v"][name] + + return super().__getattribute__(name) + + @tf.autograph.experimental.do_not_convert + def __setattr__(self, name, value): + if name in ["v", "buffers"]: + name = "_" + name + if isinstance(value, Model): + ret = super().__setattr__(name, value) + if ( + hasattr(self, "_build_mode") + and self.build_mode == "on_init" + and getattr(self, "_built", False) + ): + self._rebuild() + return ret + elif isinstance(value, tf.Variable) and not name.startswith("_"): + ret = self.register_parameter(name, value) + if ( + hasattr(self, "_build_mode") + and self.build_mode == "on_init" + and getattr(self, "_built", False) + ): + self._rebuild() + return ret + return super().__setattr__(name, value) + + @tf.autograph.experimental.do_not_convert + def __delattr__(self, name): + if hasattr(self, name): + if isinstance(getattr(self, name), Model): + super().__delattr__(name) + if self.build_mode == "on_init": + self._rebuild() + return + super().__delattr__(name) + + @tf.autograph.experimental.do_not_convert + def __repr__(self): + extra_lines = [] + extra_repr = self._extra_repr() + if extra_repr: + extra_lines = extra_repr.split("\n") + child_lines = [] + for key in self.v.keys(): + if isinstance(getattr(self, key, None), Model): + mod_str = repr(getattr(self, key)) + mod_str = self._addindent(mod_str, 2) + child_lines.append(f"({key}): {mod_str}") + lines = extra_lines + child_lines + + main_str = f"{self.__class__.__name__}(" + if lines: + # simple one-liner info, which most builtin Modules will use + if len(extra_lines) == 1 and not child_lines: + main_str += extra_lines[0] + else: + main_str += "\n " + "\n ".join(lines) + "\n" + + main_str += ")" + return main_str diff --git a/ivy/functional/backends/tensorflow/random.py b/ivy/functional/backends/tensorflow/random.py index dcb320508614d..65828a02669d9 100644 --- a/ivy/functional/backends/tensorflow/random.py +++ b/ivy/functional/backends/tensorflow/random.py @@ -80,10 +80,12 @@ def multinomial( ) -> Union[tf.Tensor, tf.Variable]: if probs is None: probs = ( - tf.ones(( - batch_size, - population_size, - )) + tf.ones( + ( + batch_size, + population_size, + ) + ) / population_size ) diff --git a/ivy/functional/backends/tensorflow/searching.py b/ivy/functional/backends/tensorflow/searching.py index 660576fe75bb2..0b1abe892c9e3 100644 --- a/ivy/functional/backends/tensorflow/searching.py +++ b/ivy/functional/backends/tensorflow/searching.py @@ -45,6 +45,7 @@ def argmax( return tf.cast(ret, dtype) if dtype is not None else ret +@with_unsupported_dtypes({"2.15.0 and below": ("complex",)}, backend_version) def argmin( x: Union[tf.Tensor, tf.Variable], /, diff --git a/ivy/functional/backends/tensorflow/statistical.py b/ivy/functional/backends/tensorflow/statistical.py index 5fe0d43121805..95db57526ef9b 100644 --- a/ivy/functional/backends/tensorflow/statistical.py +++ b/ivy/functional/backends/tensorflow/statistical.py @@ -12,19 +12,34 @@ # -------------------# -@with_unsupported_dtypes({"2.15.0 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes( + {"2.15.0 and below": ("complex", "bool", "uint64")}, backend_version +) def min( x: Union[tf.Tensor, tf.Variable], /, *, axis: Optional[Union[int, Sequence[int]]] = None, keepdims: bool = False, + initial: Optional[Union[int, float, complex]] = None, + where: Optional[Union[tf.Tensor, tf.Variable]] = None, out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: axis = tuple(axis) if isinstance(axis, list) else axis - return tf.math.reduce_min(x, axis=axis, keepdims=keepdims) + if where is not None: + max_val = ( + ivy.iinfo(x.dtype).max + if ivy.is_int_dtype(x.dtype) + else ivy.finfo(x.dtype).max + ) + x = tf.where(where, x, tf.ones_like(x) * max_val) + result = tf.math.reduce_min(x, axis=axis, keepdims=keepdims) + if initial is not None: + result = tf.minimum(result, initial) + return result +@with_unsupported_dtypes({"2.15.0 and below": ("bool",)}, backend_version) def max( x: Union[tf.Tensor, tf.Variable], /, @@ -163,7 +178,7 @@ def var( # ------# -@with_unsupported_dtypes({"2.15.0 and below": "bfloat16"}, backend_version) +@with_unsupported_dtypes({"2.15.0 and below": ("bfloat16", "bool")}, backend_version) def cumprod( x: Union[tf.Tensor, tf.Variable], /, @@ -185,6 +200,7 @@ def cumprod( return tf.math.cumprod(x, axis, exclusive, reverse) +@with_unsupported_dtypes({"2.15.0 and below": "bool"}, backend_version) def cumsum( x: Union[tf.Tensor, tf.Variable], axis: int = 0, diff --git a/ivy/functional/backends/tensorflow/sub_backends/tf_probability/experimental/random.py b/ivy/functional/backends/tensorflow/sub_backends/tf_probability/experimental/random.py index ef672977bb4d2..b33cd8304df18 100644 --- a/ivy/functional/backends/tensorflow/sub_backends/tf_probability/experimental/random.py +++ b/ivy/functional/backends/tensorflow/sub_backends/tf_probability/experimental/random.py @@ -63,6 +63,7 @@ def bernoulli( seed: Optional[int] = None, out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: + dtype = dtype if dtype is not None else probs.dtype if seed is not None: tf.random.set_seed(seed) if logits is not None: diff --git a/ivy/functional/backends/tensorflow/utility.py b/ivy/functional/backends/tensorflow/utility.py index 997b6dca682dc..e267a1533c458 100644 --- a/ivy/functional/backends/tensorflow/utility.py +++ b/ivy/functional/backends/tensorflow/utility.py @@ -15,7 +15,6 @@ def all( keepdims: bool = False, out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: - x = tf.constant(x) if axis is None: num_dims = len(x.shape) axis = tuple(range(num_dims)) @@ -24,7 +23,7 @@ def all( try: return tf.reduce_all(tf.cast(x, tf.bool), axis=axis, keepdims=keepdims) except tf.errors.InvalidArgumentError as e: - raise ivy.utils.exceptions.IvyIndexError(e) + raise ivy.utils.exceptions.IvyIndexError(e) from e def any( @@ -35,7 +34,6 @@ def any( keepdims: bool = False, out: Optional[Union[tf.Tensor, tf.Variable]] = None, ) -> Union[tf.Tensor, tf.Variable]: - x = tf.constant(x) if axis is None: num_dims = len(x.shape) axis = tuple(range(num_dims)) @@ -44,4 +42,4 @@ def any( try: return tf.reduce_any(tf.cast(x, tf.bool), axis=axis, keepdims=keepdims) except tf.errors.InvalidArgumentError as e: - raise ivy.utils.exceptions.IvyIndexError(e) + raise ivy.utils.exceptions.IvyIndexError(e) from e diff --git a/ivy/functional/backends/torch/__init__.py b/ivy/functional/backends/torch/__init__.py index 922b6ff3506bb..a9df06e5a6129 100644 --- a/ivy/functional/backends/torch/__init__.py +++ b/ivy/functional/backends/torch/__init__.py @@ -129,7 +129,7 @@ def rep_method(*args, **kwargs): # update these to add new dtypes valid_dtypes = { - "2.1.2 and below": ( + "2.2 and below": ( ivy.int8, ivy.int16, ivy.int32, @@ -147,7 +147,7 @@ def rep_method(*args, **kwargs): valid_numeric_dtypes = { - "2.1.2 and below": ( + "2.2 and below": ( ivy.int8, ivy.int16, ivy.int32, @@ -163,13 +163,13 @@ def rep_method(*args, **kwargs): } valid_int_dtypes = { - "2.1.2 and below": (ivy.int8, ivy.int16, ivy.int32, ivy.int64, ivy.uint8) + "2.2 and below": (ivy.int8, ivy.int16, ivy.int32, ivy.int64, ivy.uint8) } valid_float_dtypes = { - "2.1.2 and below": (ivy.bfloat16, ivy.float16, ivy.float32, ivy.float64) + "2.2 and below": (ivy.bfloat16, ivy.float16, ivy.float32, ivy.float64) } -valid_uint_dtypes = {"2.1.2 and below": (ivy.uint8,)} -valid_complex_dtypes = {"2.1.2 and below": (ivy.complex64, ivy.complex128)} +valid_uint_dtypes = {"2.2 and below": (ivy.uint8,)} +valid_complex_dtypes = {"2.2 and below": (ivy.complex64, ivy.complex128)} # leave these untouched valid_dtypes = _dtype_from_version(valid_dtypes, backend_version) @@ -182,17 +182,17 @@ def rep_method(*args, **kwargs): # invalid data types # update these to add new dtypes invalid_dtypes = { - "2.1.2 and below": ( + "2.2 and below": ( ivy.uint16, ivy.uint32, ivy.uint64, ) } -invalid_numeric_dtypes = {"2.1.2 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} -invalid_int_dtypes = {"2.1.2 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} -invalid_float_dtypes = {"2.1.2 and below": ()} -invalid_uint_dtypes = {"2.1.2 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} -invalid_complex_dtypes = {"2.1.2 and below": ()} +invalid_numeric_dtypes = {"2.2 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} +invalid_int_dtypes = {"2.2 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} +invalid_float_dtypes = {"2.2 and below": ()} +invalid_uint_dtypes = {"2.2 and below": (ivy.uint16, ivy.uint32, ivy.uint64)} +invalid_complex_dtypes = {"2.2 and below": ()} invalid_dtypes = _dtype_from_version(invalid_dtypes, backend_version) # leave these untouched @@ -270,8 +270,13 @@ def globals_getter_func(x=None): from .control_flow_ops import * from . import norms from .norms import * +from . import module +from .module import * # sub-backends from . import sub_backends from .sub_backends import * + + +NativeModule = torch.nn.Module diff --git a/ivy/functional/backends/torch/activations.py b/ivy/functional/backends/torch/activations.py index e341d123ec230..2529147c6f976 100644 --- a/ivy/functional/backends/torch/activations.py +++ b/ivy/functional/backends/torch/activations.py @@ -18,14 +18,22 @@ import ivy.functional.backends.torch as torch_backend -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes( + { + "2.1.2 and below": ( + "float16", + "bool", + ) + }, + backend_version, +) def relu( x: torch.Tensor, /, *, complex_mode="jax", out: Optional[torch.Tensor] = None ) -> torch.Tensor: return torch.relu(x) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def leaky_relu( x: torch.Tensor, /, @@ -37,7 +45,7 @@ def leaky_relu( return torch.nn.functional.leaky_relu(x, alpha) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def gelu( x: torch.Tensor, /, @@ -51,7 +59,7 @@ def gelu( return torch.nn.functional.gelu(x) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def sigmoid( x: torch.Tensor, /, *, complex_mode="jax", out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -63,7 +71,7 @@ def sigmoid( sigmoid.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def softmax( x: torch.Tensor, /, @@ -80,7 +88,7 @@ def softmax( return torch.nn.functional.softmax(x, axis) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def softplus( x: torch.Tensor, /, @@ -97,7 +105,7 @@ def softplus( # Softsign -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def softsign(x: torch.Tensor, /, out: Optional[torch.Tensor] = None) -> torch.Tensor: # return x / (1 + torch.abs(x)) return torch.nn.functional.softsign(x) @@ -107,7 +115,7 @@ def softsign(x: torch.Tensor, /, out: Optional[torch.Tensor] = None) -> torch.Te @with_unsupported_dtypes( - {"2.1.2 and below": ("float16",)}, + {"2.2 and below": ("float16",)}, backend_version, ) def log_softmax( @@ -128,7 +136,7 @@ def log_softmax( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16",)}, + {"2.2 and below": ("float16",)}, backend_version, ) def mish( @@ -146,7 +154,7 @@ def mish( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "complex", "float16", ) diff --git a/ivy/functional/backends/torch/control_flow_ops.py b/ivy/functional/backends/torch/control_flow_ops.py index d3a7f92c58d02..d114e59c2146d 100644 --- a/ivy/functional/backends/torch/control_flow_ops.py +++ b/ivy/functional/backends/torch/control_flow_ops.py @@ -17,8 +17,11 @@ def cond(*_): def while_loop(test_fn, body_fn, vars): - result = list(vars.values()) - while test_fn(*result): + if isinstance(vars, dict): + result = list(vars.values()) + else: + result = list(vars) + while test_fn(*result) is True: result = body_fn(*result) if not isinstance(result, tuple): result = (result,) diff --git a/ivy/functional/backends/torch/creation.py b/ivy/functional/backends/torch/creation.py index 4674ddbd17399..ab6351d5054f7 100644 --- a/ivy/functional/backends/torch/creation.py +++ b/ivy/functional/backends/torch/creation.py @@ -47,7 +47,7 @@ def _differentiable_linspace(start, stop, num, *, device, dtype=None): return res -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def arange( start: float, /, @@ -95,7 +95,7 @@ def _stack_tensors(x, dtype): return x -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, backend_version) @_asarray_to_native_arrays_and_back @_asarray_infer_device @_asarray_handle_nestable @@ -166,7 +166,7 @@ def empty_like( return torch.empty_like(x, dtype=dtype, device=device) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, backend_version) def eye( n_rows: int, n_cols: Optional[int] = None, @@ -276,7 +276,7 @@ def _slice_at_axis(sl, axis): @with_unsupported_device_and_dtypes( - {"2.1.2 and below": {"cpu": ("float16",)}}, backend_version + {"2.2 and below": {"cpu": ("float16",)}}, backend_version ) def linspace( start: Union[torch.Tensor, float], diff --git a/ivy/functional/backends/torch/data_type.py b/ivy/functional/backends/torch/data_type.py index 05faab29b6c2e..76db94f8a1ae4 100644 --- a/ivy/functional/backends/torch/data_type.py +++ b/ivy/functional/backends/torch/data_type.py @@ -72,6 +72,7 @@ def smallest_normal(self): # -------------------# +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def astype( x: torch.Tensor, dtype: torch.dtype, @@ -90,7 +91,7 @@ def broadcast_arrays(*arrays: torch.Tensor) -> List[torch.Tensor]: try: return list(torch.broadcast_tensors(*arrays)) except RuntimeError as e: - raise ivy.utils.exceptions.IvyBroadcastShapeError(e) + raise ivy.utils.exceptions.IvyBroadcastShapeError(e) from e def broadcast_to( @@ -180,9 +181,9 @@ def as_ivy_dtype( ) -@with_unsupported_dtypes({"2.1.2 and below": ("uint16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("uint16",)}, backend_version) def as_native_dtype( - dtype_in: Union[torch.dtype, str, bool, int, float, np.dtype] + dtype_in: Union[torch.dtype, str, bool, int, float, np.dtype], ) -> torch.dtype: if dtype_in is int: return ivy.default_int_dtype(as_native=True) diff --git a/ivy/functional/backends/torch/elementwise.py b/ivy/functional/backends/torch/elementwise.py index fd95b2089f6a3..b12773813fdea 100644 --- a/ivy/functional/backends/torch/elementwise.py +++ b/ivy/functional/backends/torch/elementwise.py @@ -38,7 +38,7 @@ def add( add.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def bitwise_xor( x1: Union[int, bool, torch.Tensor], @@ -54,7 +54,7 @@ def bitwise_xor( bitwise_xor.support_native_out = True -@with_supported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_supported_dtypes({"2.2 and below": ("complex",)}, backend_version) def imag( val: torch.Tensor, /, @@ -67,7 +67,7 @@ def imag( imag.support_native_out = False -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def expm1(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -77,7 +77,7 @@ def expm1(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Te expm1.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def bitwise_invert( x: Union[int, bool, torch.Tensor], /, *, out: Optional[torch.Tensor] = None @@ -95,6 +95,7 @@ def isfinite(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch return torch.isfinite(x) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def isinf( x: torch.Tensor, @@ -129,7 +130,7 @@ def equal( equal.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def less_equal( x1: Union[float, torch.Tensor], @@ -145,7 +146,7 @@ def less_equal( less_equal.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def bitwise_and( x1: Union[int, bool, torch.Tensor], @@ -161,7 +162,7 @@ def bitwise_and( bitwise_and.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def ceil(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -175,7 +176,7 @@ def ceil(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Ten ceil.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def floor(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -189,7 +190,7 @@ def floor(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Te floor.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def fmin( x1: torch.Tensor, x2: torch.Tensor, @@ -203,7 +204,7 @@ def fmin( fmin.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def asin(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -213,7 +214,7 @@ def asin(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Ten asin.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def asinh(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -223,7 +224,7 @@ def asinh(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Te asinh.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def sign( x: torch.Tensor, @@ -245,7 +246,7 @@ def sign( sign.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def sqrt(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -255,7 +256,7 @@ def sqrt(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Ten sqrt.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def cosh(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -265,7 +266,7 @@ def cosh(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Ten cosh.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def log10(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -275,14 +276,14 @@ def log10(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Te log10.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def log2(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) return torch.log2(x, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def log1p(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -298,7 +299,7 @@ def isnan(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Te return torch.isnan(x) -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def less( x1: Union[float, torch.Tensor], @@ -329,7 +330,7 @@ def multiply( multiply.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def cos(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -370,7 +371,7 @@ def divide( divide.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def greater( x1: Union[float, torch.Tensor], @@ -386,7 +387,7 @@ def greater( greater.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def greater_equal( x1: Union[float, torch.Tensor], @@ -402,7 +403,7 @@ def greater_equal( greater_equal.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def acos(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -412,7 +413,7 @@ def acos(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Ten acos.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float",)}, backend_version) @handle_numpy_arrays_in_specific_backend def lcm( x1: torch.Tensor, @@ -458,7 +459,7 @@ def logical_or( logical_or.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def acosh(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -468,7 +469,7 @@ def acosh(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Te acosh.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def sin(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -504,7 +505,7 @@ def not_equal( not_equal.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def tanh( x: torch.Tensor, /, *, complex_mode="jax", out: Optional[torch.Tensor] = None @@ -516,7 +517,7 @@ def tanh( tanh.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def floor_divide( x1: Union[float, torch.Tensor], @@ -537,7 +538,7 @@ def floor_divide( floor_divide.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def bitwise_or( x1: Union[int, bool, torch.Tensor], @@ -553,7 +554,7 @@ def bitwise_or( bitwise_or.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def sinh(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -618,7 +619,7 @@ def pow( pow.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def round( x: torch.Tensor, /, *, decimals: int = 0, out: Optional[torch.Tensor] = None @@ -659,7 +660,7 @@ def trapz( trapz.support_native_out = False -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def trunc(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -692,7 +693,7 @@ def abs( abs.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def logaddexp( x1: torch.Tensor, x2: torch.Tensor, /, *, out: Optional[torch.Tensor] = None @@ -704,7 +705,7 @@ def logaddexp( logaddexp.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def logaddexp2( x1: Union[torch.Tensor, float, list, tuple], @@ -723,7 +724,7 @@ def logaddexp2( logaddexp2.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) @handle_numpy_arrays_in_specific_backend def tan(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -733,7 +734,7 @@ def tan(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tens tan.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def atan(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -744,7 +745,7 @@ def atan(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Ten @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, backend_version + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version ) # TODO Fixed in PyTorch 1.12.1 (this note excludes complex) @handle_numpy_arrays_in_specific_backend def atan2( @@ -757,7 +758,7 @@ def atan2( atan2.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def log(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -767,7 +768,7 @@ def log(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tens log.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def exp(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -808,7 +809,7 @@ def subtract( subtract.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def remainder( x1: Union[float, torch.Tensor], @@ -836,7 +837,7 @@ def remainder( remainder.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def atanh(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -846,7 +847,7 @@ def atanh(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Te atanh.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def bitwise_right_shift( x1: Union[int, bool, torch.Tensor], @@ -863,7 +864,7 @@ def bitwise_right_shift( bitwise_right_shift.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def bitwise_left_shift( x1: Union[int, bool, torch.Tensor], @@ -883,7 +884,7 @@ def bitwise_left_shift( # ------# -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) @handle_numpy_arrays_in_specific_backend def erf(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) @@ -893,7 +894,7 @@ def erf(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tens erf.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def minimum( x1: Union[float, torch.Tensor], @@ -912,7 +913,7 @@ def minimum( minimum.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def maximum( x1: Union[float, torch.Tensor], @@ -931,7 +932,7 @@ def maximum( maximum.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) @handle_numpy_arrays_in_specific_backend def reciprocal( x: Union[float, torch.Tensor], /, *, out: Optional[torch.Tensor] = None @@ -944,7 +945,7 @@ def reciprocal( @with_unsupported_dtypes( - {"2.1.2 and below": ("complex64", "complex128")}, backend_version + {"2.2 and below": ("complex64", "complex128")}, backend_version ) @handle_numpy_arrays_in_specific_backend def deg2rad(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: @@ -955,7 +956,7 @@ def deg2rad(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch. @with_unsupported_dtypes( - {"2.1.2 and below": ("complex64", "complex128")}, backend_version + {"2.2 and below": ("complex64", "complex128")}, backend_version ) @handle_numpy_arrays_in_specific_backend def rad2deg(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: @@ -965,7 +966,7 @@ def rad2deg(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch. rad2deg.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) @handle_numpy_arrays_in_specific_backend def trunc_divide( x1: Union[float, torch.Tensor], @@ -989,7 +990,7 @@ def isreal(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.T @with_unsupported_dtypes( - {"2.1.2 and below": ("bfloat16", "complex")}, + {"2.2 and below": ("bfloat16", "complex")}, backend_version, ) @handle_numpy_arrays_in_specific_backend diff --git a/ivy/functional/backends/torch/experimental/activations.py b/ivy/functional/backends/torch/experimental/activations.py index 230e429e4bc98..8af005a250047 100644 --- a/ivy/functional/backends/torch/experimental/activations.py +++ b/ivy/functional/backends/torch/experimental/activations.py @@ -10,7 +10,7 @@ from . import backend_version -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def logit( x: torch.Tensor, /, @@ -22,7 +22,7 @@ def logit( return torch.logit(x, eps=eps, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("complex", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex", "float16")}, backend_version) def thresholded_relu( x: torch.Tensor, /, @@ -33,14 +33,14 @@ def thresholded_relu( return torch.threshold(x, threshold=threshold, value=0) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def relu6( x: torch.Tensor, /, *, complex_mode="jax", out: Optional[torch.Tensor] = None ) -> torch.Tensor: return torch.nn.functional.relu6(x) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def logsigmoid( input: torch.Tensor, /, *, complex_mode="jax", out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -49,7 +49,7 @@ def logsigmoid( return torch.nn.functional.logsigmoid(input) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def selu(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: ret = torch.nn.functional.selu(x) if ivy.exists(out): @@ -57,12 +57,12 @@ def selu(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Ten return ivy.astype(ret, x.dtype) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def silu(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: return torch.nn.functional.silu(x) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def elu( x: torch.Tensor, /, *, alpha: float = 1.0, out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -74,7 +74,7 @@ def elu( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "complex", "float16", "bfloat16", @@ -93,7 +93,7 @@ def celu( return torch.celu(x, alpha=alpha) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def hardtanh( x: torch.Tensor, /, @@ -108,7 +108,7 @@ def hardtanh( return ivy.astype(ret, x.dtype) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def tanhshrink( x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -118,7 +118,7 @@ def tanhshrink( return ivy.astype(ret, x.dtype) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def threshold( x: torch.Tensor, /, @@ -133,7 +133,7 @@ def threshold( return ivy.astype(ret, x.dtype) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def softshrink( x: torch.Tensor, /, *, lambd: float = 0.5, out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -154,7 +154,7 @@ def scaled_tanh( return alpha * torch.nn.functional.tanh(beta * x) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def hardshrink( x: torch.Tensor, /, *, lambd: float = 0.5, out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -162,3 +162,11 @@ def hardshrink( if ivy.exists(out): return ivy.inplace_update(out, ret).astype(x.dtype) return ivy.astype(ret, x.dtype) + + +@with_unsupported_dtypes({"2.0.1 and below": ("complex", "float16")}, backend_version) +def hardsilu(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: + ret = torch.nn.functional.hardswish(x) + if ivy.exists(out): + return ivy.inplace_update(out, ret).astype(x.dtype) + return ivy.astype(ret, x.dtype) diff --git a/ivy/functional/backends/torch/experimental/creation.py b/ivy/functional/backends/torch/experimental/creation.py index 2c332f82d06ea..546cde45eac66 100644 --- a/ivy/functional/backends/torch/experimental/creation.py +++ b/ivy/functional/backends/torch/experimental/creation.py @@ -20,7 +20,7 @@ @with_unsupported_device_and_dtypes( - {"2.1.2 and below": {"cpu": ("float16",)}}, + {"2.2 and below": {"cpu": ("float16",)}}, backend_version, ) def kaiser_window( @@ -87,7 +87,7 @@ def vorbis_window( vorbis_window.support_native_out = False -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def hann_window( size: int, /, @@ -152,7 +152,7 @@ def unsorted_segment_min( return res -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def blackman_window( size: int, /, diff --git a/ivy/functional/backends/torch/experimental/elementwise.py b/ivy/functional/backends/torch/experimental/elementwise.py index faa58bff5650f..db54833224dd5 100644 --- a/ivy/functional/backends/torch/experimental/elementwise.py +++ b/ivy/functional/backends/torch/experimental/elementwise.py @@ -16,7 +16,7 @@ @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "complex64", "complex128", ) @@ -40,7 +40,7 @@ def amax( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "complex64", "complex128", ) @@ -62,12 +62,12 @@ def amin( amin.support_native_out = True -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, backend_version) def lgamma(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: return torch.lgamma(x, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def fmax( x1: torch.Tensor, x2: torch.Tensor, @@ -82,7 +82,7 @@ def fmax( fmax.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def sinc(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: x = _cast_for_unary_op(x) return torch.sinc(x, out=out) @@ -158,7 +158,7 @@ def count_nonzero( count_nonzero.support_native_out = False -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def nansum( x: torch.Tensor, /, @@ -227,7 +227,7 @@ def signbit( signbit.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def hypot( x1: torch.Tensor, x2: torch.Tensor, @@ -252,7 +252,7 @@ def allclose( return torch.tensor(ret) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def fix( x: torch.Tensor, /, @@ -265,7 +265,7 @@ def fix( fix.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def nextafter( x1: torch.Tensor, x2: torch.Tensor, @@ -319,7 +319,7 @@ def gradient( @with_supported_dtypes( - {"2.1.2 and below": ("float16", "float32", "float64")}, + {"2.2 and below": ("float16", "float32", "float64")}, backend_version, ) def xlogy( @@ -382,7 +382,7 @@ def _are_suitable_types_for_torch_lerp(input, end, weight): return True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def lerp( input: torch.Tensor, end: torch.Tensor, @@ -415,12 +415,13 @@ def modf( /, *, out: Optional[torch.Tensor] = None, -) -> torch.Tensor: - modf_x = torch.modf(x) - return torch.resolve_modf(input=modf_x) +) -> Tuple[torch.Tensor, torch.Tensor]: + fractional_part = torch.frac(x) + integer_part = torch.floor(x) + return fractional_part, integer_part -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def digamma( x: torch.Tensor, /, @@ -433,7 +434,7 @@ def digamma( digamma.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def erfc( x: torch.Tensor, /, @@ -441,3 +442,16 @@ def erfc( out: Optional[torch.Tensor] = None, ) -> torch.Tensor: return torch.special.erfc(x) + + +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) +def erfinv( + x: torch.Tensor, + /, + *, + out: Optional[torch.Tensor] = None, +) -> torch.Tensor: + return torch.special.erfinv(x, out=out) + + +erfinv.support_native_out = True diff --git a/ivy/functional/backends/torch/experimental/gradients.py b/ivy/functional/backends/torch/experimental/gradients.py index a959d5ab83e03..b6c0a7cedf6e4 100644 --- a/ivy/functional/backends/torch/experimental/gradients.py +++ b/ivy/functional/backends/torch/experimental/gradients.py @@ -34,10 +34,12 @@ def backward(ctx, upstream): def vjp(func: Callable, *primals): flattened_primals, ret_idxs = _flatten_containers(primals) - unique_keys = list({ - ivy.index_nest(ret_idxs, i) - for i in ivy.nested_argwhere(ret_idxs, lambda x: isinstance(x, str)) - }) + unique_keys = list( + { + ivy.index_nest(ret_idxs, i) + for i in ivy.nested_argwhere(ret_idxs, lambda x: isinstance(x, str)) + } + ) def grad_fn(*x_in): ret, idxs = _flatten_containers( @@ -93,10 +95,12 @@ def vjpfun(*x_in): def jvp(func: Callable, primals, tangents): flattened_primals, ret_idxs = _flatten_containers(primals) flattened_tangents, _ = _flatten_containers(tangents) - unique_keys = list({ - ivy.index_nest(ret_idxs, i) - for i in ivy.nested_argwhere(ret_idxs, lambda x: isinstance(x, str)) - }) + unique_keys = list( + { + ivy.index_nest(ret_idxs, i) + for i in ivy.nested_argwhere(ret_idxs, lambda x: isinstance(x, str)) + } + ) def grad_fn(*x_in): ret, idxs = _flatten_containers( diff --git a/ivy/functional/backends/torch/experimental/layers.py b/ivy/functional/backends/torch/experimental/layers.py index c2a6a3f501794..1c53639d23409 100644 --- a/ivy/functional/backends/torch/experimental/layers.py +++ b/ivy/functional/backends/torch/experimental/layers.py @@ -29,7 +29,7 @@ def _determine_depth_max_pooling(x, kernel, strides, dims, data_format="channel_ return x, kernel, strides, depth_pooling -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def max_pool1d( x: torch.Tensor, kernel: Union[int, Tuple[int, ...]], @@ -94,7 +94,7 @@ def max_pool1d( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -170,7 +170,7 @@ def max_pool2d( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -282,7 +282,7 @@ def _get_specific_pad(x_shape, kernel, strides, padding, dims): return padding, pad_specific -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def avg_pool1d( x: torch.Tensor, kernel: Union[int, Tuple[int]], @@ -374,7 +374,7 @@ def _adjust_num_padded_values_to_ceil( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -478,7 +478,7 @@ def avg_pool2d( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -581,7 +581,7 @@ def avg_pool3d( return res -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, backend_version) def dct( x: torch.Tensor, /, @@ -694,7 +694,7 @@ def idct( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -740,7 +740,7 @@ def fft( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", "complex", @@ -774,7 +774,7 @@ def dropout( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16",)}, + {"2.2 and below": ("float16",)}, backend_version, ) def dropout1d( @@ -797,7 +797,7 @@ def dropout1d( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16",)}, + {"2.2 and below": ("float16",)}, backend_version, ) def dropout2d( @@ -822,7 +822,7 @@ def dropout2d( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -881,7 +881,7 @@ def ifft( return torch.fft.ifft(x, n, dim, norm, out=out).resolve_conj() -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def embedding( weights: torch.Tensor, indices: torch.Tensor, @@ -954,19 +954,26 @@ def interpolate( ) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def adaptive_max_pool2d( input: torch.Tensor, output_size: Union[Sequence[int], int] ) -> torch.Tensor: return torch.nn.functional.adaptive_max_pool2d(input, output_size) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) +def adaptive_max_pool3d( + input: torch.Tensor, output_size: Union[Sequence[int], int] +) -> torch.Tensor: + return torch.nn.functional.adaptive_max_pool3d(input, output_size) + + +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def adaptive_avg_pool1d(input, output_size): return torch.nn.functional.adaptive_avg_pool1d(input, output_size) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def adaptive_avg_pool2d(input, output_size, /, *, data_format: str = "NHWC"): squeeze = False if input.ndim == 3: @@ -982,7 +989,7 @@ def adaptive_avg_pool2d(input, output_size, /, *, data_format: str = "NHWC"): return ret -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def fft2( x: torch.Tensor, *, @@ -1048,7 +1055,7 @@ def rfft( return ret -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def rfftn( x: torch.Tensor, s: Optional[Sequence[int]] = None, @@ -1086,7 +1093,7 @@ def rfftn( # stft @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) diff --git a/ivy/functional/backends/torch/experimental/linear_algebra.py b/ivy/functional/backends/torch/experimental/linear_algebra.py index e73e9f297d7c1..5c7dc1492571b 100644 --- a/ivy/functional/backends/torch/experimental/linear_algebra.py +++ b/ivy/functional/backends/torch/experimental/linear_algebra.py @@ -1,18 +1,17 @@ # global import math - +from collections import namedtuple import torch from typing import Optional, Tuple, Sequence, Union import ivy from ivy.func_wrapper import with_unsupported_dtypes -from ivy.utils.exceptions import IvyNotImplementedException from .. import backend_version from ivy.functional.ivy.experimental.linear_algebra import _check_valid_dimension_size -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def diagflat( x: torch.Tensor, /, @@ -176,7 +175,7 @@ def solve_triangular( solve_triangular.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def multi_dot( x: Sequence[torch.Tensor], /, @@ -203,16 +202,31 @@ def cond( cond.support_native_out = False +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def lu_factor( x: torch.Tensor, /, *, pivot: Optional[bool] = True, out: Optional[torch.Tensor] = None, -) -> Tuple[torch.Tensor]: - raise IvyNotImplementedException() +) -> Tuple[torch.Tensor, torch.Tensor]: + ret = torch.linalg.lu_factor(x, pivot=pivot, out=out) + ret_tuple = namedtuple("lu_factor", ["LU", "p"]) + return ret_tuple(ret.LU, ret.pivots) + + +def lu_solve( + lu: Tuple[torch.Tensor, torch.Tensor], + p: torch.Tensor, + b: torch.Tensor, + /, + *, + out: Optional[torch.Tensor] = None, +) -> torch.Tensor: + return torch.linalg.lu_solve(lu, p, b, out=out) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def dot( a: torch.Tensor, b: torch.Tensor, diff --git a/ivy/functional/backends/torch/experimental/losses.py b/ivy/functional/backends/torch/experimental/losses.py index fbd5a899d964e..aaab1a95d2eb5 100644 --- a/ivy/functional/backends/torch/experimental/losses.py +++ b/ivy/functional/backends/torch/experimental/losses.py @@ -11,7 +11,7 @@ @with_unsupported_dtypes( - {"2.1.2 and below": ("unit8", "int8", "int16", "int32", "int64", "bool")}, + {"2.2 and below": ("unit8", "int8", "int16", "int32", "int64", "bool")}, backend_version, ) def l1_loss( @@ -30,7 +30,7 @@ def l1_loss( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "complex", "uint8", "int8", @@ -59,7 +59,7 @@ def smooth_l1_loss( @with_unsupported_dtypes( - {"2.1.2 and below": ("uint8", "int8", "int16", "int32", "int64", "bool")}, + {"2.2 and below": ("uint8", "int8", "int16", "int32", "int64", "bool")}, backend_version, ) def huber_loss( @@ -77,7 +77,7 @@ def huber_loss( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "uint8", "int8", @@ -104,7 +104,7 @@ def soft_margin_loss( @with_supported_dtypes( - {"2.1.2 and below": ("float",)}, + {"2.2 and below": ("float",)}, backend_version, ) def kl_div( @@ -152,3 +152,24 @@ def poisson_nll_loss( return torch.nn.functional.poisson_nll_loss( input, target, log_input=log_input, full=full, eps=eps, reduction=reduction ) + + +@with_supported_device_and_dtypes( + { + "2.2 and below": { + "cpu": ("float16", "float32", "float64"), + "gpu": ("float16", "float32", "float64"), + } + }, + backend_version, +) +def hinge_embedding_loss( + input: torch.Tensor, + target: torch.Tensor, + *, + margin: float = 1.0, + reduction: str = "mean", +) -> torch.Tensor: + return torch.nn.functional.hinge_embedding_loss( + input, target, margin=margin, reduction=reduction + ) diff --git a/ivy/functional/backends/torch/experimental/manipulation.py b/ivy/functional/backends/torch/experimental/manipulation.py index 14265cebd1eea..c0164e4c067a6 100644 --- a/ivy/functional/backends/torch/experimental/manipulation.py +++ b/ivy/functional/backends/torch/experimental/manipulation.py @@ -17,7 +17,11 @@ # local -from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes +from ivy.func_wrapper import ( + with_unsupported_dtypes, + with_supported_dtypes, + handle_out_argument, +) from .. import backend_version import ivy from ivy.functional.ivy.experimental.manipulation import ( @@ -60,7 +64,7 @@ def heaviside( @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex64", "complex128")}, + {"2.2 and below": ("float32", "float64", "complex64", "complex128")}, backend_version, ) def pad( @@ -238,7 +242,7 @@ def fliplr( fliplr.support_native_out = False -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def i0( x: torch.Tensor, /, @@ -331,7 +335,7 @@ def atleast_3d( return transformed -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def take_along_axis( arr: torch.Tensor, indices: torch.Tensor, @@ -409,7 +413,7 @@ def expand( expand.support_native_out = False -@with_unsupported_dtypes({"2.1.2 and below": ("complex", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex", "float16")}, backend_version) def unique_consecutive( x: torch.Tensor, /, @@ -439,7 +443,7 @@ def column_stack( return torch.column_stack(arrays) -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, backend_version) +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, backend_version) def put_along_axis( arr: torch.Tensor, indices: torch.Tensor, @@ -550,13 +554,13 @@ def take( if ivy.exists(axis): try: x_shape = x.shape[axis] - except Exception: + except Exception as e: rank = len(x.shape) raise IndexError( "IndexError: Dimension out of range" f"(expected to be in range of[-{rank}, {rank-1}]" f", but got {axis})" - ) + ) from e else: x_shape = torch.prod(torch.tensor(x.shape)) @@ -639,3 +643,16 @@ def trim_zeros(a: torch.Tensor, /, *, trim: Optional[str] = "bf") -> torch.Tenso else: last = last - 1 return a[first:last] + + +@handle_out_argument +def unflatten( + x: torch.Tensor, + /, + shape: Tuple[int] = None, + dim: Optional[int] = 0, + *, + out: Optional[torch.Tensor] = None, +) -> torch.Tensor: + res = torch.unflatten(x, dim, shape) + return res diff --git a/ivy/functional/backends/torch/experimental/norms.py b/ivy/functional/backends/torch/experimental/norms.py index f29b0283833c2..e17a2c42a8e62 100644 --- a/ivy/functional/backends/torch/experimental/norms.py +++ b/ivy/functional/backends/torch/experimental/norms.py @@ -18,7 +18,7 @@ def l1_normalize( l1_normalize.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def l2_normalize( x: torch.Tensor, /, @@ -32,7 +32,7 @@ def l2_normalize( l2_normalize.support_native_out = True -@with_supported_dtypes({"2.1.2 and below": ("float",)}, backend_version) +@with_supported_dtypes({"2.2 and below": ("float",)}, backend_version) def local_response_norm( x: torch.Tensor, size, @@ -56,7 +56,7 @@ def local_response_norm( return ret -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def batch_norm( x: torch.Tensor, mean: torch.Tensor, @@ -102,7 +102,7 @@ def batch_norm( ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def instance_norm( x: torch.Tensor, mean: torch.Tensor, @@ -150,7 +150,7 @@ def instance_norm( ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def group_norm( x: torch.Tensor, num_groups: int = 1, @@ -175,7 +175,7 @@ def group_norm( return xnormalized -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def lp_normalize( x: torch.Tensor, /, diff --git a/ivy/functional/backends/torch/experimental/random.py b/ivy/functional/backends/torch/experimental/random.py index a4d5b116b0782..2226b4b75ff7a 100644 --- a/ivy/functional/backends/torch/experimental/random.py +++ b/ivy/functional/backends/torch/experimental/random.py @@ -13,7 +13,7 @@ # dirichlet -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def dirichlet( alpha: Union[torch.tensor, float, Sequence[float]], /, @@ -32,7 +32,7 @@ def dirichlet( ) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, backend_version) def beta( alpha: Union[float, torch.Tensor], beta: Union[float, torch.Tensor], @@ -53,7 +53,7 @@ def beta( return ret -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, backend_version) def gamma( alpha: Union[float, torch.Tensor], beta: Union[float, torch.Tensor], @@ -116,16 +116,14 @@ def bernoulli( seed: Optional[int] = None, out: Optional[torch.Tensor] = None, ) -> torch.Tensor: + dtype = dtype if dtype is not None else probs.dtype if seed: torch.manual_seed(seed) if logits is not None: - if not _check_shapes_broadcastable(shape, logits.shape): - shape = logits.shape - elif probs is not None: - if not _check_shapes_broadcastable(shape, probs.shape): - shape = probs.shape - return ( - torch.distributions.bernoulli.Bernoulli(probs=probs, logits=logits) - .sample(shape) - .to(device, dtype) - ) + probs = torch.nn.functional.softmax(logits, -1) + if not _check_shapes_broadcastable(shape, probs.shape): + shape = probs.shape + return torch.bernoulli(probs, out=out).to(device, dtype).broadcast_to(shape) + + +bernoulli.support_native_out = True diff --git a/ivy/functional/backends/torch/experimental/sorting.py b/ivy/functional/backends/torch/experimental/sorting.py index e37526f3fb7d1..609eb6b69d3bf 100644 --- a/ivy/functional/backends/torch/experimental/sorting.py +++ b/ivy/functional/backends/torch/experimental/sorting.py @@ -33,7 +33,7 @@ def lexsort( return torch.tensor([0]) _, result = torch.sort(keys[0], dim=axis, stable=True) # result = torch.argsort(keys[0], dim=axis, stable=True) - # only valid for torch > 2.1.2 + # only valid for torch > 2.2 if shape[0] == 1: return result for i in range(1, shape[0]): @@ -41,7 +41,7 @@ def lexsort( ind = key[result] _, temp = torch.sort(ind, dim=axis, stable=True) # temp = torch.argsort(ind, dim=axis, stable=True) - # only valid for torch > 2.1.2 + # only valid for torch > 2.2 result = result[temp] return result diff --git a/ivy/functional/backends/torch/experimental/statistical.py b/ivy/functional/backends/torch/experimental/statistical.py index efad6240c1400..d5aa9e44c085a 100644 --- a/ivy/functional/backends/torch/experimental/statistical.py +++ b/ivy/functional/backends/torch/experimental/statistical.py @@ -3,7 +3,7 @@ import torch # local -from ivy.func_wrapper import with_unsupported_dtypes +from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes from . import backend_version import ivy from ..statistical import _infer_dtype @@ -12,7 +12,7 @@ @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "uint8", "int8", "int16", @@ -139,7 +139,7 @@ def histogram( histogram.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bool")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bool")}, backend_version) def median( input: torch.Tensor, /, @@ -170,6 +170,7 @@ def median( median.support_native_out = False +@with_supported_dtypes({"2.2 and below": ("float",)}, backend_version) def nanmean( a: torch.Tensor, /, @@ -291,10 +292,12 @@ def _handle_axis(a, q, fn, keepdims=False, axis=None): for i, s in enumerate(sorted(keep)): a = torch.moveaxis(a, s, i) - a = a.view([ - *a.shape[:nkeep], - -1, - ]) + a = a.view( + [ + *a.shape[:nkeep], + -1, + ] + ) axis_arg = -1 ret = fn(a, q, axis=axis_arg) @@ -364,7 +367,7 @@ def _compute_quantile_wrapper( ) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def quantile( a: torch.Tensor, q: Union[torch.Tensor, float], @@ -445,7 +448,7 @@ def _nanmedian(input, axis, keepdims): return ret -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def nanmedian( input: torch.Tensor, /, @@ -533,7 +536,7 @@ def igamma( igamma.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def cov( x1: torch.Tensor, x2: torch.Tensor = None, @@ -590,7 +593,7 @@ def cov( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "complex")}, + {"2.2 and below": ("float16", "complex")}, backend_version, ) def cummax( @@ -627,7 +630,7 @@ def cummax( @with_unsupported_dtypes( { - "2.1.2 and below": ("uint8", "float16", "bfloat16"), + "2.2 and below": ("uint8", "float16", "bfloat16"), "1.12.1 and above": ("uint8", "float16"), }, backend_version, diff --git a/ivy/functional/backends/torch/general.py b/ivy/functional/backends/torch/general.py index 2fb22fc355458..ea02caf0707f3 100644 --- a/ivy/functional/backends/torch/general.py +++ b/ivy/functional/backends/torch/general.py @@ -54,7 +54,7 @@ def is_native_array(x, /, *, exclusive=False): return False -@with_unsupported_dtypes({"2.1.2 and below": ("complex", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex", "bfloat16")}, backend_version) def array_equal(x0: torch.Tensor, x1: torch.Tensor, /) -> bool: x0, x1 = ivy.promote_types_of_inputs(x0, x1) return torch.equal(x0, x1) @@ -354,7 +354,7 @@ def multiprocessing(context: Optional[str] = None): @with_unsupported_dtypes( { - "2.1.2 and below": ("bfloat16",), + "2.2 and below": ("bfloat16",), }, backend_version, ) @@ -387,10 +387,10 @@ def scatter_flat( if torch_scatter is None: try: import torch_scatter as torch_scatter - except ImportError: + except ImportError as e: raise ivy.utils.exceptions.IvyException( "Unable to import torch_scatter, verify this is correctly installed." - ) + ) from e if reduction == "replace": output[indices.type(torch.int64)] = updates res = output @@ -406,7 +406,7 @@ def scatter_flat( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -478,10 +478,10 @@ def scatter_nd( if torch_scatter is None: try: import torch_scatter as torch_scatter - except ImportError: + except ImportError as e: raise ivy.utils.exceptions.IvyException( "Unable to import torch_scatter, verify this is correctly installed." - ) + ) from e if reduction == "replace": flat_output[flat_indices_for_flat] = flat_updates flat_scatter = flat_output @@ -513,7 +513,7 @@ def shape( return ivy.Shape(x.shape) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, backend_version) def vmap_v_1p13p1_and_below( func: Callable, in_axes: Union[int, Sequence[int], Sequence[None]] = 0, @@ -531,7 +531,7 @@ def new_fun(*args): return _vmap -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, backend_version) def vmap_v_2p0p0_and_above( func: Callable, in_axes: Union[int, Sequence[int], Sequence[None]] = 0, @@ -550,7 +550,7 @@ def new_fun(*args): @with_unsupported_dtypes( - {"2.1.2 and below": ("bfloat16", "float16", "complex", "bool")}, backend_version + {"2.2 and below": ("bfloat16", "float16", "complex", "bool")}, backend_version ) def isin( elements: torch.tensor, diff --git a/ivy/functional/backends/torch/layers.py b/ivy/functional/backends/torch/layers.py index 2a7640b33db3f..c470384987513 100644 --- a/ivy/functional/backends/torch/layers.py +++ b/ivy/functional/backends/torch/layers.py @@ -14,7 +14,7 @@ @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex")}, + {"2.2 and below": ("float32", "float64", "complex")}, backend_version, ) def multi_head_attention( @@ -117,7 +117,7 @@ def multi_head_attention( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version, ) def linear( @@ -254,7 +254,7 @@ def _tranpose_padding( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version, ) # noinspection PyUnresolvedReferences @@ -287,7 +287,7 @@ def conv1d( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version, ) def conv1d_v_1p9p0_and_above( @@ -325,7 +325,7 @@ def conv1d_v_1p9p0_and_above( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", "complex", @@ -379,7 +379,7 @@ def conv1d_transpose( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version, ) # noinspection PyUnresolvedReferences @@ -412,7 +412,7 @@ def conv2d( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version, ) def conv2d_v_1p9p0_and_above( @@ -450,7 +450,7 @@ def conv2d_v_1p9p0_and_above( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", "complex", @@ -507,7 +507,7 @@ def conv2d_transpose( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", "complex", @@ -548,7 +548,7 @@ def depthwise_conv2d( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, backend_version + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version ) # noinspection PyUnresolvedReferences def conv3d( @@ -580,7 +580,7 @@ def conv3d( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, backend_version + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version ) def conv3d_v_1p9p0_and_above( x: torch.Tensor, @@ -616,7 +616,7 @@ def conv3d_v_1p9p0_and_above( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version, ) # noinspection PyUnresolvedReferences @@ -669,7 +669,7 @@ def conv3d_transpose( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version, ) def conv_general_dilated( @@ -718,7 +718,7 @@ def conv_general_dilated( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version, ) def conv_general_dilated_v_1p9p0_and_above( @@ -772,7 +772,7 @@ def conv_general_dilated_v_1p9p0_and_above( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "complex")}, backend_version, ) def conv_general_transpose( @@ -868,3 +868,58 @@ def scaled_dot_product_attention_v_2p0p0_and_above( if isinstance(mask, torch.Tensor): mask = torch.where(mask == 0, -torch.inf, 0) return torch.nn.functional.scaled_dot_product_attention(q, k, v, attn_mask=mask) + + +def lstm( + input: torch.Tensor, + initial_states: Tuple[torch.Tensor], + all_weights: Tuple[torch.Tensor], + num_layers: int, + dropout: float, + train: bool, + bidirectional: bool, + batch_first: bool = False, + batch_sizes: Sequence = None, + weights_transposed: bool = False, + has_ih_bias: bool = True, + has_hh_bias: bool = True, +): + if weights_transposed: + # transpose the weights if they are in the wrong format + all_weights = [ + torch.transpose(weight, 1, 0).contiguous() if weight.dim() == 2 else weight + for weight in all_weights + ] + else: + all_weights = list(all_weights) + + if (has_ih_bias and not has_hh_bias) or (has_hh_bias and not has_ih_bias): + # insert zero biases into the weights where one set of biases is not + # used, to avoid stride errors in lstm + shapes = [] + for i in range(2, len(all_weights), 3): + shapes.append(tuple(all_weights[i].shape)) + for i, shape in enumerate(shapes): + idx = (i + 1) * 4 - (1 if has_ih_bias else 2) + all_weights.insert(idx, torch.zeros(shape)) + has_ih_bias = True + has_hh_bias = True + + if initial_states[0].dim() == 2: + initial_states[0] = ivy.expand_dims(initial_states[0]) + if initial_states[1].dim() == 2: + initial_states[1] = ivy.expand_dims(initial_states[1]) + + ret = torch.lstm( + input, + initial_states, + all_weights, + has_ih_bias, + num_layers, + dropout, + train, + bidirectional, + batch_first, + ) + + return ret[0][:, -1], ret[0], (ret[1], ret[2]) diff --git a/ivy/functional/backends/torch/linear_algebra.py b/ivy/functional/backends/torch/linear_algebra.py index 59302f23b3468..39a2d1919838e 100644 --- a/ivy/functional/backends/torch/linear_algebra.py +++ b/ivy/functional/backends/torch/linear_algebra.py @@ -18,7 +18,7 @@ @with_unsupported_dtypes( - {"2.1.2 and below": ("bfloat16", "float16", "complex")}, + {"2.2 and below": ("bfloat16", "float16", "complex")}, backend_version, ) def cholesky( @@ -42,7 +42,7 @@ def cholesky( cholesky.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, backend_version) def cross( x1: torch.Tensor, x2: torch.Tensor, @@ -70,7 +70,7 @@ def cross( cross.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def det(x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None) -> torch.Tensor: return torch.linalg.det(x, out=out) @@ -90,7 +90,7 @@ def diagonal( return torch.diagonal(x, offset=offset, dim1=axis1, dim2=axis2) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def eigh( x: torch.Tensor, /, *, UPLO: str = "L", out: Optional[torch.Tensor] = None ) -> Tuple[torch.Tensor]: @@ -104,7 +104,7 @@ def eigh( eigh.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def eigvalsh( x: torch.Tensor, /, *, UPLO: str = "L", out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -114,7 +114,7 @@ def eigvalsh( eigvalsh.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, backend_version) def inner( x1: torch.Tensor, x2: torch.Tensor, /, *, out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -134,7 +134,7 @@ def inner( inner.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def inv( x: torch.Tensor, /, @@ -160,7 +160,7 @@ def inv( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "bool")}, backend_version + {"2.2 and below": ("float16", "bfloat16", "bool")}, backend_version ) def matmul( x1: torch.Tensor, @@ -193,7 +193,7 @@ def matmul( matmul.support_native_out = True -@with_supported_dtypes({"2.1.2 and below": ("float", "complex")}, backend_version) +@with_supported_dtypes({"2.2 and below": ("float", "complex")}, backend_version) def matrix_norm( x: torch.Tensor, /, @@ -201,15 +201,19 @@ def matrix_norm( ord: Union[int, float, Literal[inf, -inf, "fro", "nuc"]] = "fro", axis: Tuple[int, int] = (-2, -1), keepdims: bool = False, + dtype: Optional[torch.dtype] = None, out: Optional[torch.Tensor] = None, ) -> torch.Tensor: - return torch.linalg.matrix_norm(x, ord=ord, dim=axis, keepdim=keepdims, out=out) + ret = torch.linalg.matrix_norm( + x, ord=ord, dim=axis, keepdim=keepdims, dtype=dtype, out=out + ) + return ret matrix_norm.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def eig( x: torch.Tensor, /, *, out: Optional[torch.Tensor] = None ) -> Tuple[torch.Tensor]: @@ -223,7 +227,7 @@ def eig( eig.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def matrix_power( x: torch.Tensor, n: int, /, *, out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -233,7 +237,7 @@ def matrix_power( matrix_power.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def matrix_rank( x: torch.Tensor, /, @@ -281,7 +285,7 @@ def matrix_transpose( return torch.swapaxes(x, -1, -2) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def outer( x1: torch.Tensor, x2: torch.Tensor, @@ -296,7 +300,7 @@ def outer( outer.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def pinv( x: torch.Tensor, /, @@ -312,7 +316,7 @@ def pinv( pinv.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def tensorsolve( x1: torch.Tensor, x2: torch.Tensor, @@ -324,7 +328,7 @@ def tensorsolve( return torch.linalg.tensorsolve(x1, x2, dims=axes) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def qr( x: torch.Tensor, /, @@ -346,7 +350,7 @@ def qr( return ret -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def slogdet( x: torch.Tensor, /, @@ -361,7 +365,7 @@ def slogdet( slogdet.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def solve( x1: torch.Tensor, x2: torch.Tensor, @@ -397,7 +401,7 @@ def solve( return ret -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def svd( x: torch.Tensor, /, *, full_matrices: bool = True, compute_uv: bool = True ) -> Union[torch.Tensor, Tuple[torch.Tensor, ...]]: @@ -414,7 +418,7 @@ def svd( return results(D) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def svdvals( x: torch.Tensor, /, @@ -430,7 +434,7 @@ def svdvals( # ToDo: re-add int32 support once # (https://github.com/pytorch/pytorch/issues/84530) is fixed -@with_supported_dtypes({"2.1.2 and below": ("float32",)}, backend_version) +@with_supported_dtypes({"2.2 and below": ("float32",)}, backend_version) def tensordot( x1: torch.Tensor, x2: torch.Tensor, @@ -449,7 +453,7 @@ def tensordot( return ret -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def trace( x: torch.Tensor, /, @@ -489,7 +493,7 @@ def vecdot( vecdot.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("integer",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("integer",)}, backend_version) def vector_norm( x: torch.Tensor, /, @@ -515,7 +519,7 @@ def vector_norm( # ----- # -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def diag( x: torch.Tensor, /, @@ -526,7 +530,7 @@ def diag( return torch.diag(x, diagonal=k) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) def vander( x: torch.tensor, /, @@ -552,7 +556,7 @@ def vander( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "complex", "unsigned", ) diff --git a/ivy/functional/backends/torch/manipulation.py b/ivy/functional/backends/torch/manipulation.py index 86cf88bb8e919..023fb00a7409c 100644 --- a/ivy/functional/backends/torch/manipulation.py +++ b/ivy/functional/backends/torch/manipulation.py @@ -1,7 +1,7 @@ # global import math from numbers import Number -from typing import Union, Optional, Tuple, List, Sequence, Iterable +from typing import Iterable, List, Optional, Sequence, Tuple, Union import torch @@ -11,6 +11,7 @@ # noinspection PyProtectedMember from ivy.functional.ivy.manipulation import _calculate_out_shape + from . import backend_version @@ -61,7 +62,7 @@ def flip( out: Optional[torch.Tensor] = None, ) -> torch.Tensor: if copy: - x = x.clone().detach() + x = x.clone() num_dims = len(x.shape) if not num_dims: return x @@ -88,6 +89,10 @@ def permute_dims( return torch.permute(x, axes) +@with_unsupported_dtypes( + {"2.2 and below": ("bfloat16",)}, + backend_version, +) def reshape( x: torch.Tensor, /, @@ -98,6 +103,8 @@ def reshape( allowzero: bool = True, out: Optional[torch.Tensor] = None, ) -> torch.Tensor: + if copy: + x = x.clone() ivy.utils.assertions.check_elem_in_list(order, ["C", "F"]) if not allowzero: shape = [ @@ -234,13 +241,15 @@ def split( torch.tensor(dim_size) / torch.tensor(num_or_size_splits) ) elif isinstance(num_or_size_splits, list): + if num_or_size_splits[-1] == -1: + # infer the final size split + remaining_size = dim_size - sum(num_or_size_splits[:-1]) + num_or_size_splits[-1] = remaining_size num_or_size_splits = tuple(num_or_size_splits) return list(torch.split(x, num_or_size_splits, axis)) -@with_unsupported_dtypes( - {"2.1.2 and below": ("int8", "int16", "uint8")}, backend_version -) +@with_unsupported_dtypes({"2.2 and below": ("int8", "int16", "uint8")}, backend_version) def repeat( x: torch.Tensor, /, @@ -308,7 +317,7 @@ def swapaxes( @with_unsupported_dtypes( - {"2.1.2 and below": ("bool", "float16", "complex")}, backend_version + {"2.2 and below": ("bool", "float16", "complex")}, backend_version ) def clip( x: torch.Tensor, diff --git a/ivy/functional/backends/torch/module.py b/ivy/functional/backends/torch/module.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ivy/functional/backends/torch/norms.py b/ivy/functional/backends/torch/norms.py index 4d2803259ad58..d6c2793b68cb0 100644 --- a/ivy/functional/backends/torch/norms.py +++ b/ivy/functional/backends/torch/norms.py @@ -5,7 +5,7 @@ from . import backend_version -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, backend_version) def layer_norm( x: torch.Tensor, normalized_idxs: List[int], diff --git a/ivy/functional/backends/torch/random.py b/ivy/functional/backends/torch/random.py index efc61ba4c52a1..f4ee4e0cdf2ad 100644 --- a/ivy/functional/backends/torch/random.py +++ b/ivy/functional/backends/torch/random.py @@ -63,7 +63,7 @@ def random_normal( random_normal.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, backend_version) def multinomial( population_size: int, num_samples: int, @@ -78,10 +78,12 @@ def multinomial( ) -> torch.Tensor: if probs is None: probs = ( - torch.ones(( - batch_size, - population_size, - )) + torch.ones( + ( + batch_size, + population_size, + ) + ) / population_size ) if seed: diff --git a/ivy/functional/backends/torch/searching.py b/ivy/functional/backends/torch/searching.py index 847d9b6da30d4..5194967076efa 100644 --- a/ivy/functional/backends/torch/searching.py +++ b/ivy/functional/backends/torch/searching.py @@ -13,7 +13,15 @@ # ------------------ # -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes( + { + "2.2 and below": ( + "complex", + "bool", + ) + }, + backend_version, +) def argmax( x: torch.Tensor, /, @@ -41,7 +49,15 @@ def argmax( return ret -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes( + { + "2.2 and below": ( + "complex", + "bool", + ) + }, + backend_version, +) def argmin( x: torch.Tensor, /, diff --git a/ivy/functional/backends/torch/set.py b/ivy/functional/backends/torch/set.py index 333d90e14c47f..a7eee8289918f 100644 --- a/ivy/functional/backends/torch/set.py +++ b/ivy/functional/backends/torch/set.py @@ -11,7 +11,7 @@ @with_unsupported_dtypes( { - "2.1.2 and below": ("complex", "float16"), + "2.2 and below": ("complex", "float16"), }, backend_version, ) @@ -66,7 +66,7 @@ def unique_all( [i[0] for i in sorted(enumerate(values_), key=lambda x: tuple(x[1]))] ) ivy_torch = ivy.current_backend() - values = ivy_torch.gather(values, sort_idx, axis=axis) + values = values.index_select(dim=axis, index=sort_idx) counts = ivy_torch.gather(counts, sort_idx) indices = ivy_torch.gather(indices, sort_idx) inv_sort_idx = ivy_torch.invert_permutation(sort_idx) @@ -84,7 +84,7 @@ def unique_all( @with_unsupported_dtypes( { - "2.1.2 and below": ("float16",), + "2.2 and below": ("float16",), }, backend_version, ) @@ -98,7 +98,7 @@ def unique_counts(x: torch.Tensor, /) -> Tuple[torch.Tensor, torch.Tensor]: @with_unsupported_dtypes( { - "2.1.2 and below": ("float16",), + "2.2 and below": ("float16",), }, backend_version, ) @@ -124,7 +124,7 @@ def unique_inverse( @with_unsupported_dtypes( { - "2.1.2 and below": ("float16", "complex"), + "2.2 and below": ("float16", "complex"), }, backend_version, ) diff --git a/ivy/functional/backends/torch/sorting.py b/ivy/functional/backends/torch/sorting.py index bbb7475faf966..eac46ae04472f 100644 --- a/ivy/functional/backends/torch/sorting.py +++ b/ivy/functional/backends/torch/sorting.py @@ -8,7 +8,7 @@ from . import backend_version -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def argsort( x: torch.Tensor, /, @@ -29,7 +29,7 @@ def argsort( argsort.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def sort( x: torch.Tensor, /, @@ -51,7 +51,7 @@ def sort( # msort -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def msort( a: Union[torch.Tensor, list, tuple], /, *, out: Optional[torch.Tensor] = None ) -> torch.Tensor: @@ -61,7 +61,7 @@ def msort( msort.support_native_out = True -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def searchsorted( x: torch.Tensor, v: torch.Tensor, diff --git a/ivy/functional/backends/torch/statistical.py b/ivy/functional/backends/torch/statistical.py index dfb1b501bdd61..3fcfbd15ee414 100644 --- a/ivy/functional/backends/torch/statistical.py +++ b/ivy/functional/backends/torch/statistical.py @@ -14,13 +14,15 @@ # -------------------# -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, backend_version) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, backend_version) def min( x: torch.Tensor, /, *, axis: Optional[Union[int, Sequence[int]]] = None, keepdims: bool = False, + initial: Optional[Union[int, float, complex]] = None, + where: Optional[torch.Tensor] = None, out: Optional[torch.Tensor] = None, ) -> torch.Tensor: if axis == (): @@ -28,9 +30,22 @@ def min( return ivy.inplace_update(out, x) else: return x + if where is not None: + max_val = ( + ivy.iinfo(x.dtype).max + if ivy.is_int_dtype(x.dtype) + else ivy.finfo(x.dtype).max + ) + val = torch.ones_like(x) * max_val + val = val.type(x.dtype) + x = torch.where(where, x, val) if not keepdims and not axis and axis != 0: - return torch.amin(input=x, out=out) - return torch.amin(input=x, dim=axis, keepdim=keepdims, out=out) + result = torch.amin(input=x, out=out) + result = torch.amin(input=x, dim=axis, keepdim=keepdims, out=out) + if initial is not None: + initial = torch.tensor(initial, dtype=x.dtype) + result = torch.minimum(result, initial) + return result min.support_native_out = True @@ -66,7 +81,7 @@ def max( max.support_native_out = True -@with_supported_dtypes({"2.1.2 and below": ("float", "complex")}, backend_version) +@with_supported_dtypes({"2.2 and below": ("float", "complex")}, backend_version) def mean( x: torch.Tensor, /, @@ -101,7 +116,7 @@ def _infer_dtype(dtype: torch.dtype) -> torch.dtype: # the function to break the upcasting rule defined in the Array API Standard @with_unsupported_dtypes( { - "2.1.2 and below": ("uint8", "float16", "bfloat16"), + "2.2 and below": ("uint8", "float16", "bfloat16"), }, backend_version, ) @@ -129,7 +144,7 @@ def prod( @with_unsupported_dtypes( - {"2.1.2 and below": ("int8", "int16", "int32", "int64", "float16")}, + {"2.2 and below": ("int8", "int16", "int32", "int64", "float16")}, backend_version, ) def std( @@ -166,7 +181,9 @@ def std( # Function does support uint8, but allowing support for unsigned will cause # the function to break the upcasting rule defined in the Array API Standard -@with_unsupported_dtypes({"2.1.2 and below": ("uint8",)}, backend_version) +@with_unsupported_dtypes( + {"2.2 and below": ("uint8", "float16", "bfloat16")}, backend_version +) def sum( x: torch.Tensor, /, @@ -228,7 +245,7 @@ def var( # TODO: bfloat16 support is added in PyTorch 1.12.1 @with_unsupported_dtypes( { - "2.1.2 and below": ("uint8", "float16", "bfloat16"), + "2.2 and below": ("uint8", "float16", "bfloat16", "bool"), }, backend_version, ) @@ -275,8 +292,8 @@ def cumprod( # TODO: bfloat16 support is added in PyTorch 1.12.1 @with_unsupported_dtypes( { - "1.12.1 and below": ("uint8", "float16", "bfloat16"), - "1.12.1 and above": ("uint8", "float16"), + "1.12.1 and below": ("uint8", "bool", "float16", "bfloat16"), + "1.12.1 and above": ("uint8", "bool", "float16"), }, backend_version, ) @@ -319,7 +336,7 @@ def cumsum( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16",)}, + {"2.2 and below": ("float16",)}, backend_version, ) def einsum( diff --git a/ivy/functional/frontends/__init__.py b/ivy/functional/frontends/__init__.py index 83fa1be55a9e1..6e71d220f4e32 100644 --- a/ivy/functional/frontends/__init__.py +++ b/ivy/functional/frontends/__init__.py @@ -2,15 +2,16 @@ versions = { - "torch": "2.1.2", + "torch": "2.2", "tensorflow": "2.15.0", "numpy": "1.25.2", - "jax": "0.4.23", + "jax": "0.4.24", "scipy": "1.10.1", - "paddle": "2.5.2", + "paddle": "2.6.0", "sklearn": "1.3.0", "xgboost": "1.7.6", "torchvision": "0.15.2.", + "mindspore": "2.0.0", } diff --git a/ivy/functional/frontends/jax/array.py b/ivy/functional/frontends/jax/array.py index 7e5aa872f4c04..2e049123c166a 100644 --- a/ivy/functional/frontends/jax/array.py +++ b/ivy/functional/frontends/jax/array.py @@ -74,7 +74,7 @@ def astype(self, dtype): f"Dtype {self.dtype} is not castable to {dtype}" ) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def argmax( self, /, @@ -90,7 +90,7 @@ def argmax( keepdims=keepdims, ) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def argmin( self, /, diff --git a/ivy/functional/frontends/jax/lax/operators.py b/ivy/functional/frontends/jax/lax/operators.py index c0967b50436d7..9f1cc9b554f63 100644 --- a/ivy/functional/frontends/jax/lax/operators.py +++ b/ivy/functional/frontends/jax/lax/operators.py @@ -157,7 +157,7 @@ def broadcast(operand, sizes): @with_supported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "float32", "float64", @@ -309,7 +309,7 @@ def cosh(x): @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16", "float16", "bool", "complex64", "complex128")}, + {"0.4.24 and below": ("bfloat16", "float16", "bool", "complex64", "complex128")}, "jax", ) @to_ivy_arrays_and_back @@ -400,7 +400,7 @@ def erf(x): @with_supported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "float32", "float64", @@ -465,7 +465,7 @@ def imag(x): @with_unsupported_dtypes( - {"0.4.23 and below": ("bool", "bfloat16")}, + {"0.4.24 and below": ("bool", "bfloat16")}, "jax", ) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/jax/nn/non_linear_activations.py b/ivy/functional/frontends/jax/nn/non_linear_activations.py index 71114b968d1b4..afbaac59e1948 100644 --- a/ivy/functional/frontends/jax/nn/non_linear_activations.py +++ b/ivy/functional/frontends/jax/nn/non_linear_activations.py @@ -289,7 +289,7 @@ def sigmoid(x): @with_supported_dtypes( - {"0.4.23 and below": ("complex", "float")}, + {"0.4.24 and below": ("complex", "float")}, "jax", ) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/jax/numpy/__init__.py b/ivy/functional/frontends/jax/numpy/__init__.py index 4b8a28a0a6ed9..2512624217a74 100644 --- a/ivy/functional/frontends/jax/numpy/__init__.py +++ b/ivy/functional/frontends/jax/numpy/__init__.py @@ -407,8 +407,10 @@ def promote_types_jax( """ try: ret = jax_promotion_table[(ivy.as_ivy_dtype(type1), ivy.as_ivy_dtype(type2))] - except KeyError: - raise ivy.utils.exceptions.IvyException("these dtypes are not type promotable") + except KeyError as e: + raise ivy.utils.exceptions.IvyException( + "these dtypes are not type promotable" + ) from e return ret diff --git a/ivy/functional/frontends/jax/numpy/creation.py b/ivy/functional/frontends/jax/numpy/creation.py index 0ee3781d3c64b..1b72e1ea7819b 100644 --- a/ivy/functional/frontends/jax/numpy/creation.py +++ b/ivy/functional/frontends/jax/numpy/creation.py @@ -17,7 +17,7 @@ @with_unsupported_device_and_dtypes( { - "0.4.23 and below": { + "0.4.24 and below": { "cpu": ( "float16", "bflooat16", @@ -196,7 +196,7 @@ def iterable(y): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -217,7 +217,7 @@ def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) diff --git a/ivy/functional/frontends/jax/numpy/fft.py b/ivy/functional/frontends/jax/numpy/fft.py index e8c18e016caf8..d1500f394e5e1 100644 --- a/ivy/functional/frontends/jax/numpy/fft.py +++ b/ivy/functional/frontends/jax/numpy/fft.py @@ -19,7 +19,7 @@ def fft2(a, s=None, axes=(-2, -1), norm=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def fftfreq(n, d=1.0, *, dtype=None): if not isinstance( n, (int, type(ivy.int8), type(ivy.int16), type(ivy.int32), type(ivy.int64)) diff --git a/ivy/functional/frontends/jax/numpy/linalg.py b/ivy/functional/frontends/jax/numpy/linalg.py index 4e014dee3178f..57c69ee5b1596 100644 --- a/ivy/functional/frontends/jax/numpy/linalg.py +++ b/ivy/functional/frontends/jax/numpy/linalg.py @@ -88,7 +88,7 @@ def multi_dot(arrays, *, precision=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"0.4.23 and below": ("float32", "float64")}, + {"0.4.24 and below": ("float32", "float64")}, "jax", ) def norm(x, ord=None, axis=None, keepdims=False): @@ -127,7 +127,7 @@ def svd(a, /, *, full_matrices=True, compute_uv=True, hermitian=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"0.4.23 and below": ("float16", "bfloat16")}, "jax") +@with_unsupported_dtypes({"0.4.24 and below": ("float16", "bfloat16")}, "jax") def tensorinv(a, ind=2): old_shape = ivy.shape(a) prod = 1 diff --git a/ivy/functional/frontends/jax/numpy/logic.py b/ivy/functional/frontends/jax/numpy/logic.py index e1bc10cd40f16..1c5b45f0d80ed 100644 --- a/ivy/functional/frontends/jax/numpy/logic.py +++ b/ivy/functional/frontends/jax/numpy/logic.py @@ -101,7 +101,7 @@ def equal(x1, x2, /): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"0.4.23 and below": ("bfloat16",)}, "jax") +@with_unsupported_dtypes({"0.4.24 and below": ("bfloat16",)}, "jax") def fromfunction(function, shape, *, dtype=float, **kwargs): def canonicalize_shape(shape, context="shape argument"): if isinstance(shape, int): @@ -285,7 +285,7 @@ def right_shift(x1, x2, /): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"0.4.23 and below": ("bfloat16", "bool")}, "jax") +@with_unsupported_dtypes({"0.4.24 and below": ("bfloat16", "bool")}, "jax") def setxor1d(ar1, ar2, assume_unique=False): common_dtype = ivy.promote_types(ivy.dtype(ar1), ivy.dtype(ar2)) ar1 = ivy.asarray(ar1, dtype=common_dtype) diff --git a/ivy/functional/frontends/jax/numpy/manipulations.py b/ivy/functional/frontends/jax/numpy/manipulations.py index f3f3c1721c546..61fe0fe6279ff 100644 --- a/ivy/functional/frontends/jax/numpy/manipulations.py +++ b/ivy/functional/frontends/jax/numpy/manipulations.py @@ -331,7 +331,7 @@ def transpose(a, axes=None): return a if not axes: axes = list(range(len(a.shape)))[::-1] - if type(axes) is int: + if isinstance(axes, int): axes = [axes] if (len(a.shape) == 0 and not axes) or (len(a.shape) == 1 and axes[0] == 0): return a diff --git a/ivy/functional/frontends/jax/numpy/mathematical_functions.py b/ivy/functional/frontends/jax/numpy/mathematical_functions.py index 3c7b864f20500..0fee3841f509c 100644 --- a/ivy/functional/frontends/jax/numpy/mathematical_functions.py +++ b/ivy/functional/frontends/jax/numpy/mathematical_functions.py @@ -76,7 +76,7 @@ def around(a, decimals=0, out=None): @with_unsupported_dtypes( - {"0.4.23 and below": ("bfloat16",)}, + {"0.4.24 and below": ("bfloat16",)}, "jax", ) @to_ivy_arrays_and_back @@ -90,7 +90,7 @@ def ceil(x, /): return ivy.ceil(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def clip(a, a_min=None, a_max=None, out=None): return ivy.array(ivy.clip(a, a_min, a_max), dtype=a.dtype) @@ -315,7 +315,7 @@ def einsum_path(subscripts, *operands, optimize="greedy"): elif path_type == "optimal": path = optimal_path(input_sets, output_set, dimension_dict, memory_arg) else: - raise KeyError("Path name %s not found", path_type) + raise KeyError(f"Path name {path_type} not found") cost_list, scale_list, size_list, contraction_list = [], [], [], [] @@ -420,7 +420,7 @@ def expm1( @with_unsupported_dtypes( - {"0.4.23 and below": ("uint16",)}, + {"0.4.24 and below": ("uint16",)}, "jax", ) @to_ivy_arrays_and_back @@ -584,7 +584,7 @@ def minimum(x1, x2, /): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"0.4.23 and below": ("complex",)}, "jax") +@with_unsupported_dtypes({"0.4.24 and below": ("complex",)}, "jax") def mod(x1, x2, /): x1, x2 = promote_types_of_jax_inputs(x1, x2) return ivy.remainder(x1, x2) @@ -626,7 +626,7 @@ def negative( @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "bfloat16", "float16", ) @@ -671,7 +671,7 @@ def polyadd(a1, a2): @with_unsupported_dtypes( - {"0.4.23 and below": ("float16",)}, + {"0.4.24 and below": ("float16",)}, "jax", ) @to_ivy_arrays_and_back @@ -713,7 +713,7 @@ def polydiv(u, v, *, trim_leading_zeros=False): @with_unsupported_dtypes( - {"0.4.23 and below": ("float16",)}, + {"0.4.24 and below": ("float16",)}, "jax", ) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/jax/numpy/searching_sorting.py b/ivy/functional/frontends/jax/numpy/searching_sorting.py index cf0973d83d4a4..397031ad1d606 100644 --- a/ivy/functional/frontends/jax/numpy/searching_sorting.py +++ b/ivy/functional/frontends/jax/numpy/searching_sorting.py @@ -16,7 +16,7 @@ @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -111,7 +111,7 @@ def argwhere(a, /, *, size=None, fill_value=None): @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "uint8", "int8", "bool", diff --git a/ivy/functional/frontends/jax/numpy/statistical.py b/ivy/functional/frontends/jax/numpy/statistical.py index 8c26ec22e3c75..0b20517c66187 100644 --- a/ivy/functional/frontends/jax/numpy/statistical.py +++ b/ivy/functional/frontends/jax/numpy/statistical.py @@ -103,7 +103,7 @@ def corrcoef(x, y=None, rowvar=True): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"0.4.23 and below": ("float16", "bfloat16")}, "jax") +@with_unsupported_dtypes({"0.4.24 and below": ("float16", "bfloat16")}, "jax") def correlate(a, v, mode="valid", precision=None): if ivy.get_num_dims(a) != 1 or ivy.get_num_dims(v) != 1: raise ValueError("correlate() only support 1-dimensional inputs.") @@ -404,7 +404,9 @@ def apply_along_axis(func1d, axis, arr, *args, **kwargs): if axis < 0: axis = axis + ndim - func = lambda elem: func1d(elem, *args, **kwargs) + def func(elem): + return func1d(elem, *args, **kwargs) + for i in range(1, ndim - axis): func = ivy.vmap(func, in_axes=i, out_axes=-1) for i in range(axis): @@ -572,7 +574,7 @@ def ptp(a, axis=None, out=None, keepdims=False): @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"0.4.23 and below": ("complex64", "complex128", "bfloat16", "bool", "float16")}, + {"0.4.24 and below": ("complex64", "complex128", "bfloat16", "bool", "float16")}, "jax", ) def quantile( @@ -597,7 +599,7 @@ def quantile( @handle_jax_dtype -@with_unsupported_dtypes({"0.4.23 and below": ("bfloat16",)}, "jax") +@with_unsupported_dtypes({"0.4.24 and below": ("bfloat16",)}, "jax") @to_ivy_arrays_and_back def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=None): axis = tuple(axis) if isinstance(axis, list) else axis diff --git a/ivy/functional/frontends/jax/random.py b/ivy/functional/frontends/jax/random.py index 6fbc288c0aeb6..4a63a1d81baf1 100644 --- a/ivy/functional/frontends/jax/random.py +++ b/ivy/functional/frontends/jax/random.py @@ -38,7 +38,7 @@ def PRNGKey(seed): @to_ivy_arrays_and_back @with_supported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float32", "float64", ) @@ -70,7 +70,7 @@ def bernoulli(key, p=0.5, shape=None): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -85,7 +85,7 @@ def beta(key, a, b, shape=None, dtype=None): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -133,7 +133,7 @@ def cauchy(key, shape=(), dtype="float64"): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -149,7 +149,7 @@ def dirichlet(key, alpha, shape=None, dtype="float32"): @handle_jax_dtype @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"0.4.23 and below": "uint32"}, + {"0.4.24 and below": "uint32"}, "jax", ) def double_sided_maxwell(key, loc, scale, shape=(), dtype="float64"): @@ -168,7 +168,7 @@ def double_sided_maxwell(key, loc, scale, shape=(), dtype="float64"): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -196,7 +196,7 @@ def fold_in(key, data): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -212,7 +212,7 @@ def gamma(key, a, shape=None, dtype="float64"): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -231,7 +231,7 @@ def generalized_normal(key, p, shape=(), dtype="float64"): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -255,7 +255,7 @@ def gumbel(key, shape=(), dtype="float64"): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -270,7 +270,7 @@ def loggamma(key, a, shape=None, dtype="float64"): @handle_jax_dtype @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"0.4.23 and below": ("float16", "bfloat16")}, + {"0.4.24 and below": ("float16", "bfloat16")}, "jax", ) def logistic(key, shape=(), dtype="float64"): @@ -301,7 +301,7 @@ def maxwell(key, shape, dtype="float64"): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -358,7 +358,7 @@ def orthogonal(key, n, shape=(), dtype=None): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "0.4.23 and below": ( + "0.4.24 and below": ( "float16", "bfloat16", ) @@ -393,7 +393,7 @@ def permutation(key, x, axis=0, independent=False): @handle_jax_dtype @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"0.4.23 and below": ("unsigned", "int8", "int16")}, + {"0.4.24 and below": ("unsigned", "int8", "int16")}, "jax", ) def poisson(key, lam, shape=None, dtype=None): @@ -404,7 +404,7 @@ def poisson(key, lam, shape=None, dtype=None): @handle_jax_dtype @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"0.4.23 and below": ("unsigned", "int8", "int16")}, + {"0.4.24 and below": ("unsigned", "int8", "int16")}, "jax", ) def rademacher(key, shape, dtype="int64"): @@ -418,7 +418,7 @@ def rademacher(key, shape, dtype="int64"): @handle_jax_dtype @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"0.4.23 and below": ("unsigned", "int8", "int16")}, + {"0.4.24 and below": ("unsigned", "int8", "int16")}, "jax", ) def randint(key, shape, minval, maxval, dtype="int64"): diff --git a/ivy/functional/frontends/mindspore/ops/function/nn_func.py b/ivy/functional/frontends/mindspore/ops/function/nn_func.py index 864119a245bc0..c476401281148 100644 --- a/ivy/functional/frontends/mindspore/ops/function/nn_func.py +++ b/ivy/functional/frontends/mindspore/ops/function/nn_func.py @@ -111,12 +111,12 @@ def adaptive_avg_pool2d(input, output_size): @to_ivy_arrays_and_back def avg_pool2d( input, - kernel_size, - stride=None, + kernel_size=1, + stride=1, padding=0, - pad_mode=False, + ceil_mode=False, count_include_pad=True, - divisor_override=None, + divisor_override=0, ): # Figure out input dims N input_rank = input.ndim @@ -149,7 +149,7 @@ def avg_pool2d( stride, padding_str, data_format=data_format, - pad_mode=pad_mode, + ceil_mode=ceil_mode, count_include_pad=count_include_pad, divisor_override=divisor_override, ) diff --git a/ivy/functional/frontends/mxnet/numpy/__init__.py b/ivy/functional/frontends/mxnet/numpy/__init__.py index 1f8fb0f1393f8..cc7390eadec51 100644 --- a/ivy/functional/frontends/mxnet/numpy/__init__.py +++ b/ivy/functional/frontends/mxnet/numpy/__init__.py @@ -121,8 +121,10 @@ def promote_types_mxnet( """ try: ret = mxnet_promotion_table[(ivy.as_ivy_dtype(type1), ivy.as_ivy_dtype(type2))] - except KeyError: - raise ivy.utils.exceptions.IvyException("these dtypes are not type promotable") + except KeyError as e: + raise ivy.utils.exceptions.IvyException( + "these dtypes are not type promotable" + ) from e return ret diff --git a/ivy/functional/frontends/numpy/__init__.py b/ivy/functional/frontends/numpy/__init__.py index 9cdf0c1278021..2abc591a2ddcf 100644 --- a/ivy/functional/frontends/numpy/__init__.py +++ b/ivy/functional/frontends/numpy/__init__.py @@ -425,8 +425,10 @@ def promote_numpy_dtypes( type1, type2 = ivy.as_ivy_dtype(type1), ivy.as_ivy_dtype(type2) try: return numpy_promotion_table[(type1, type2)] - except KeyError: - raise ivy.utils.exceptions.IvyException("these dtypes are not type promotable") + except KeyError as e: + raise ivy.utils.exceptions.IvyException( + "these dtypes are not type promotable" + ) from e @handle_exceptions diff --git a/ivy/functional/frontends/numpy/data_type_routines/creating_data_types.py b/ivy/functional/frontends/numpy/data_type_routines/creating_data_types.py index bab1425b65a5c..84bd99b6b71d6 100644 --- a/ivy/functional/frontends/numpy/data_type_routines/creating_data_types.py +++ b/ivy/functional/frontends/numpy/data_type_routines/creating_data_types.py @@ -19,11 +19,11 @@ def __repr__(self): def __ge__(self, other): try: other = dtype(other) - except TypeError: + except TypeError as e: raise ivy.utils.exceptions.IvyException( "Attempted to compare a dtype with something which" "couldn't be interpreted as a dtype" - ) + ) from e return self == np_frontend.promote_numpy_dtypes( self._ivy_dtype, other._ivy_dtype @@ -32,22 +32,22 @@ def __ge__(self, other): def __gt__(self, other): try: other = dtype(other) - except TypeError: + except TypeError as e: raise ivy.utils.exceptions.IvyException( "Attempted to compare a dtype with something which" "couldn't be interpreted as a dtype" - ) + ) from e return self >= other and self != other def __lt__(self, other): try: other = dtype(other) - except TypeError: + except TypeError as e: raise ivy.utils.exceptions.IvyException( "Attempted to compare a dtype with something which" "couldn't be interpreted as a dtype" - ) + ) from e return self != np_frontend.promote_numpy_dtypes( self._ivy_dtype, other._ivy_dtype @@ -56,11 +56,11 @@ def __lt__(self, other): def __le__(self, other): try: other = dtype(other) - except TypeError: + except TypeError as e: raise ivy.utils.exceptions.IvyException( "Attempted to compare a dtype with something which" "couldn't be interpreted as a dtype" - ) + ) from e return self < other or self == other diff --git a/ivy/functional/frontends/numpy/fft/discrete_fourier_transform.py b/ivy/functional/frontends/numpy/fft/discrete_fourier_transform.py index bbf898a2c02d7..738f68cdd1681 100644 --- a/ivy/functional/frontends/numpy/fft/discrete_fourier_transform.py +++ b/ivy/functional/frontends/numpy/fft/discrete_fourier_transform.py @@ -33,7 +33,7 @@ def fft(a, n=None, axis=-1, norm=None): return ivy.fft(ivy.astype(a, ivy.complex128), axis, norm=norm, n=n) -@with_unsupported_dtypes({"1.26.2 and below": ("int",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("int",)}, "numpy") @to_ivy_arrays_and_back def fftfreq(n, d=1.0): if not isinstance( @@ -54,7 +54,7 @@ def fftfreq(n, d=1.0): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") def fftshift(x, axes=None): x = ivy.asarray(x) @@ -99,7 +99,7 @@ def ifftn(a, s=None, axes=None, norm=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") def ifftshift(x, axes=None): x = ivy.asarray(x) @@ -119,7 +119,7 @@ def ifftshift(x, axes=None): return roll -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") @to_ivy_arrays_and_back def ihfft(a, n=None, axis=-1, norm=None): if n is None: @@ -129,7 +129,7 @@ def ihfft(a, n=None, axis=-1, norm=None): return output -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") @to_ivy_arrays_and_back def rfft(a, n=None, axis=-1, norm=None): if norm is None: diff --git a/ivy/functional/frontends/numpy/func_wrapper.py b/ivy/functional/frontends/numpy/func_wrapper.py index cdfc6aaae6137..91df6184aa626 100644 --- a/ivy/functional/frontends/numpy/func_wrapper.py +++ b/ivy/functional/frontends/numpy/func_wrapper.py @@ -30,7 +30,10 @@ def _assert_array(args, dtype, scalar_check=False, casting="safe"): if ivy.is_bool_dtype(dtype): assert_fn = ivy.is_bool_dtype if ivy.is_int_dtype(dtype): - assert_fn = lambda x: not ivy.is_float_dtype(x) + + def assert_fn(x): # noqa F811 + return not ivy.is_float_dtype(x) + if assert_fn: ivy.utils.assertions.check_all_or_any_fn( *args, @@ -51,13 +54,19 @@ def _assert_no_array(args, dtype, scalar_check=False, none=False): if args: first_arg = args[0] fn_func = ivy.as_ivy_dtype(dtype) if ivy.exists(dtype) else ivy.dtype(first_arg) - assert_fn = lambda x: ivy.dtype(x) == fn_func + + def assert_fn(x): + return ivy.dtype(x) == fn_func + if scalar_check: - assert_fn = lambda x: ( - ivy.dtype(x) == fn_func - if ivy.shape(x) != () - else _casting_no_special_case(ivy.dtype(x), fn_func, none) - ) + + def assert_fn(x): # noqa F811 + return ( + ivy.dtype(x) == fn_func + if ivy.shape(x) != () + else _casting_no_special_case(ivy.dtype(x), fn_func, none) + ) + ivy.utils.assertions.check_all_or_any_fn( *args, fn=assert_fn, @@ -105,9 +114,15 @@ def _assert_scalar(args, dtype): if args and dtype: assert_fn = None if ivy.is_int_dtype(dtype): - assert_fn = lambda x: not isinstance(x, float) + + def assert_fn(x): # noqa F811 + return not isinstance(x, float) + elif ivy.is_bool_dtype(dtype): - assert_fn = lambda x: isinstance(x, bool) + + def assert_fn(x): + return isinstance(x, bool) + if assert_fn: ivy.utils.assertions.check_all_or_any_fn( *args, diff --git a/ivy/functional/frontends/numpy/linalg/norms_and_other_numbers.py b/ivy/functional/frontends/numpy/linalg/norms_and_other_numbers.py index e1d492dddfe2d..2ca07b851cadd 100644 --- a/ivy/functional/frontends/numpy/linalg/norms_and_other_numbers.py +++ b/ivy/functional/frontends/numpy/linalg/norms_and_other_numbers.py @@ -23,7 +23,7 @@ def matrix_rank(A, tol=None, hermitian=False): # solve -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") @to_ivy_arrays_and_back @from_zero_dim_arrays_to_scalar def norm(x, ord=None, axis=None, keepdims=False): @@ -46,7 +46,7 @@ def norm(x, ord=None, axis=None, keepdims=False): # slogdet -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") @to_ivy_arrays_and_back @from_zero_dim_arrays_to_scalar def slogdet(a): diff --git a/ivy/functional/frontends/numpy/linalg/solving_equations_and_inverting_matrices.py b/ivy/functional/frontends/numpy/linalg/solving_equations_and_inverting_matrices.py index e6c504d83f360..9c464431774bb 100644 --- a/ivy/functional/frontends/numpy/linalg/solving_equations_and_inverting_matrices.py +++ b/ivy/functional/frontends/numpy/linalg/solving_equations_and_inverting_matrices.py @@ -10,7 +10,7 @@ # inv -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") @to_ivy_arrays_and_back def inv(a): return ivy.inv(a) @@ -19,7 +19,7 @@ def inv(a): # TODO: replace this with function from API # As the compositon provides unstable results @to_ivy_arrays_and_back -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") def lstsq(a, b, rcond="warn"): solution = ivy.matmul( ivy.pinv(a, rtol=1e-15).astype(ivy.float64), b.astype(ivy.float64) @@ -32,14 +32,14 @@ def lstsq(a, b, rcond="warn"): # pinv # TODO: add hermitian functionality -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") @to_ivy_arrays_and_back def pinv(a, rcond=1e-15, hermitian=False): return ivy.pinv(a, rtol=rcond) # solve -@with_unsupported_dtypes({"1.26.2 and below": ("float16",)}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16",)}, "numpy") @to_ivy_arrays_and_back def solve(a, b): a, b = promote_types_of_numpy_inputs(a, b) @@ -47,7 +47,7 @@ def solve(a, b): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"1.26.2 and below": ("float16", "blfloat16")}, "numpy") +@with_unsupported_dtypes({"1.26.3 and below": ("float16", "blfloat16")}, "numpy") def tensorinv(a, ind=2): old_shape = ivy.shape(a) prod = 1 diff --git a/ivy/functional/frontends/numpy/logic/array_contents.py b/ivy/functional/frontends/numpy/logic/array_contents.py index 2d0c40ef64ce7..7388b57862b8d 100644 --- a/ivy/functional/frontends/numpy/logic/array_contents.py +++ b/ivy/functional/frontends/numpy/logic/array_contents.py @@ -25,7 +25,7 @@ def isclose(a, b, /, *, rtol=1e-05, atol=1e-08, equal_nan=False): @with_supported_dtypes( - {"2.5.2 and below": ("int64", "float64", "float32", "int32", "bfloat16")}, "paddle" + {"2.6.0 and below": ("int64", "float64", "float32", "int32", "bfloat16")}, "paddle" ) @to_ivy_arrays_and_back def isin(element, test_elements, assume_unique=False, invert=False): diff --git a/ivy/functional/frontends/numpy/manipulation_routines/transpose_like_operations.py b/ivy/functional/frontends/numpy/manipulation_routines/transpose_like_operations.py index 696e7bb89c673..ca35eba5eeb30 100644 --- a/ivy/functional/frontends/numpy/manipulation_routines/transpose_like_operations.py +++ b/ivy/functional/frontends/numpy/manipulation_routines/transpose_like_operations.py @@ -32,7 +32,7 @@ def swapaxes(a, axis1, axis2): def transpose(array, /, *, axes=None): if not axes: axes = list(range(len(array.shape)))[::-1] - if type(axes) is int: + if isinstance(axes, int): axes = [axes] if (len(array.shape) == 0 and not axes) or (len(array.shape) == 1 and axes[0] == 0): return array diff --git a/ivy/functional/frontends/numpy/mathematical_functions/miscellaneous.py b/ivy/functional/frontends/numpy/mathematical_functions/miscellaneous.py index 43da4792f5f9d..e14023acadb6d 100644 --- a/ivy/functional/frontends/numpy/mathematical_functions/miscellaneous.py +++ b/ivy/functional/frontends/numpy/mathematical_functions/miscellaneous.py @@ -147,7 +147,7 @@ def _fabs( @to_ivy_arrays_and_back @from_zero_dim_arrays_to_scalar @with_supported_dtypes( - {"1.26.2 and below": ("int8", "int16", "int32", "int64")}, "numpy" + {"1.26.3 and below": ("int8", "int16", "int32", "int64")}, "numpy" ) # Add def _gcd( x1, diff --git a/ivy/functional/frontends/numpy/ndarray/ndarray.py b/ivy/functional/frontends/numpy/ndarray/ndarray.py index dc54cdbdd7267..fcb9e0e6684ed 100644 --- a/ivy/functional/frontends/numpy/ndarray/ndarray.py +++ b/ivy/functional/frontends/numpy/ndarray/ndarray.py @@ -415,7 +415,7 @@ def tolist(self) -> list: @with_supported_device_and_dtypes( { - "1.26.2 and below": { + "1.26.3 and below": { "cpu": ( "int64", "float32", diff --git a/ivy/functional/frontends/numpy/statistics/averages_and_variances.py b/ivy/functional/frontends/numpy/statistics/averages_and_variances.py index 3cfd82ed68ced..bd911614f0fc7 100644 --- a/ivy/functional/frontends/numpy/statistics/averages_and_variances.py +++ b/ivy/functional/frontends/numpy/statistics/averages_and_variances.py @@ -13,7 +13,6 @@ @from_zero_dim_arrays_to_scalar def average(a, /, *, axis=None, weights=None, returned=False, keepdims=False): axis = tuple(axis) if isinstance(axis, list) else axis - global avg avg = 0 if keepdims is None: diff --git a/ivy/functional/frontends/numpy/statistics/histograms.py b/ivy/functional/frontends/numpy/statistics/histograms.py index fb0795ec8750c..8220eff8fbd27 100644 --- a/ivy/functional/frontends/numpy/statistics/histograms.py +++ b/ivy/functional/frontends/numpy/statistics/histograms.py @@ -3,7 +3,7 @@ from ivy.func_wrapper import with_supported_dtypes -@with_supported_dtypes({"1.26.2 and below": ("int64",)}, "numpy") +@with_supported_dtypes({"1.26.3 and below": ("int64",)}, "numpy") @to_ivy_arrays_and_back def bincount(x, /, weights=None, minlength=0): return ivy.bincount(x, weights=weights, minlength=minlength) diff --git a/ivy/functional/frontends/onnx/__init__.py b/ivy/functional/frontends/onnx/__init__.py index 46a5fb5daad61..1eafc7e63a158 100644 --- a/ivy/functional/frontends/onnx/__init__.py +++ b/ivy/functional/frontends/onnx/__init__.py @@ -208,8 +208,10 @@ def promote_types_onnx( """ try: ret = onnx_promotion_table[(ivy.as_ivy_dtype(type1), ivy.as_ivy_dtype(type2))] - except KeyError: - raise ivy.utils.exceptions.IvyException("these dtypes are not type promotable") + except KeyError as e: + raise ivy.utils.exceptions.IvyException( + "these dtypes are not type promotable" + ) from e return ret diff --git a/ivy/functional/frontends/paddle/__init__.py b/ivy/functional/frontends/paddle/__init__.py index 58ae61580f139..33518fbaf3905 100644 --- a/ivy/functional/frontends/paddle/__init__.py +++ b/ivy/functional/frontends/paddle/__init__.py @@ -173,8 +173,10 @@ def promote_types_paddle( """ try: ret = paddle_promotion_table[(ivy.as_ivy_dtype(type1), ivy.as_ivy_dtype(type2))] - except KeyError: - raise ivy.utils.exceptions.IvyException("these dtypes are not type promotable") + except KeyError as e: + raise ivy.utils.exceptions.IvyException( + "these dtypes are not type promotable" + ) from e return ret diff --git a/ivy/functional/frontends/paddle/attribute.py b/ivy/functional/frontends/paddle/attribute.py index a94192737bdcb..baa8f64258d4a 100644 --- a/ivy/functional/frontends/paddle/attribute.py +++ b/ivy/functional/frontends/paddle/attribute.py @@ -1,5 +1,6 @@ # global import ivy +from ivy.func_wrapper import with_supported_dtypes from ivy.functional.frontends.paddle.func_wrapper import ( to_ivy_arrays_and_back, ) @@ -30,6 +31,15 @@ def rank(input): return ivy.get_num_dims(input) +@with_supported_dtypes( + { + "2.6.0 and below": ( + "complex64", + "complex128", + ) + }, + "paddle", +) @to_ivy_arrays_and_back def real(x): return ivy.real(x) diff --git a/ivy/functional/frontends/paddle/creation.py b/ivy/functional/frontends/paddle/creation.py index 24d90399e4f8a..2f1b4a5f136c5 100644 --- a/ivy/functional/frontends/paddle/creation.py +++ b/ivy/functional/frontends/paddle/creation.py @@ -7,14 +7,14 @@ ) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def arange(start, end=None, step=1, dtype=None, name=None): return ivy.arange(start, end, step=step, dtype=dtype) @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64", "bool")}, + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64", "bool")}, "paddle", ) @to_ivy_arrays_and_back @@ -30,7 +30,7 @@ def assign(x, output=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("bfloat16", "uint16", "uint32", "uint64")}, "paddle" + {"2.6.0 and below": ("bfloat16", "uint16", "uint32", "uint64")}, "paddle" ) @to_ivy_arrays_and_back def clone(x): @@ -38,7 +38,7 @@ def clone(x): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -54,7 +54,7 @@ def complex(real, imag, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def diag(x, offset=0, padding_value=0, name=None): @@ -69,7 +69,7 @@ def diag(x, offset=0, padding_value=0, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def diagflat(x, offset=0, name=None): @@ -87,6 +87,9 @@ def empty_like(x, dtype=None, name=None): return ivy.empty_like(x, dtype=dtype) +@with_supported_dtypes( + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" +) @to_ivy_arrays_and_back def eye(num_rows, num_columns=None, dtype=None, name=None): return ivy.eye(num_rows, num_columns, dtype=dtype) @@ -105,7 +108,7 @@ def full_like(x, fill_value, /, *, dtype=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def linspace(start, stop, num, dtype=None, name=None): @@ -113,7 +116,7 @@ def linspace(start, stop, num, dtype=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def logspace(start, stop, num, base=10.0, dtype=None, name=None): @@ -121,14 +124,14 @@ def logspace(start, stop, num, base=10.0, dtype=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def meshgrid(*args, **kwargs): return ivy.meshgrid(*args, indexing="ij") -@with_unsupported_dtypes({"2.5.2 and below": "int8"}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": "int8"}, "paddle") @to_ivy_arrays_and_back def ones(shape, /, *, dtype=None, name=None): dtype = "float32" if dtype is None else dtype @@ -136,7 +139,7 @@ def ones(shape, /, *, dtype=None, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("uint8", "int8", "complex64", "complex128")}, "paddle" + {"2.6.0 and below": ("uint8", "int8", "complex64", "complex128")}, "paddle" ) @to_ivy_arrays_and_back def ones_like(x, /, *, dtype=None, name=None): @@ -152,7 +155,7 @@ def to_tensor(data, /, *, dtype=None, place=None, stop_gradient=True): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "uint8", "int8", "int16", @@ -169,7 +172,7 @@ def tril(x, diagonal=0, name=None): return ivy.tril(x, k=diagonal) -@with_supported_dtypes({"2.5.2 and below": ("int32", "int64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("int32", "int64")}, "paddle") @to_ivy_arrays_and_back def tril_indices(row, col, offset=0, dtype="int64"): arr = ivy.tril_indices(row, col, offset) @@ -179,7 +182,7 @@ def tril_indices(row, col, offset=0, dtype="int64"): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "uint8", "int8", "int16", @@ -196,7 +199,7 @@ def triu(x, diagonal=0, name=None): return ivy.triu(x, k=diagonal) -@with_supported_dtypes({"2.5.2 and below": ("int32", "int64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("int32", "int64")}, "paddle") @to_ivy_arrays_and_back def triu_indices(row, col=None, offset=0, dtype="int64"): arr = ivy.triu_indices(row, col, offset) @@ -206,7 +209,7 @@ def triu_indices(row, col=None, offset=0, dtype="int64"): return arr -@with_unsupported_dtypes({"2.5.2 and below": "int8"}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": "int8"}, "paddle") @to_ivy_arrays_and_back def zeros(shape, /, *, dtype=None, name=None): dtype = "float32" if dtype is None else dtype @@ -214,7 +217,7 @@ def zeros(shape, /, *, dtype=None, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("uint8", "int8", "complex64", "complex128")}, "paddle" + {"2.6.0 and below": ("uint8", "int8", "complex64", "complex128")}, "paddle" ) @to_ivy_arrays_and_back def zeros_like(x, /, *, dtype=None, name=None): diff --git a/ivy/functional/frontends/paddle/fft.py b/ivy/functional/frontends/paddle/fft.py index bc72bd9aa7df1..4068bc665bcaf 100644 --- a/ivy/functional/frontends/paddle/fft.py +++ b/ivy/functional/frontends/paddle/fft.py @@ -7,7 +7,7 @@ @with_supported_dtypes( - {"2.5.2 and below": ("complex64", "complex128")}, + {"2.6.0 and below": ("complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -18,7 +18,7 @@ def fft(x, n=None, axis=-1.0, norm="backward", name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float32", @@ -37,7 +37,7 @@ def fft2(x, s=None, axes=(-2, -1), norm="backward", name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float32", @@ -63,7 +63,7 @@ def fftfreq(n, d=1.0, dtype=None, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float32", @@ -92,7 +92,7 @@ def fftshift(x, axes=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("complex64", "complex128")}, + {"2.6.0 and below": ("complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -114,7 +114,7 @@ def hfft(x, n=None, axes=-1, norm="backward", name=None): @with_supported_dtypes( - {"2.5.2 and below": "complex64"}, + {"2.6.0 and below": "complex64"}, "paddle", ) @to_ivy_arrays_and_back @@ -135,7 +135,7 @@ def hfft2(x, s=None, axis=(-2, -1), norm="backward"): @with_supported_dtypes( - {"2.5.2 and below": ("complex64", "complex128")}, + {"2.6.0 and below": ("complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -145,7 +145,7 @@ def ifft(x, n=None, axis=-1.0, norm="backward", name=None): @with_supported_dtypes( - {"2.5.2 and below": ("complex64", "complex128")}, + {"2.6.0 and below": ("complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -156,7 +156,7 @@ def ifftn(x, s=None, axes=None, norm="backward", name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float32", @@ -184,7 +184,7 @@ def ifftshift(x, axes=None, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float32", @@ -238,7 +238,7 @@ def ihfftn(x, s=None, axes=None, norm="backward", name=None): @with_supported_dtypes( - {"2.5.2 and below": ("complex64", "complex128")}, + {"2.6.0 and below": ("complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -257,7 +257,7 @@ def irfft(x, n=None, axis=-1.0, norm="backward", name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float16", @@ -280,7 +280,7 @@ def irfft2(x, s=None, axes=(-2, -1), norm="backward"): # Calculate the normalization factor 'n' based on the shape 's' n = ivy.prod(ivy.array(s)) - result = ivy.ifftn(x, dim=axes[0], norm=norm) + result = ivy.ifftn(x, axes=axes[0], norm=norm) # Normalize the result based on the 'norm' parameter if norm == "backward": @@ -293,7 +293,7 @@ def irfft2(x, s=None, axes=(-2, -1), norm="backward"): @with_supported_dtypes( - {"2.5.2 and below": ("complex64", "complex128")}, + {"2.6.0 and below": ("complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -344,7 +344,7 @@ def irfftn(x, s=None, axes=None, norm="backward", name=None): return result_t -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def rfft(x, n=None, axis=-1, norm="backward", name=None): return ivy.dft(x, axis=axis, inverse=False, onesided=True, dft_length=n, norm=norm) diff --git a/ivy/functional/frontends/paddle/linalg.py b/ivy/functional/frontends/paddle/linalg.py index 23d7e51f918de..559050e2dd0a9 100644 --- a/ivy/functional/frontends/paddle/linalg.py +++ b/ivy/functional/frontends/paddle/linalg.py @@ -14,7 +14,7 @@ def bincount(x, weights=None, minlength=0, name=None): # bmm -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def bmm(x, y, transpose_x=False, transpose_y=False, name=None): if len(ivy.shape(x)) != 3 or len(ivy.shape(y)) != 3: @@ -24,14 +24,14 @@ def bmm(x, y, transpose_x=False, transpose_y=False, name=None): # cholesky -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def cholesky(x, /, *, upper=False, name=None): return ivy.cholesky(x, upper=upper) # cholesky_solve -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def cholesky_solve(x, y, /, *, upper=False, name=None): if upper: @@ -41,7 +41,7 @@ def cholesky_solve(x, y, /, *, upper=False, name=None): # cond -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def cond(x, p=None, name=None): ret = ivy.cond(x, p=p, out=name) @@ -51,7 +51,7 @@ def cond(x, p=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def cross(x, y, /, *, axis=9, name=None): @@ -62,7 +62,7 @@ def cross(x, y, /, *, axis=9, name=None): # diagonal @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float64", @@ -87,7 +87,7 @@ def dist(x, y, p=2): # dot -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def dot(x, y, name=None): x, y = promote_types_of_paddle_inputs(x, y) @@ -151,7 +151,7 @@ def lu_unpack(lu_data, lu_pivots, unpack_datas=True, unpack_pivots=True, *, out= # matmul -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def matmul(x, y, transpose_x=False, transpose_y=False, name=None): x, y = promote_types_of_paddle_inputs(x, y) @@ -159,21 +159,21 @@ def matmul(x, y, transpose_x=False, transpose_y=False, name=None): # matrix_power -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def matrix_power(x, n, name=None): return ivy.matrix_power(x, n) # mv -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def mv(x, vec, name=None): return ivy.dot(x, vec) # norm -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def norm(x, p="fro", axis=None, keepdim=False, name=None): if axis is None and p is not None: @@ -226,7 +226,7 @@ def norm(x, p="fro", axis=None, keepdim=False, name=None): # pinv -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def pinv(x, rcond=1e-15, hermitian=False, name=None): # TODO: Add hermitian functionality @@ -234,21 +234,21 @@ def pinv(x, rcond=1e-15, hermitian=False, name=None): # qr -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def qr(x, mode="reduced", name=None): return ivy.qr(x, mode=mode) # solve -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def solve(x, y, name=None): return ivy.solve(x, y) # transpose -@with_unsupported_dtypes({"2.5.2 and below": ("uint8", "int8", "int16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("uint8", "int8", "int16")}, "paddle") @to_ivy_arrays_and_back def transpose(x, perm, name=None): return ivy.permute_dims(x, axes=perm) diff --git a/ivy/functional/frontends/paddle/logic.py b/ivy/functional/frontends/paddle/logic.py index 220d26ded9aaf..45bb6cd12fc10 100644 --- a/ivy/functional/frontends/paddle/logic.py +++ b/ivy/functional/frontends/paddle/logic.py @@ -13,7 +13,7 @@ @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "float32", "float64", "bool", @@ -35,7 +35,7 @@ def allclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -54,7 +54,7 @@ def bitwise_and(x, y, /, *, name=None, out=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -73,7 +73,7 @@ def bitwise_not(x, out=None, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -92,7 +92,7 @@ def bitwise_or(x, y, name=None, out=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -110,7 +110,7 @@ def bitwise_xor(x, y, /, *, name=None, out=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("uint8", "int8", "int16", "complex64", "complex128")}, + {"2.6.0 and below": ("uint8", "int8", "int16", "complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -120,7 +120,7 @@ def equal(x, y, /, *, name=None): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "uint8", "int8", "int16", @@ -137,7 +137,7 @@ def equal_all(x, y, /, *, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "uint8", "int8", "int16", "complex64", "complex128")}, + {"2.6.0 and below": ("bool", "uint8", "int8", "int16", "complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -146,7 +146,7 @@ def greater_equal(x, y, /, *, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "uint8", "int8", "int16", "complex64", "complex128")}, + {"2.6.0 and below": ("bool", "uint8", "int8", "int16", "complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -155,7 +155,7 @@ def greater_than(x, y, /, *, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("uint8", "int8", "int16", "complex64", "complex128")}, + {"2.6.0 and below": ("uint8", "int8", "int16", "complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -170,7 +170,7 @@ def is_tensor(x): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "float32", "float64", ) @@ -183,7 +183,7 @@ def isclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "uint8", "int8", "int16", "complex64", "complex128")}, + {"2.6.0 and below": ("bool", "uint8", "int8", "int16", "complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -192,7 +192,7 @@ def less_equal(x, y, /, *, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("bool", "float16", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("bool", "float16", "float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -202,7 +202,7 @@ def less_than(x, y, /, *, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int8", "int16", @@ -222,7 +222,7 @@ def logical_and(x, y, /, *, name=None, out=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int8", "int16", @@ -242,7 +242,7 @@ def logical_not(x, /, *, name=None, out=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int8", "int16", @@ -262,7 +262,7 @@ def logical_or(x, y, /, *, name=None, out=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int8", "int16", @@ -281,7 +281,7 @@ def logical_xor(x, y, /, *, name=None, out=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("uint8", "int8", "int16", "complex64", "complex128")}, + {"2.6.0 and below": ("uint8", "int8", "int16", "complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/paddle/manipulation.py b/ivy/functional/frontends/paddle/manipulation.py index 69e9f6c22dbb3..dd7c7e79a28f9 100644 --- a/ivy/functional/frontends/paddle/manipulation.py +++ b/ivy/functional/frontends/paddle/manipulation.py @@ -10,14 +10,14 @@ ) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def abs(x, name=None): return ivy.abs(x) @with_supported_dtypes( - {"2.5.2 and below": ("bool", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("bool", "float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -27,7 +27,7 @@ def broadcast_to(x, shape, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "float16", "float32", @@ -44,14 +44,14 @@ def cast(x, dtype): return ivy.astype(x, dtype) -@with_unsupported_dtypes({"2.5.2 and below": ("int8", "int16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("int8", "int16")}, "paddle") @to_ivy_arrays_and_back def concat(x, axis, name=None): return ivy.concat(x, axis=axis) @with_supported_dtypes( - {"2.5.2 and below": ("bool", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("bool", "float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -60,7 +60,7 @@ def expand(x, shape, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("int8", "uint8", "int16", "float16")}, + {"2.6.0 and below": ("int8", "uint8", "int16", "float16")}, "paddle", ) @to_ivy_arrays_and_back @@ -69,7 +69,7 @@ def flip(x, axis, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("bool", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("bool", "float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -78,7 +78,7 @@ def gather(params, indices, axis=-1, batch_dims=0, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("int8", "uint8", "int16", "uint16", "float16", "bfloat16")}, + {"2.6.0 and below": ("int8", "uint8", "int16", "uint16", "float16", "bfloat16")}, "paddle", ) @to_ivy_arrays_and_back @@ -86,6 +86,37 @@ def gather_nd(x, index, name=None): return ivy.gather_nd(x, index) +@with_supported_dtypes( + {"2.6.0 and below": ("bool", "int32", "int64", "float16", "float32", "float64")}, + "paddle", +) +@to_ivy_arrays_and_back +def index_add(x, index, axis, value, *, name=None): + x = ivy.swapaxes(x, axis, 0) + value = ivy.swapaxes(value, axis, 0) + _to_adds = [] + index = sorted(zip(ivy.to_list(index), range(len(index))), key=(lambda i: i[0])) + while index: + _curr_idx = index[0][0] + while len(_to_adds) < _curr_idx: + _to_adds.append(ivy.zeros_like(value[0])) + _to_add_cum = ivy.get_item(value, index[0][1]) + while (len(index)) > 1 and (index[0][0] == index[1][0]): + _to_add_cum = _to_add_cum + ivy.get_item(value, index.pop(1)[1]) + index.pop(0) + _to_adds.append(_to_add_cum) + while len(_to_adds) < x.shape[0]: + _to_adds.append(ivy.zeros_like(value[0])) + _to_adds = ivy.stack(_to_adds) + if len(x.shape) < 2: + # Added this line due to the paddle backend treating scalars as 1-d arrays + _to_adds = ivy.flatten(_to_adds) + + ret = ivy.add(x, _to_adds) + ret = ivy.swapaxes(ret, axis, 0) + return ret + + @to_ivy_arrays_and_back def put_along_axis(arr, indices, values, axis, reduce="assign"): result = ivy.put_along_axis(arr, indices, values, axis) @@ -93,7 +124,7 @@ def put_along_axis(arr, indices, values, axis, reduce="assign"): @with_supported_dtypes( - {"2.5.2 and below": ("int32", "int64", "float32", "float64")}, + {"2.6.0 and below": ("int32", "int64", "float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -126,7 +157,7 @@ def roll(x, shifts, axis=None, name=None): @with_supported_device_and_dtypes( { - "2.5.2 and above": { + "2.6.0 and above": { "cpu": ( "bool", "int32", @@ -145,7 +176,7 @@ def rot90(x, k=1, axes=(0, 1), name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("int16", "complex64", "complex128")}, + {"2.6.0 and below": ("int16", "complex64", "complex128")}, "paddle", ) @to_ivy_arrays_and_back @@ -154,7 +185,7 @@ def split(x, num_or_sections, axis=0, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("float16", "bfloat16", "int8", "int16")}, + {"2.6.0 and below": ("float16", "bfloat16", "int8", "int16")}, "paddle", ) @to_ivy_arrays_and_back @@ -167,12 +198,17 @@ def stack(x, axis=0, name=None): return ivy.stack(x, axis=axis) +@with_supported_dtypes( + {"2.6.0 and below": ("float32", "float64")}, + "paddle", +) +@to_ivy_arrays_and_back def take_along_axis(arr, indices, axis): return ivy.take_along_axis(arr, indices, axis) @with_unsupported_dtypes( - {"2.5.2 and below": ("int8", "uint8", "int16", "float16")}, + {"2.6.0 and below": ("int8", "uint8", "int16", "float16")}, "paddle", ) @to_ivy_arrays_and_back @@ -186,7 +222,7 @@ def tolist(x): @with_supported_dtypes( - {"2.5.2 and below": ("bool", "int32", "int64", "float16", "float32", "float64")}, + {"2.6.0 and below": ("bool", "int32", "int64", "float16", "float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -198,7 +234,7 @@ def unbind(input, axis=0): @with_supported_dtypes( - {"2.5.2 and below": ("bool", "int32", "int64", "float16", "float32", "float64")}, + {"2.6.0 and below": ("bool", "int32", "int64", "float16", "float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -208,7 +244,7 @@ def unique_consecutive(x, axis=0): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "float32", "float64", "int32", diff --git a/ivy/functional/frontends/paddle/math.py b/ivy/functional/frontends/paddle/math.py index f8cd603766781..a70fc6179477f 100644 --- a/ivy/functional/frontends/paddle/math.py +++ b/ivy/functional/frontends/paddle/math.py @@ -8,26 +8,26 @@ from ivy.functional.frontends.paddle.func_wrapper import to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def abs(x, name=None): return ivy.abs(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def acos(x, name=None): return ivy.acos(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def acosh(x, name=None): return ivy.acosh(x) @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle" + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle" ) @to_ivy_arrays_and_back def add(x, y, name=None): @@ -35,7 +35,7 @@ def add(x, y, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle" + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle" ) @to_ivy_arrays_and_back def add_(x, y, name=None): @@ -43,7 +43,7 @@ def add_(x, y, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def addmm(input, x, y, beta=1.0, alpha=1.0, name=None): @@ -58,7 +58,7 @@ def all(x, axis, keepdim=False, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def amax(x, axis=None, keepdims=False): @@ -76,7 +76,7 @@ def amax(x, axis=None, keepdims=False): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def amin(x, axis=None, keepdim=False, name=None): @@ -84,7 +84,7 @@ def amin(x, axis=None, keepdim=False, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("complex64", "complex128", "float32", "float64")}, + {"2.6.0 and below": ("complex64", "complex128", "float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -98,19 +98,19 @@ def any(x, axis=None, keepdim=False, name=None): return ivy.any(x, axis=axis, keepdims=keepdim) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def asin(x, name=None): return ivy.asin(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def asinh(x, name=None): return ivy.asinh(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def atan(x, name=None): return ivy.atan(x) @@ -122,19 +122,19 @@ def atan2(x, y, name=None): return ivy.atan2(x, y) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def atanh(x, name=None): return ivy.atanh(x) -@with_supported_dtypes({"2.5.2 and below": ("int32", "int64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("int32", "int64")}, "paddle") @to_ivy_arrays_and_back def broadcast_shape(x_shape, y_shape): return ivy.broadcast_shapes(x_shape, y_shape) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def ceil(x, name=None): return ivy.ceil(x) @@ -146,20 +146,20 @@ def conj(x, name=None): return ivy.conj(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def cos(x, name=None): return ivy.cos(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def cosh(x, name=None): return ivy.cosh(x) @with_supported_dtypes( - {"2.5.2 and below": ("int32", "int64", "float16", "float32", "float64", "bool")}, + {"2.6.0 and below": ("int32", "int64", "float16", "float32", "float64", "bool")}, "paddle", ) @to_ivy_arrays_and_back @@ -169,7 +169,7 @@ def count_nonzero(x, axis=None, keepdim=False, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float32", @@ -186,14 +186,14 @@ def cumprod(x, dim=None, dtype=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def cumsum(x, axis=None, dtype=None, name=None): return ivy.cumsum(x, axis=axis, dtype=dtype) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def deg2rad(x, name=None): return ivy.deg2rad(x) @@ -201,7 +201,7 @@ def deg2rad(x, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float64", @@ -219,53 +219,53 @@ def diagonal(x, offset=0, axis1=0, axis2=1, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def diff(x, n=1, axis=-1, prepend=None, append=None, name=None): return ivy.diff(x, n=n, axis=axis, prepend=prepend, append=append) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def digamma(x, name=None): digamma_fun = ivy.digamma return ivy.array(digamma_fun(x), dtype=x.dtype) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def divide(x, y, name=None): return ivy.divide(x, y) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def erf(x, name=None): return ivy.erf(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def exp(x, name=None): return ivy.exp(x) -@with_supported_dtypes({"2.5.2 and below": ("float16", "float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float16", "float32", "float64")}, "paddle") @to_ivy_arrays_and_back def expm1(x, name=None): return ivy.expm1(x) @with_supported_dtypes( - {"2.5.2 and below": ("bfloat16", "float32", "float64")}, "paddle" + {"2.6.0 and below": ("bfloat16", "float32", "float64")}, "paddle" ) @to_ivy_arrays_and_back def floor(x, name=None): return ivy.floor(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def floor_divide(x, y, name=None): return ivy.floor_divide(x, y) @@ -273,7 +273,7 @@ def floor_divide(x, y, name=None): @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("float32", "float64", "int32", "int64"), "gpu": ("float16", "float32", "float64", "int32", "int64"), } @@ -285,20 +285,24 @@ def floor_mod(x, y, name=None): return ivy.remainder(x, y) -@with_unsupported_dtypes({"2.5.2 and below": "bfloat16"}, "paddle") +@with_supported_dtypes( + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" +) @to_ivy_arrays_and_back def fmax(x, y, name=None): return ivy.fmax(x, y) -@with_unsupported_dtypes({"2.5.2 and below": "bfloat16"}, "paddle") +@with_supported_dtypes( + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" +) @to_ivy_arrays_and_back def fmin(x, y, name=None): return ivy.fmin(x, y) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def frac(x, name=None): @@ -306,21 +310,21 @@ def frac(x, name=None): return ivy.subtract(x, y) -@with_supported_dtypes({"2.5.2 and below": ("int32", "int64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("int32", "int64")}, "paddle") @to_ivy_arrays_and_back def gcd(x, y, name=None): return ivy.gcd(x, y) @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def heaviside(x, y, name=None): return ivy.heaviside(x, y) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def inner(x, y, name=None): result = ivy.inner(x, y) @@ -331,14 +335,14 @@ def inner(x, y, name=None): return result -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def inverse(x, name=None): return ivy.inv(x) @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def isfinite(x, name=None): @@ -346,7 +350,7 @@ def isfinite(x, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def isinf(x, name=None): @@ -354,7 +358,7 @@ def isinf(x, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def isnan(x, name=None): @@ -362,63 +366,86 @@ def isnan(x, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def kron(x, y, name=None): return ivy.kron(x, y) -@with_supported_dtypes({"2.5.2 and below": ("int32", "int64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("int32", "int64")}, "paddle") @to_ivy_arrays_and_back def lcm(x, y, name=None): return ivy.lcm(x, y) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def lerp(x, y, weight, name=None): return ivy.lerp(x, y, weight) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def lgamma(x, name=None): return ivy.lgamma(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def log(x, name=None): return ivy.log(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def log10(x, name=None): return ivy.log10(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def log1p(x, name=None): return ivy.log1p(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def log2(x, name=None): return ivy.log2(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def logit(x, eps=None, name=None): return ivy.logit(x, eps=eps) +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") +@to_ivy_arrays_and_back +def logsumexp(x, axis=None, y=None): + x = ivy.asarray(x) + if y is not None: + y = ivy.asarray(y) + x = ivy.where(y != 0, x, -ivy.inf) + if axis is None: + amax = ivy.max(x) + expsub = ivy.exp(x - amax) + sumexp = ivy.sum(expsub) + out = ivy.log(sumexp) + amax + else: + amax = ivy.max(x, axis=axis, keepdims=True) + expsub = ivy.exp(x - amax) + sumexp = ivy.sum(expsub, axis=axis, keepdims=True) + out = ivy.log(sumexp) + amax + if y is not None: + sign = ivy.stop_gradient(ivy.sign(sumexp)) + out = ivy.where(sign < 0, ivy.nan, out) + return out + + @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def max(x, axis=None, keepdim=False, name=None): @@ -426,14 +453,14 @@ def max(x, axis=None, keepdim=False, name=None): # maximum -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def maximum(x, y, name=None): return ivy.maximum(x, y) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def min(x, axis=None, keepdim=False, name=None): @@ -441,7 +468,7 @@ def min(x, axis=None, keepdim=False, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def minimum(x, y, name=None): @@ -449,27 +476,27 @@ def minimum(x, y, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def mm(input, mat2, name=None): return ivy.matmul(input, mat2) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def multiply(x, y, name=None): return ivy.multiply(x, y) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def nanmean(x, axis=None, keepdims=False): return ivy.nanmean(x, axis=axis, keepdims=keepdims) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def nansum(x, axis=None, dtype=None, name=None): @@ -477,7 +504,7 @@ def nansum(x, axis=None, dtype=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int8", "int16", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int8", "int16", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -485,39 +512,41 @@ def neg(x, name=None): return ivy.negative(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def outer(x, y, name=None): return ivy.outer(x, y) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_supported_dtypes( + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle" +) @to_ivy_arrays_and_back def pow(x, y, name=None): return ivy.pow(x, y) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def prod(x, axis=None, keepdim=False, dtype=None, name=None): return ivy.prod(x, axis=axis, keepdims=keepdim, dtype=dtype) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def rad2deg(x, name=None): return ivy.rad2deg(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def reciprocal(x, name=None): return ivy.reciprocal(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def remainder(x, y, name=None): return ivy.remainder(x, y) @@ -525,7 +554,7 @@ def remainder(x, y, name=None): @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("float32", "float64"), "gpu": ("float16", "float32", "float64"), } @@ -537,7 +566,7 @@ def remainder_(x, y, name=None): return ivy.inplace_update(x, remainder(x, y)) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def round(x, name=None): sign = ivy.sign(x) @@ -545,49 +574,49 @@ def round(x, name=None): return x -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def rsqrt(x, name=None): return 1 / ivy.sqrt(x) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def sgn(x, name=None): return ivy.sign(x, np_variant=True) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def sign(x, name=None): return ivy.sign(x, np_variant=False) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def sin(x, name=None): return ivy.sin(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def sinh(x, name=None): return ivy.sinh(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def sqrt(x, name=None): return ivy.sqrt(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def square(x, name=None): return ivy.square(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def stanh(x, scale_a=0.67, scale_b=1.7159, name=None): # TODO this function will be simplified as soon as the ivy.stanh(x,a,b) is added @@ -599,7 +628,7 @@ def stanh(x, scale_a=0.67, scale_b=1.7159, name=None): return ret -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def subtract(x, y, name=None): return ivy.subtract(x, y) @@ -607,7 +636,7 @@ def subtract(x, y, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "float64", "int64", ) @@ -625,7 +654,7 @@ def sum(x, axis=None, dtype=None, keepdim=False, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int6")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int6")}, "paddle" ) @to_ivy_arrays_and_back def take( @@ -647,20 +676,20 @@ def take( return ivy.gather(x, index, axis=0) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def tan(x, name=None): return ivy.tan(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def tanh(x, name=None): return ivy.tanh(x) @with_supported_dtypes( - {"2.5.2 and below": ("int32", "int64", "float32", "float64")}, "paddle" + {"2.6.0 and below": ("int32", "int64", "float32", "float64")}, "paddle" ) @to_ivy_arrays_and_back def trace(x, offset=0, axis1=0, axis2=1, name=None): diff --git a/ivy/functional/frontends/paddle/nn/functional/activation.py b/ivy/functional/frontends/paddle/nn/functional/activation.py index f8621b7f3f998..da520c585e761 100644 --- a/ivy/functional/frontends/paddle/nn/functional/activation.py +++ b/ivy/functional/frontends/paddle/nn/functional/activation.py @@ -8,7 +8,7 @@ tanh = paddle_tanh -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def celu( x, @@ -20,7 +20,7 @@ def celu( return ivy.celu(x, alpha=alpha) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def elu( x, @@ -32,13 +32,13 @@ def elu( return ivy.elu(x, alpha=alpha) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def gelu(x, approximate=False, name=None): return ivy.gelu(x, approximate=approximate) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def glu(x, axis=-1, name=None): size = x.shape[axis] @@ -63,21 +63,21 @@ def gumbel_softmax(x, temperature=1.0, hard=False, axis=-1, name=None): return y_soft -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def hardshrink(x, threshold=0.5, name=None): mask = ivy.logical_or(ivy.greater(x, threshold), ivy.less(x, -threshold)) return ivy.where(mask, x, 0.0) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def hardsigmoid(x, slope=0.1666667, offset=0.5, name=None): ret = ivy.minimum(ivy.maximum(ivy.add(ivy.multiply(x, slope), offset), 0), 1) return ret -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def hardswish(x, name=None): relu6_val = ivy.relu6(ivy.add(x, 3)) @@ -85,7 +85,7 @@ def hardswish(x, name=None): return ret -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def hardtanh( x, @@ -106,13 +106,13 @@ def leaky_relu(x, negative_slope=0.01, name=None): return ivy.leaky_relu(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def log_sigmoid(x, name=None): return -ivy.softplus(-x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def log_softmax(x, axis=-1, dtype=None, name=None): x = ivy.astype(x, dtype) if dtype else x @@ -121,31 +121,31 @@ def log_softmax(x, axis=-1, dtype=None, name=None): return ret -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def mish(x, name=None): return ivy.mish(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def prelu(x, weight, data_format="NCHW", name=None): return ivy.add(ivy.maximum(0, x), ivy.multiply(weight, ivy.minimum(0, x))) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def relu(x, name=None): return ivy.relu(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def relu6(x, name=None): return ivy.relu6(x) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def relu_(x, name=None): ret = ivy.relu(x) @@ -153,7 +153,7 @@ def relu_(x, name=None): return x -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def rrelu( x, @@ -189,7 +189,7 @@ def rrelu( return out.astype(x.dtype) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def selu( x, @@ -222,13 +222,13 @@ def softmax_(x, axis=-1, dtype=None, name=None): return x -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def softplus(x, beta=1, threshold=20, name=None): return ivy.softplus(x, beta=beta, threshold=threshold) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def softshrink( x, @@ -243,7 +243,7 @@ def softshrink( return ivy.astype(add, x.dtype) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def softsign( x, @@ -254,7 +254,7 @@ def softsign( return ivy.divide(x, ivy.add(1, ivy.abs(x))) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def swish(x, name=None): return ivy.multiply(x, ivy.sigmoid(x)) @@ -273,7 +273,7 @@ def tanh_(x, name=None): # return ret.astype(x.dtype) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def tanhshrink( x, diff --git a/ivy/functional/frontends/paddle/nn/functional/common.py b/ivy/functional/frontends/paddle/nn/functional/common.py index 4f513b23cf5a9..882ce9a543f64 100644 --- a/ivy/functional/frontends/paddle/nn/functional/common.py +++ b/ivy/functional/frontends/paddle/nn/functional/common.py @@ -5,7 +5,7 @@ @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def cosine_similarity(x1, x2, *, axis=1, eps=1e-08): if len(x1.shape) == len(x2.shape) and len(x2.shape) >= 2: numerator = ivy.sum(x1 * x2, axis=axis) @@ -26,7 +26,7 @@ def cosine_similarity(x1, x2, *, axis=1, eps=1e-08): @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def dropout(x, p=0.5, axis=None, training=True, mode="upscale_in_train", name=None): if axis is not None and axis > 1: raise ValueError("Axis value can only be 0 or 1 or None.") @@ -53,13 +53,13 @@ def dropout(x, p=0.5, axis=None, training=True, mode="upscale_in_train", name=No @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def dropout2d(x, *, p=0.5, training=True, data_format="NCHW", name=None): return ivy.dropout2d(x, p, training=training, data_format=data_format) @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def dropout3d(x, p=0.5, training=True, data_format="NCDHW", name=None): return ivy.dropout3d(x, p, training=training, data_format=data_format) @@ -74,7 +74,7 @@ def get_mask(shape, device, prob, seed=None): @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def interpolate( x, size=None, @@ -91,14 +91,14 @@ def interpolate( @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def linear(x, weight, bias=None, name=None): weight = ivy.swapaxes(weight, -1, -2) return ivy.linear(x, weight, bias=bias) @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def unfold(x, kernel_sizes, strides=1, paddings=0, dilations=1, name=None): # Input checking if isinstance(kernel_sizes, int): @@ -178,7 +178,7 @@ def unfold(x, kernel_sizes, strides=1, paddings=0, dilations=1, name=None): @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def zeropad2d(x, padding, data_format="NCHW", name=None): if ivy.is_array(padding): padding = padding.to_list() diff --git a/ivy/functional/frontends/paddle/nn/functional/conv.py b/ivy/functional/frontends/paddle/nn/functional/conv.py index 296ba22e4237c..43e7699eba218 100644 --- a/ivy/functional/frontends/paddle/nn/functional/conv.py +++ b/ivy/functional/frontends/paddle/nn/functional/conv.py @@ -79,7 +79,7 @@ def _conv_transpose( # ------------ # -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def conv1d( x, @@ -95,7 +95,7 @@ def conv1d( return _conv(x, weight, bias, stride, padding, dilation, groups, data_format) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def conv1d_transpose( x, @@ -115,7 +115,7 @@ def conv1d_transpose( ) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def conv2d( x, @@ -131,7 +131,7 @@ def conv2d( return _conv(x, weight, bias, stride, padding, dilation, groups, data_format) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def conv2d_transpose( x, @@ -151,7 +151,7 @@ def conv2d_transpose( ) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def conv3d( x, @@ -167,7 +167,7 @@ def conv3d( return _conv(x, weight, bias, stride, padding, dilation, groups, data_format) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def conv3d_transpose( x, diff --git a/ivy/functional/frontends/paddle/nn/functional/loss.py b/ivy/functional/frontends/paddle/nn/functional/loss.py index 5951a446501b8..41cf9f9ab8d1e 100644 --- a/ivy/functional/frontends/paddle/nn/functional/loss.py +++ b/ivy/functional/frontends/paddle/nn/functional/loss.py @@ -47,7 +47,7 @@ def _pairwise_distance(x1, x2, *, p=2.0, eps=1e-06, keepdim=False): # ------------ # -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def binary_cross_entropy(input, label, weight=None, reduction="mean", name=None): reduction = _get_reduction_func(reduction) @@ -59,7 +59,7 @@ def binary_cross_entropy(input, label, weight=None, reduction="mean", name=None) @with_supported_dtypes( - {"2.5.2 and below": ("float32",)}, + {"2.6.0 and below": ("float32",)}, "paddle", ) @inputs_to_ivy_arrays @@ -83,7 +83,7 @@ def binary_cross_entropy_with_logits( @handle_exceptions @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def cosine_embedding_loss( input1, input2, label, margin=0.0, reduction="mean", name=None ): @@ -124,7 +124,7 @@ def cosine_embedding_loss( return out -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def dice_loss(input, label, epsilon=0.00001, name=None): ivy.assertions.check_true( @@ -163,7 +163,7 @@ def dice_loss(input, label, epsilon=0.00001, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32",)}, + {"2.6.0 and below": ("float32",)}, "paddle", ) @to_ivy_arrays_and_back @@ -187,7 +187,7 @@ def hinge_embedding_loss(input, label, margin=1.0, reduction="mean"): return loss -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def kl_div( input, @@ -234,7 +234,7 @@ def l1_loss( @with_supported_dtypes( - {"2.5.2 and below": ("float32",)}, + {"2.6.0 and below": ("float32",)}, "paddle", ) @to_ivy_arrays_and_back @@ -245,7 +245,7 @@ def log_loss(input, label, epsilon=0.0001, name=None): return out -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def margin_ranking_loss(input, other, label, margin=0.0, reduction="mean", name=None): reduction = _get_reduction_func(reduction) @@ -265,7 +265,7 @@ def margin_ranking_loss(input, other, label, margin=0.0, reduction="mean", name= return out -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @inputs_to_ivy_arrays def mse_loss(input, label, reduction="mean", name=None): reduction = _get_reduction_func(reduction) @@ -275,7 +275,7 @@ def mse_loss(input, label, reduction="mean", name=None): return paddle.to_tensor(ret) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def multi_label_soft_margin_loss( input, label, weight=None, reduction="mean", name=None @@ -293,7 +293,7 @@ def multi_label_soft_margin_loss( return ret -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def nll_loss( input, @@ -326,7 +326,7 @@ def nll_loss( return output -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def sigmoid_focal_loss( logit, @@ -372,7 +372,7 @@ def sigmoid_focal_loss( return loss -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def smooth_l1_loss( input, @@ -399,7 +399,7 @@ def smooth_l1_loss( @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, "paddle", ) @inputs_to_ivy_arrays @@ -459,13 +459,13 @@ def softmax_with_cross_entropy( return paddle.to_tensor(loss) -@with_supported_dtypes({"2.5.2 and below": ("float32",)}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32",)}, "paddle") @to_ivy_arrays_and_back def square_error_cost(input, label): return ivy.square(ivy.subtract(input, label)) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def triplet_margin_loss( input, diff --git a/ivy/functional/frontends/paddle/nn/functional/norm.py b/ivy/functional/frontends/paddle/nn/functional/norm.py index 392abafeca45b..0090bb9ac5a9f 100644 --- a/ivy/functional/frontends/paddle/nn/functional/norm.py +++ b/ivy/functional/frontends/paddle/nn/functional/norm.py @@ -5,13 +5,13 @@ @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def layer_norm(x, normalized_shape, weight=None, bias=None, epsilon=1e-05, name=None): return ivy.layer_norm(x, normalized_shape, scale=weight, offset=bias, eps=epsilon) @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def normalize(x, p=2, axis=1, epsilon=1e-12, name=None): if axis < 0: axis = ivy.get_num_dims(x) + axis diff --git a/ivy/functional/frontends/paddle/nn/functional/pooling.py b/ivy/functional/frontends/paddle/nn/functional/pooling.py index 261176db7211c..219b73f8a47b7 100644 --- a/ivy/functional/frontends/paddle/nn/functional/pooling.py +++ b/ivy/functional/frontends/paddle/nn/functional/pooling.py @@ -7,13 +7,13 @@ @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def adaptive_avg_pool1d(x, output_size, name=None): return ivy.adaptive_avg_pool1d(x, output_size) @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def adaptive_avg_pool2d(x, output_size, data_format="NCHW", name=None): return ivy.adaptive_avg_pool2d(x, output_size, data_format=data_format) @@ -25,13 +25,13 @@ def adaptive_avg_pool3d(x, output_size, data_format="NCHW", name=None): @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def adaptive_max_pool2d(x, output_size, return_mask=None, name=None): return ivy.adaptive_max_pool2d(x, output_size) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def avg_pool1d( x, kernel_size, stride=None, padding=0, exclusive=True, ceil_mode=False, name=None ): @@ -61,7 +61,7 @@ def avg_pool1d( @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def avg_pool2d( x, kernel_size, @@ -99,7 +99,7 @@ def avg_pool2d( @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.1 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def max_pool2d( x, kernel_size, @@ -133,7 +133,7 @@ def max_pool2d( @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def max_unpool1d( x, indices, diff --git a/ivy/functional/frontends/paddle/nn/functional/vision.py b/ivy/functional/frontends/paddle/nn/functional/vision.py index 73fcae0c89e1b..bc7b222e83ea8 100644 --- a/ivy/functional/frontends/paddle/nn/functional/vision.py +++ b/ivy/functional/frontends/paddle/nn/functional/vision.py @@ -9,7 +9,7 @@ @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def affine_grid(theta, out_shape, align_corners=True): if len(out_shape) == 4: N, C, H, W = out_shape @@ -75,7 +75,7 @@ def affine_grid(theta, out_shape, align_corners=True): @to_ivy_arrays_and_back -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def channel_shuffle(x, groups, data_format="NCHW", name=None): if len(ivy.shape(x)) != 4: raise ValueError( diff --git a/ivy/functional/frontends/paddle/random.py b/ivy/functional/frontends/paddle/random.py index 2a436935b9933..dafb52ffd7ece 100644 --- a/ivy/functional/frontends/paddle/random.py +++ b/ivy/functional/frontends/paddle/random.py @@ -8,7 +8,7 @@ @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -18,7 +18,7 @@ def multinomial(x, num_samples=1, replacement=False, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -27,7 +27,7 @@ def normal(mean=0.0, std=1.0, shape=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -37,7 +37,7 @@ def poisson(x, name=None): @with_supported_device_and_dtypes( { - "2.5.2 and above": { + "2.6.0 and above": { "cpu": ( "bfloat16", "float32", @@ -75,7 +75,7 @@ def randint(low=0, high=None, shape=[1], dtype=None, name=None): @with_unsupported_dtypes( - {"2.5.2 and below": ("int16", "float16", "bfloat16", "uint8")}, + {"2.6.0 and below": ("int16", "float16", "bfloat16", "uint8")}, "paddle", ) @to_ivy_arrays_and_back @@ -99,7 +99,7 @@ def randn(shape, dtype=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -108,7 +108,7 @@ def standard_normal(shape, dtype=None, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/paddle/search.py b/ivy/functional/frontends/paddle/search.py index c26923d08ae2e..29608b493561c 100644 --- a/ivy/functional/frontends/paddle/search.py +++ b/ivy/functional/frontends/paddle/search.py @@ -7,7 +7,7 @@ @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int16", "int32", "int64", "uint8")}, + {"2.6.0 and below": ("float32", "float64", "int16", "int32", "int64", "uint8")}, "paddle", ) @to_ivy_arrays_and_back @@ -16,7 +16,7 @@ def argmax(x, /, *, axis=None, keepdim=False, dtype="int64", name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int16", "int32", "int64", "uint8")}, + {"2.6.0 and below": ("float32", "float64", "int16", "int32", "int64", "uint8")}, "paddle", ) @to_ivy_arrays_and_back @@ -34,7 +34,7 @@ def argsort(x, /, *, axis=-1, descending=False, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("int32", "int64", "float32", "float64")}, + {"2.6.0 and below": ("int32", "int64", "float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -44,7 +44,7 @@ def index_sample(x, index): # kthvalue @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def kthvalue(x, k, axis=None, keepdim=False, name=None): @@ -65,7 +65,7 @@ def kthvalue(x, k, axis=None, keepdim=False, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -86,7 +86,7 @@ def nonzero(input, /, *, as_tuple=False): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -102,7 +102,7 @@ def searchsorted(sorted_sequence, values, out_int32=False, right=False, name=Non @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -111,7 +111,7 @@ def sort(x, /, *, axis=-1, descending=False, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -121,7 +121,7 @@ def topk(x, k, axis=None, largest=True, sorted=True, name=None): # where @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/paddle/stat.py b/ivy/functional/frontends/paddle/stat.py index 1ee6edd5ce54d..695e60dc5bd4e 100644 --- a/ivy/functional/frontends/paddle/stat.py +++ b/ivy/functional/frontends/paddle/stat.py @@ -1,12 +1,12 @@ # global import ivy -from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes +from ivy.func_wrapper import with_supported_dtypes from ivy.functional.frontends.paddle.func_wrapper import ( to_ivy_arrays_and_back, ) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def mean(input, axis=None, keepdim=False, out=None): ret = ivy.mean(input, axis=axis, keepdims=keepdim, out=out) @@ -14,7 +14,7 @@ def mean(input, axis=None, keepdim=False, out=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -37,7 +37,7 @@ def nanmedian(x, axis=None, keepdim=True, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("bool", "float16", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("bool", "float16", "float32", "float64", "int32", "int64")}, "paddle", ) @to_ivy_arrays_and_back @@ -51,7 +51,7 @@ def numel(x, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "uint16")}, + {"2.6.0 and below": ("float32", "float64", "uint16")}, "paddle", ) @to_ivy_arrays_and_back @@ -64,7 +64,7 @@ def std(x, axis=None, unbiased=True, keepdim=False, name=None): return ivy.std(x, axis=axis, correction=int(unbiased), keepdims=keepdim) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def var(x, axis=None, unbiased=True, keepdim=False, name=None): if unbiased: diff --git a/ivy/functional/frontends/paddle/tensor/manipulation.py b/ivy/functional/frontends/paddle/tensor/manipulation.py index 5300c5ba213d9..c83bdaaf96101 100644 --- a/ivy/functional/frontends/paddle/tensor/manipulation.py +++ b/ivy/functional/frontends/paddle/tensor/manipulation.py @@ -6,17 +6,49 @@ ) from ivy.func_wrapper import with_unsupported_dtypes + +@with_supported_dtypes( + {"2.5.1 and below": ("bool", "int32", "int64", "float16", "float32", "float64")}, + "paddle", +) +@to_ivy_arrays_and_back +def index_add_(x, index, axis, value, *, name=None): + x = ivy.swapaxes(x, axis, 0) + value = ivy.swapaxes(value, axis, 0) + _to_adds = [] + index = sorted(zip(ivy.to_list(index), range(len(index))), key=(lambda i: i[0])) + while index: + _curr_idx = index[0][0] + while len(_to_adds) < _curr_idx: + _to_adds.append(ivy.zeros_like(value[0])) + _to_add_cum = ivy.get_item(value, index[0][1]) + while (len(index)) > 1 and (index[0][0] == index[1][0]): + _to_add_cum = _to_add_cum + ivy.get_item(value, index.pop(1)[1]) + index.pop(0) + _to_adds.append(_to_add_cum) + while len(_to_adds) < x.shape[0]: + _to_adds.append(ivy.zeros_like(value[0])) + _to_adds = ivy.stack(_to_adds) + if len(x.shape) < 2: + # Added this line due to the paddle backend treating scalars as 1-d arrays + _to_adds = ivy.flatten(_to_adds) + + ret = ivy.add(x, _to_adds) + ret = ivy.swapaxes(ret, axis, 0) + x = ret + return x + + # NOTE: # Only inplace functions are to be added in this file. # Please add non-inplace counterparts to `/frontends/paddle/manipulation.py`. @with_unsupported_dtypes( - {"2.5.2 and below": ("int8", "uint8", "int16", "uint16", "float16", "bfloat16")}, + {"2.6.0 and below": ("int8", "uint8", "int16", "uint16", "float16", "bfloat16")}, "paddle", ) @to_ivy_arrays_and_back def reshape_(x, shape): - ret = ivy.reshape(x, shape) - ivy.inplace_update(x, ret) + ivy.reshape(x, shape) return x diff --git a/ivy/functional/frontends/paddle/tensor/math.py b/ivy/functional/frontends/paddle/tensor/math.py index ceb36b11d7310..6332b1636a37d 100644 --- a/ivy/functional/frontends/paddle/tensor/math.py +++ b/ivy/functional/frontends/paddle/tensor/math.py @@ -9,14 +9,14 @@ # Please add non-inplace counterparts to `/frontends/paddle/math.py`. -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def ceil_(x, name=None): return ivy.ceil(x, out=x) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def clip_(x, min=None, max=None, name=None): @@ -38,54 +38,54 @@ def clip_(x, min=None, max=None, name=None): return res -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def exp_(x, name=None): return ivy.inplace_update(x, exp(x)) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def floor_(x, name=None): return ivy.inplace_update(x, floor(x)) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def lerp_(x, y, weight, name=None): return ivy.inplace_update(x, lerp(x, y, weight)) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def reciprocal_(x, name=None): return ivy.inplace_update(x, reciprocal(x)) -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def round_(x, name=None): return ivy.inplace_update(x, round(x)) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def rsqrt_(x, name=None): return ivy.inplace_update(x, reciprocal(sqrt(x))) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def sqrt_(x, name=None): return ivy.inplace_update(x, sqrt(x)) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def subtract_(x, y, name=None): return ivy.inplace_update(x, subtract(x, y)) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def tanh_(x, name=None): return ivy.inplace_update(x, tanh(x)) diff --git a/ivy/functional/frontends/paddle/tensor/random.py b/ivy/functional/frontends/paddle/tensor/random.py index dd6be26c2f4f2..31e370942c6ad 100644 --- a/ivy/functional/frontends/paddle/tensor/random.py +++ b/ivy/functional/frontends/paddle/tensor/random.py @@ -12,7 +12,7 @@ @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back @@ -21,7 +21,7 @@ def exponential_(x, lam=1.0, name=None): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64")}, + {"2.6.0 and below": ("float32", "float64")}, "paddle", ) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/paddle/tensor/tensor.py b/ivy/functional/frontends/paddle/tensor/tensor.py index 09d662d5b3dc6..51ba3eee9a1d7 100644 --- a/ivy/functional/frontends/paddle/tensor/tensor.py +++ b/ivy/functional/frontends/paddle/tensor/tensor.py @@ -62,28 +62,28 @@ def ivy_array(self, array): # -------------------# @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle", ) def __add__(self, y, /, name=None): return paddle_frontend.add(self, y) @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle", ) def __radd__(self, x, /, name=None): return paddle_frontend.add(self, x) @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle", ) def __sub__(self, y, /, name=None): return paddle_frontend.subtract(self, y) @with_unsupported_dtypes( - {"2.5.2 and below": ("uint8", "int8", "int16", "float16", "bfloat16")}, + {"2.6.0 and below": ("uint8", "int8", "int16", "float16", "bfloat16")}, "paddle", ) def __mul__(self, y, /, name=None): @@ -91,7 +91,7 @@ def __mul__(self, y, /, name=None): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -107,7 +107,7 @@ def __gt__(self, y, /, name=None): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -123,7 +123,7 @@ def __lt__(self, y, /, name=None): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -139,7 +139,7 @@ def __ge__(self, y, /, name=None): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -155,7 +155,7 @@ def __le__(self, y, /, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -170,7 +170,7 @@ def __or__(self, y, /, name=None): return paddle_frontend.logic.bitwise_or(self, y) @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle", ) def __rsub__(self, x, /, name=None): @@ -186,11 +186,11 @@ def __setitem__(self, item, value): "ivy.functional.frontends.paddle.Tensor object doesn't support assignment" ) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def __floordiv__(self, y, /, name=None): return paddle_frontend.floor_divide(self, y) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def __ne__(self, y, /, name=None): return paddle_frontend.not_equal(self, y) @@ -201,14 +201,14 @@ def __iter__(self): yield self[i] @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle", ) def __rmul__(self, y, /, name=None): return paddle_frontend.multiply(self, y) @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle", ) def __float__(self): @@ -227,14 +227,21 @@ def __neg__(self): return paddle_frontend.neg(self) @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle", ) def __rdiv__(self, y, /, name=None): return paddle_frontend.divide(y, self) @with_unsupported_dtypes( - {"2.5.2 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, + "paddle", + ) + def __rtruediv__(self, y, /, name=None): + return paddle_frontend.divide(y, self) + + @with_unsupported_dtypes( + {"2.6.0 and below": ("bool", "unsigned", "int8", "float16", "bfloat16")}, "paddle", ) def __int__(self): @@ -242,7 +249,7 @@ def __int__(self): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "unsigned", "int8", @@ -274,50 +281,73 @@ def reshape(self, *args, shape=None): else: raise ValueError("reshape() got no values for argument 'shape'") + def reshape_(self, *args, shape=None): + if args and shape: + raise TypeError("reshape() got multiple values for argument 'shape'") + if shape is not None: + self.ivy_array = paddle_frontend.reshape( + self._ivy_array, shape=shape + ).ivy_array + return self + if args: + if isinstance(args[0], (tuple, list)): + shape = args[0] + self.ivy_array = paddle_frontend.reshape( + self._ivy_array, shape=shape + ).ivy_array + return self + else: + self.ivy_array = paddle_frontend.reshape( + self._ivy_array, args + ).ivy_array + return self + else: + raise ValueError("reshape_() got no values for argument 'shape'") + def dim(self): return self.ivy_array.ndim - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def abs(self): return paddle_frontend.abs(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def acosh(self, name=None): return paddle_frontend.acosh(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def add_n(self, inputs, name=None): inputs = ivy.array(inputs) return ivy.sum(inputs, dtype=inputs.dtype, axis=0) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def ceil(self): return paddle_frontend.ceil(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def ceil_(self): self.ivy_array = self.ceil().ivy_array return self - @with_unsupported_dtypes({"2.5.2 and below": ("complex", "int8")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("complex", "int8")}, "paddle") def numel(self): return paddle_frontend.numel(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16",)}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16",)}, "paddle") def asinh(self, name=None): return paddle_frontend.asinh(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def asin(self, name=None): return paddle_frontend.asin(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def cosh(self, name=None): return paddle_frontend.cosh(self) @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "int32", "int64", "float64", @@ -332,101 +362,101 @@ def cosh(self, name=None): def diagonal(self, offset, axis1=0, axis2=1, name=None): return paddle_frontend.diagonal(self, offset=offset, axis1=axis1, axis2=axis2) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def log(self, name=None): return paddle_frontend.log(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def sin(self, name=None): return paddle_frontend.sin(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def sinh(self, name=None): return paddle_frontend.sinh(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def lerp(self, y, weight, name=None): return paddle_frontend.lerp(self, y, weight) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def lerp_(self, y, weight, name=None): self.ivy_array = paddle_frontend.lerp(self, y, weight).ivy_array return self - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def argmax(self, axis=None, keepdim=False, dtype=None, name=None): return paddle_frontend.argmax(self, axis=axis, keepdim=keepdim, dtype=dtype) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "uint16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "uint16")}, "paddle") def unsqueeze(self, axis=None, name=None): return paddle_frontend.Tensor(ivy.expand_dims(self._ivy_array, axis=axis)) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def sqrt(self, name=None): return paddle_frontend.sqrt(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def sqrt_(self, name=None): self.ivy_array = self.sqrt().ivy_array return self - @with_unsupported_dtypes({"2.5.2 and below": ("bfloat16", "uint16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("bfloat16", "uint16")}, "paddle") def zero_(self): self.ivy_array = paddle_frontend.zeros_like(self).ivy_array return self - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def cos(self, name=None): return paddle_frontend.cos(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def exp(self, name=None): return paddle_frontend.exp(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def exp_(self, name=None): self.ivy_array = self.exp().ivy_array return self - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def erf(self, name=None): return paddle_frontend.erf(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def subtract(self, y, name=None): return paddle_frontend.subtract(self, y) @with_unsupported_dtypes( - {"2.5.2 and below": ("float16", "uint8", "int8", "bool")}, "paddle" + {"2.6.0 and below": ("float16", "uint8", "int8", "bool")}, "paddle" ) def subtract_(self, y, name=None): self.ivy_array = self.subtract(y).ivy_array return self - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def log10(self, name=None): return paddle_frontend.Tensor(ivy.log10(self._ivy_array)) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def argsort(self, axis=-1, descending=False, name=None): return paddle_frontend.argsort(self, axis=axis, descending=descending) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def floor(self, name=None): return paddle_frontend.floor(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def floor_(self): self.ivy_array = self.floor().ivy_array return self - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def round_(self, name=None): self.ivy_array = paddle_frontend.round(self).ivy_array return self @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def clip(self, min=None, max=None, name=None): ivy.utils.assertions.check_all_or_any_fn( @@ -446,89 +476,106 @@ def clip(self, min=None, max=None, name=None): return paddle_frontend.Tensor(ret) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def clip_(self, min=None, max=None, name=None): self._ivy_array = self.clip(min, max).ivy_array return self - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def tanh(self, name=None): return paddle_frontend.tanh(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def add(self, y, name=None): return paddle_frontend.Tensor(ivy.add(self._ivy_array, _to_ivy_array(y))) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def add_(self, y, name=None): self.ivy_array = paddle_frontend.add(self, y).ivy_array return self - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def addmm(self, x, y, beta=1.0, alpha=1.0, name=None): return paddle_frontend.addmm(self, x, y, beta, alpha) @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle", ) def isinf(self, name=None): return paddle_frontend.isinf(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "uint16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "uint16")}, "paddle") def unsqueeze_(self, axis=None, name=None): self.ivy_array = self.unsqueeze(axis=axis).ivy_array return self - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def square(self, name=None): return paddle_frontend.square(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def remainder_(self, y, name=None): self.ivy_array = paddle_frontend.remainder(self, y).ivy_array return self - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def cholesky(self, upper=False, name=None): return paddle_frontend.cholesky(self, upper=upper) @with_unsupported_dtypes( - {"2.5.2 and below": ("float16", "uint16", "int16")}, "paddle" + {"2.6.0 and below": ("float16", "uint16", "int16")}, "paddle" + ) + def squeeze(self, axis=None, name=None): + if isinstance(axis, int) and self.ndim > 0: + if self.shape[axis] > 1: + return self + if len(self.shape) == 0: + return self + return paddle_frontend.squeeze(self, axis=axis) + + @with_unsupported_dtypes( + {"2.6.0 and below": ("float16", "uint16", "int16")}, "paddle" ) def squeeze_(self, axis=None, name=None): self.ivy_array = paddle_frontend.squeeze(self, axis=axis).ivy_array return self - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def multiply(self, y, name=None): return paddle_frontend.multiply(self, y) + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") + def matmul(self, y, transpose_x=False, transpose_y=False, name=None): + return paddle_frontend.matmul( + self, y, transpose_x=transpose_x, transpose_y=transpose_y + ) + @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle", ) def isfinite(self, name=None): return paddle_frontend.isfinite(self) @with_supported_dtypes({"2.4.2 and below": ("float16", "bfloat16")}, "paddle") - def all(self, axis=None, keepdim=False, dtype=None, name=None): + def all(self, axis=None, keepdim=False, name=None): return paddle_frontend.Tensor( - ivy.all(self.ivy_array, axis=axis, keepdims=keepdim, dtype=dtype) + ivy.all(self.ivy_array, axis=axis, keepdims=keepdim) ) - @with_supported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def allclose(self, other, rtol=1e-05, atol=1e-08, equal_nan=False, name=None): return paddle_frontend.allclose( self, other, rtol=rtol, atol=atol, equal_nan=equal_nan ) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def sort(self, axis=-1, descending=False, name=None): return paddle_frontend.sort(self, axis=axis, descending=descending) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def log1p(self, name=None): return paddle_frontend.log1p(self) @@ -550,7 +597,7 @@ def bitwise_and(self, y, out=None, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int8", "int16", @@ -566,22 +613,22 @@ def logical_or(self, y, out=None, name=None): return paddle_frontend.logical_or(self, y, out=out) @with_supported_dtypes( - {"2.5.2 and below": ("bool", "uint8", "int8", "int16", "int32", "int64")}, + {"2.6.0 and below": ("bool", "uint8", "int8", "int16", "int32", "int64")}, "paddle", ) def bitwise_xor(self, y, out=None, name=None): return paddle_frontend.bitwise_xor(self, y) - @with_supported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def any(self, axis=None, keepdim=False, name=None): return paddle_frontend.any(self, axis=axis, keepdim=keepdim) - @with_unsupported_dtypes({"2.5.2 and below": "bfloat16"}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": "bfloat16"}, "paddle") def astype(self, dtype): return paddle_frontend.Tensor(ivy.astype(self._ivy_array, dtype)) @with_supported_dtypes( - {"2.5.2 and below": ("bool", "uint8", "int8", "int16", "int32", "int64")}, + {"2.6.0 and below": ("bool", "uint8", "int8", "int16", "int32", "int64")}, "paddle", ) def bitwise_not(self, out=None, name=None): @@ -589,7 +636,7 @@ def bitwise_not(self, out=None, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int8", "int16", @@ -604,7 +651,7 @@ def bitwise_or(self, y, out=None, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int8", "int16", @@ -620,7 +667,7 @@ def logical_xor(self, y, out=None, name=None): return paddle_frontend.logical_xor(self, y, out=out) @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle", ) def isnan(self, name=None): @@ -628,7 +675,7 @@ def isnan(self, name=None): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -642,22 +689,22 @@ def isnan(self, name=None): def greater_than(self, y, name=None): return paddle_frontend.greater_than(self, y) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def rsqrt(self, name=None): return paddle_frontend.rsqrt(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def rsqrt_(self, name=None): self.ivy_array = self.rsqrt().ivy_array return self - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def reciprocal(self, name=None): return paddle_frontend.reciprocal(self) @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int8", "int16", @@ -672,12 +719,12 @@ def reciprocal(self, name=None): def logical_and(self, y, out=None, name=None): return paddle_frontend.logical_and(self, y, out=out) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def divide(self, y, name=None): return paddle_frontend.divide(self, y) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "complex64", "complex128")}, + {"2.6.0 and below": ("float32", "float64", "complex64", "complex128")}, "paddle", ) def eigvals(self, name=None): @@ -685,7 +732,7 @@ def eigvals(self, name=None): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "uint8", "int8", @@ -699,18 +746,18 @@ def eigvals(self, name=None): def less_than(self, y, name=None): return paddle_frontend.less_than(self, y) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def cumprod(self, dim=None, dtype=None, name=None): return paddle_frontend.cumprod(self, dim=dim, dtype=dtype) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def cumsum(self, axis=None, dtype=None, name=None): return paddle_frontend.Tensor( ivy.cumsum(self._ivy_array, axis=axis, dtype=dtype) ) @with_supported_dtypes( - {"2.5.2 and below": ("complex64", "complex128", "float32", "float64")}, + {"2.6.0 and below": ("complex64", "complex128", "float32", "float64")}, "paddle", ) def angle(self, name=None): @@ -718,7 +765,7 @@ def angle(self, name=None): @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "uint8", "int8", "int16", @@ -731,13 +778,13 @@ def angle(self, name=None): def equal(self, y, name=None): return paddle_frontend.equal(self, y) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def rad2deg(self, name=None): return paddle_frontend.rad2deg(self) @with_unsupported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "uint8", "int8", "int16", @@ -751,46 +798,46 @@ def rad2deg(self, name=None): def equal_all(self, y, name=None): return paddle_frontend.equal_all(self, y) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def maximum(self, other, name=None): return paddle_frontend.maximum(self, other) - @with_unsupported_dtypes({"2.5.2 and below": "bfloat16"}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": "bfloat16"}, "paddle") def fmax(self, y, name=None): return paddle_frontend.fmax(self, y) - @with_unsupported_dtypes({"2.5.2 and below": "bfloat16"}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": "bfloat16"}, "paddle") def fmin(self, y, name=None): return paddle_frontend.fmin(self, y) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def minimum(self, y, name=None): return paddle_frontend.minimum(self, y) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def max(self, axis=None, keepdim=False, name=None): return paddle_frontend.max(self, axis=axis, keepdim=keepdim) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def deg2rad(self, name=None): return paddle_frontend.deg2rad(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def digamma(self, name=None): return paddle_frontend.digamma(self) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64", "bool")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64", "bool")}, "paddle" ) def rot90(self, k=1, axes=(0, 1), name=None): return paddle_frontend.rot90(self, k=k, axes=axes) @with_supported_dtypes( - {"2.5.2 and below": ("complex64", "complex128")}, + {"2.6.0 and below": ("complex64", "complex128")}, "paddle", ) def imag(self, name=None): @@ -801,7 +848,7 @@ def is_tensor(self): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "float32", "float64", ) @@ -813,22 +860,22 @@ def isclose(self, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None): self, y, rtol=rtol, atol=atol, equal_nan=equal_nan ) - @with_supported_dtypes({"2.5.2 and below": ("int32", "int64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("int32", "int64")}, "paddle") def floor_divide(self, y, name=None): return paddle_frontend.floor_divide(self, y) - @with_supported_dtypes({"2.5.2 and below": ("int32", "int64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("int32", "int64")}, "paddle") def mod(self, y, name=None): return paddle_frontend.Tensor(ivy.fmod(self._ivy_array, _to_ivy_array(y))) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def floor_mod(self, y, name=None): return paddle_frontend.remainder(self, y) # cond - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def cond(self, p=None, name=None): return paddle_frontend.cond(self, p=p, name=name) @@ -836,7 +883,7 @@ def cond(self, p=None, name=None): def conj(self, name=None): return paddle_frontend.conj(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def log2(self, name=None): return paddle_frontend.log2(self) @@ -848,7 +895,7 @@ def neg(self, name=None): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int8", "int16", @@ -863,15 +910,15 @@ def neg(self, name=None): def logical_not(self, out=None, name=None): return paddle_frontend.logical_not(self) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def sign(self, name=None): return paddle_frontend.sign(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def var(self, axis=None, unbiased=True, keepdim=False, name=None): return paddle_frontend.var(self, axis=axis, unbiased=unbiased, keepdim=keepdim) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def sgn(self, name=None): return paddle_frontend.sgn(self) @@ -879,45 +926,45 @@ def tolist(self): return paddle_frontend.Tensor(ivy.to_list(self._ivy_array)) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle", ) def min(self, axis=None, keepdim=False, name=None): return paddle_frontend.min(self, axis=axis, keepdim=keepdim) @with_supported_dtypes( - {"2.5.2 and below": ("int32", "int64", "float32", "float64")}, "paddle" + {"2.6.0 and below": ("int32", "int64", "float32", "float64")}, "paddle" ) def pow(self, y, name=None): return paddle_frontend.pow(self, y) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def prod(self, axis=None, keepdim=False, dtype=None, name=None): return paddle_frontend.Tensor( ivy.prod(self._ivy_array, axis=axis, keepdims=keepdim, dtype=dtype) ) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def atan(self, name=None): return paddle_frontend.atan(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def atanh(self, name=None): return paddle_frontend.atanh(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def std(self, axis=None, unbiased=True, keepdim=False, name=None): return paddle_frontend.std(self, axis=axis, unbiased=unbiased, keepdim=keepdim) @with_supported_dtypes( - {"2.5.2 and below": ("int32", "int64", "float32", "float64")}, "paddle" + {"2.6.0 and below": ("int32", "int64", "float32", "float64")}, "paddle" ) def trunc(self, name=None): return paddle_frontend.trunc(self) - @with_supported_dtypes({"2.5.2 and below": ("complex64", "complex128")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("complex64", "complex128")}, "paddle") def as_real(self, name=None): if not ivy.is_complex_dtype(self._ivy_array): raise ivy.exceptions.IvyError( @@ -927,21 +974,55 @@ def as_real(self, name=None): im_part = ivy.imag(self._ivy_array) return paddle_frontend.Tensor(ivy.stack((re_part, im_part), axis=-1)) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def stanh(self, scale_a=0.67, scale_b=1.7159, name=None): return paddle_frontend.stanh(self, scale_a=scale_a, scale_b=scale_b) @with_supported_dtypes( - {"2.5.2 and below": ("int32", "int64", "float32", "float64")}, "paddle" + {"2.6.0 and below": ("int32", "int64", "float32", "float64")}, "paddle" ) def trace(self, offset=0, axis1=0, axis2=1, name=None): return paddle_frontend.Tensor( ivy.trace(self._ivy_array, offset=offset, axis1=axis1, axis2=axis2) ) + @with_supported_dtypes({"2.6.0 and below": ("float64", "float32")}, "paddle") + def cov(self, rowvar=True, ddof=True, fweights=None, aweights=None): + return paddle_frontend.Tensor( + ivy.cov( + self._ivy_array, + rowVar=rowvar, + ddof=int(ddof), + fweights=fweights, + aweights=aweights, + ) + ) + + @with_supported_dtypes( + { + "2.6.0 and below": ( + "bfloat16", + "float32", + "float64", + "int8", + "int16", + "int32", + "int64", + "uint8", + ) + }, + "paddle", + ) + def flatten(self, start_axis=0, stop_axis=-1, name=None): + if len(self.shape) == 0: + return self.unsqueeze(axis=0) + return paddle_frontend.Tensor( + ivy.flatten(self.ivy_array, start_dim=start_axis, end_dim=stop_axis) + ) + @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "float32", "float64", "int16", @@ -956,52 +1037,52 @@ def argmin(self, axis=None, keepdim=False, dtype=None, name=None): return paddle_frontend.argmin(self, axis=axis, keepdim=keepdim, dtype=dtype) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle", ) def topk(self, k, axis=None, largest=True, sorted=True, name=None): return paddle_frontend.topk(self, k, axis=axis, largest=largest, sorted=sorted) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def remainder(self, y, name=None): return paddle_frontend.remainder(self, y) def is_floating_point(self): return paddle_frontend.is_floating_point(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def tanh_(self, name=None): y = self.tanh(self) return ivy.inplace_update(self, y) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def reciprocal_(self, name=None): y = self.reciprocal(self) return ivy.inplace_update(self, y) @with_unsupported_dtypes( - {"2.5.2 and below": ("complex", "uint8", "uint16")}, "paddle" + {"2.6.0 and below": ("complex", "uint8", "uint16")}, "paddle" ) def numpy(self): return self.ivy_array.to_numpy() - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def nonzero(self): return paddle_frontend.nonzero(self) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def inner(self, y, name=None): return paddle_frontend.inner(self, y, name) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def acos(self, name=None): return paddle_frontend.Tensor(ivy.acos(self._ivy_array)) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def mean(self, axis=None, keepdim=False, name=None): return paddle_frontend.mean(self, axis=axis, keepdim=keepdim) - @with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") def as_complex(self, name=None): if self.ivy_array.shape[-1] != 2: raise ivy.exceptions.IvyError( @@ -1016,29 +1097,29 @@ def as_complex(self, name=None): return value @with_supported_dtypes( - {"2.5.2 and below": ("int32", "int64", "float32", "float64", "bool")}, "paddle" + {"2.6.0 and below": ("int32", "int64", "float32", "float64", "bool")}, "paddle" ) def not_equal(self, y, name=None): return paddle_frontend.not_equal(self._ivy_array, y) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def less_equal(self, y, name=None): return paddle_frontend.less_equal(self._ivy_array, y) - @with_supported_dtypes({"2.5.2 and below": ("complex64", "complex128")}, "paddle") + @with_supported_dtypes({"2.6.0 and below": ("complex64", "complex128")}, "paddle") def real(self, name=None): return paddle_frontend.real(self._ivy_array) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def t(self, name=None): axes = list(range(len(self.ivy_array.shape)))[::-1] return ivy.permute_dims(self.ivy_array, axes=axes) @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "float16", "float32", @@ -1053,12 +1134,12 @@ def t(self, name=None): def cast(self, dtype): return paddle_frontend.cast(self, dtype) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def bmm(self, y, transpose_x=False, transpose_y=False, name=None): return paddle_frontend.bmm(self, y, transpose_x, transpose_y) @with_supported_dtypes( - {"2.5.2 and below": ("float16", "float32", "float64", "int32", "int64")}, + {"2.6.0 and below": ("float16", "float32", "float64", "int32", "int64")}, "paddle", ) def fill_(self, value): @@ -1067,7 +1148,7 @@ def fill_(self, value): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int32", "int64", @@ -1083,7 +1164,7 @@ def unbind(self, axis=0): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "int32", "int64", @@ -1102,19 +1183,19 @@ def cpu(self): return self @with_unsupported_dtypes( - {"2.5.2 and below": ("int16", "complex64", "complex128")}, + {"2.6.0 and below": ("int16", "complex64", "complex128")}, "paddle", ) def split(self, num_or_sections, axis=0, name=None): return paddle_frontend.split(self._ivy_array, num_or_sections, axis, name) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def frac(self, name=None): return paddle_frontend.frac(self._ivy_array) - @with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") + @with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def gather(self, y, name=None): return paddle_frontend.gather(self, y) @@ -1122,27 +1203,27 @@ def is_complex(self): return paddle_frontend.is_complex(self) @with_unsupported_dtypes( - {"2.5.2 and below": ("float16", "uint8", "int8", "bool")}, "paddle" + {"2.6.0 and below": ("float16", "uint8", "int8", "bool")}, "paddle" ) def gather_(self, y, name=None): res = self.gather(self, y) return ivy.inplace_update(self, res) @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def heaviside(self, y, name=None): return paddle_frontend.heaviside(self, y) @with_supported_dtypes( - {"2.5.2 and below": ("bool", "int32", "int64", "float32", "float64")}, "paddle" + {"2.6.0 and below": ("bool", "int32", "int64", "float32", "float64")}, "paddle" ) def expand(self, shape, name=None): return paddle_frontend.expand(self._ivy_array, shape) @with_supported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ( "bool", "int32", @@ -1161,7 +1242,7 @@ def tile(self, repeat_times): @with_supported_dtypes( { - "2.5.2 and below": ( + "2.6.0 and below": ( "bool", "float16", "float32", diff --git a/ivy/functional/frontends/paddle/vision/transforms.py b/ivy/functional/frontends/paddle/vision/transforms.py index dac89b602ea19..c2ff2af63c3ce 100644 --- a/ivy/functional/frontends/paddle/vision/transforms.py +++ b/ivy/functional/frontends/paddle/vision/transforms.py @@ -104,7 +104,7 @@ def _rgb_to_hsv(img): # ------------ # -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64")}, "paddle") @to_ivy_arrays_and_back def adjust_brightness(img, brightness_factor): assert brightness_factor >= 0, "brightness_factor should be non-negative." @@ -117,7 +117,7 @@ def adjust_brightness(img, brightness_factor): return _blend_images(img, extreme_target, brightness_factor) -@with_supported_dtypes({"2.5.2 and below": ("float32", "float64", "uint8")}, "paddle") +@with_supported_dtypes({"2.6.0 and below": ("float32", "float64", "uint8")}, "paddle") @to_ivy_arrays_and_back def adjust_hue(img, hue_factor): assert -0.5 <= hue_factor <= 0.5, "hue_factor should be in range [-0.5, 0.5]" @@ -145,7 +145,7 @@ def adjust_hue(img, hue_factor): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def hflip(img): @@ -154,7 +154,7 @@ def hflip(img): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) def normalize(img, mean, std, data_format="CHW", to_rgb=False): if ivy.is_array(img): @@ -171,7 +171,7 @@ def normalize(img, mean, std, data_format="CHW", to_rgb=False): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def pad(img, padding, fill=0, padding_mode="constant"): @@ -201,7 +201,7 @@ def pad(img, padding, fill=0, padding_mode="constant"): @with_supported_dtypes( - {"2.5.2 and below": ("float32", "float64", "int32", "int64")}, "paddle" + {"2.6.0 and below": ("float32", "float64", "int32", "int64")}, "paddle" ) @to_ivy_arrays_and_back def to_tensor(pic, data_format="CHW"): @@ -211,7 +211,7 @@ def to_tensor(pic, data_format="CHW"): @with_unsupported_device_and_dtypes( { - "2.5.2 and below": { + "2.6.0 and below": { "cpu": ("int8", "uint8", "int16", "float16", "bfloat16", "bool") } }, diff --git a/ivy/functional/frontends/scipy/fft/fft.py b/ivy/functional/frontends/scipy/fft/fft.py index 163589eac0f3d..4b9c9a1dbbbd8 100644 --- a/ivy/functional/frontends/scipy/fft/fft.py +++ b/ivy/functional/frontends/scipy/fft/fft.py @@ -38,7 +38,7 @@ def ifft(x, n=None, axis=-1, norm=None, overwrite_x=False): def ifftn( x, s=None, axes=None, norm=None, overwrite_x=False, workers=None, *, plan=None ): - return ivy.ifftn(x, s=s, dim=axes, norm=norm) + return ivy.ifftn(x, s=s, axes=axes, norm=norm) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/sklearn/model_selection/_split.py b/ivy/functional/frontends/sklearn/model_selection/_split.py index ec6dc3d067f1e..1f14400186012 100644 --- a/ivy/functional/frontends/sklearn/model_selection/_split.py +++ b/ivy/functional/frontends/sklearn/model_selection/_split.py @@ -77,7 +77,7 @@ def _iter_test_indices(self, X=None, y=None, groups=None): ivy.seed(seed_value=self.random_state) y = ivy.array(y) y = column_or_1d(y) - _, y_idx, y_inv, _ = ivy.unique_all(y, return_index=True, return_inverse=True) + _, y_idx, y_inv, _ = ivy.unique_all(y) class_perm = ivy.unique_inverse(y_idx) y_encoded = class_perm[y_inv] diff --git a/ivy/functional/frontends/sklearn/tree/_classes.py b/ivy/functional/frontends/sklearn/tree/_classes.py index acc2702bd8c64..6cfbe791630ef 100644 --- a/ivy/functional/frontends/sklearn/tree/_classes.py +++ b/ivy/functional/frontends/sklearn/tree/_classes.py @@ -57,6 +57,7 @@ def _fit( check_input=True, missing_values_in_feature_mask=None, ): + ivy.seed(seed_value=self.random_state) n_samples, self.n_features_in_ = X.shape y = ivy.atleast_1d(y) if y.ndim == 1: @@ -146,6 +147,7 @@ def _prune_tree(self): self.tree_ = pruned_tree def predict(self, X, check_input=True): + ivy.seed(seed_value=self.random_state) proba = self.tree_.predict(X) n_samples = X.shape[0] diff --git a/ivy/functional/frontends/tensorflow/__init__.py b/ivy/functional/frontends/tensorflow/__init__.py index fb8077c3672b7..9c1d731b8a586 100644 --- a/ivy/functional/frontends/tensorflow/__init__.py +++ b/ivy/functional/frontends/tensorflow/__init__.py @@ -74,6 +74,9 @@ def check_tensorflow_casting(x1, x2): if hasattr(x1, "dtype") and not hasattr(x2, "dtype"): x1 = ivy.asarray(x1) x2 = ivy.asarray(x2, dtype=x1.dtype) + elif hasattr(x2, "dtype") and not hasattr(x1, "dtype"): + x2 = ivy.asarray(x2) + x1 = ivy.asarray(x1, dtype=x2.dtype) else: x1 = ivy.asarray(x1) if not hasattr(x2, "dtype"): @@ -100,6 +103,7 @@ def check_tensorflow_casting(x1, x2): from .math import * from . import nest from . import nn +from . import __operators__ from . import quantization from . import random from . import general_functions diff --git a/ivy/functional/frontends/tensorflow/__operators__.py b/ivy/functional/frontends/tensorflow/__operators__.py new file mode 100644 index 0000000000000..7945e8f863764 --- /dev/null +++ b/ivy/functional/frontends/tensorflow/__operators__.py @@ -0,0 +1,5 @@ +import ivy.functional.frontends.tensorflow as tf_frontend + + +def add(x, y, name=None): + return tf_frontend.math.add(x, y, name=name) diff --git a/ivy/functional/frontends/tensorflow/general_functions.py b/ivy/functional/frontends/tensorflow/general_functions.py index 322becf12c4b4..cc98ef66453e8 100644 --- a/ivy/functional/frontends/tensorflow/general_functions.py +++ b/ivy/functional/frontends/tensorflow/general_functions.py @@ -212,7 +212,7 @@ def foldl( return result -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") @to_ivy_arrays_and_back def foldr( fn, diff --git a/ivy/functional/frontends/tensorflow/keras/__init__.py b/ivy/functional/frontends/tensorflow/keras/__init__.py index 0d11e115ad78c..052c66a399130 100644 --- a/ivy/functional/frontends/tensorflow/keras/__init__.py +++ b/ivy/functional/frontends/tensorflow/keras/__init__.py @@ -1,4 +1,5 @@ from . import activations +from . import backend from . import layers from . import metrics from . import regularizers diff --git a/ivy/functional/frontends/tensorflow/keras/activations.py b/ivy/functional/frontends/tensorflow/keras/activations.py index 9abc0a84825ad..1bbffa3d5f375 100644 --- a/ivy/functional/frontends/tensorflow/keras/activations.py +++ b/ivy/functional/frontends/tensorflow/keras/activations.py @@ -16,6 +16,21 @@ ] +# --- Helpers --- # +# --------------- # + + +# note: defined to avoid AST call extraction of +# 'tf_frontend.keras.activations.__dict__.items() +# or 'tf_frontend.keras.activations.__dict__.values()' +def _get_tf_keras_activations(): + return tf_frontend.keras.activations.__dict__.items() + + +# --- Main --- # +# ------------ # + + @with_supported_dtypes( {"2.15.0 and below": ("float16", "float32", "float64")}, "tensorflow", @@ -132,13 +147,15 @@ def serialize(activation, use_legacy_format=False, custom_objects=None): if custom_func == activation: return name + tf_keras_frontend_activations = _get_tf_keras_activations() + # Check if the function is in the ACTIVATION_FUNCTIONS list if activation.__name__ in ACTIVATION_FUNCTIONS: return activation.__name__ # Check if the function is in the TensorFlow frontend activations - elif activation in tf_frontend.keras.activations.__dict__.values(): - for name, tf_func in tf_frontend.keras.activations.__dict__.items(): + elif activation in [fn for name, fn in tf_keras_frontend_activations]: + for name, tf_func in tf_keras_frontend_activations: if tf_func == activation: return name diff --git a/ivy/functional/frontends/tensorflow/keras/backend.py b/ivy/functional/frontends/tensorflow/keras/backend.py new file mode 100644 index 0000000000000..6c29237ef6b5e --- /dev/null +++ b/ivy/functional/frontends/tensorflow/keras/backend.py @@ -0,0 +1,118 @@ +import functools +import ivy +import ivy.functional.frontends.tensorflow as tf_frontend +from ivy.functional.frontends.tensorflow.func_wrapper import ( + _ivy_array_to_tensorflow, + _to_ivy_array, + to_ivy_arrays_and_back, +) + + +def bias_add(x, bias, data_format=None): + if data_format is None: + data_format = "channels_last" + bias_shape = bias.shape + if len(bias_shape) == 1: + if data_format == "channels_first": + return tf_frontend.nn.bias_add(x, bias, data_format="NC...") + return tf_frontend.nn.bias_add(x, bias, data_format="N...C") + if x.ndim in (3, 4, 5): + if data_format == "channels_first": + bias_reshape_axis = (1, bias_shape[-1]) + bias_shape[:-1] + return x + tf_frontend.reshape(bias, bias_reshape_axis) + return x + tf_frontend.reshape(bias, (1,) + bias_shape) + return tf_frontend.nn.bias_add(x, bias) + + +@to_ivy_arrays_and_back +def depthwise_conv2d( + x, + depthwise_kernel, + strides=(1, 1), + padding="valid", + data_format=None, + dilation_rate=(1, 1), +): + data_format = "channels_last" if data_format is None else data_format + if data_format not in {"channels_first", "channels_last"}: + raise ValueError("Unknown data_format: " + str(data_format)) + + tf_data_format = "NHWC" + permuted_x = False + if data_format == "channels_first": + if ivy.dev(x) == "cpu": + x = tf_frontend.transpose(x, (0, 2, 3, 1)) # NCHW -> NHWC + permuted_x = True + else: + tf_data_format = "NCHW" + + padding = padding.upper() + if padding not in {"VALID", "SAME"}: + raise ValueError("Unknown padding: " + str(padding)) + + if tf_data_format == "NHWC": + strides = (1,) + strides + (1,) + else: + strides = (1, 1) + strides + + x = tf_frontend.nn.depthwise_conv2d( + x, + depthwise_kernel, + strides=strides, + padding=padding, + dilations=dilation_rate, + data_format=tf_data_format, + ) + + if permuted_x: + x = tf_frontend.transpose(x, (0, 3, 1, 2)) # NHWC -> NCHW + return x + + +@to_ivy_arrays_and_back +def dot(x, y): + return ivy.dot(x, y) + + +def mean(x, axis=None, keepdims=False): + return tf_frontend.reduce_mean(x, axis, keepdims) + + +@to_ivy_arrays_and_back +def rnn( + step_function, + inputs, + initial_states, + go_backwards=False, + mask=None, + constants=None, + unroll=False, + input_length=None, + time_major=False, + zero_output_for_mask=False, + return_all_outputs=True, +): + @functools.wraps(step_function) + def _new_step_function(*args, **kwargs): + frontend_args = ivy.nested_map( + _ivy_array_to_tensorflow, args, include_derived=True, shallow=False + ) + frontend_kwargs = ivy.nested_map( + _ivy_array_to_tensorflow, kwargs, include_derived=True, shallow=False + ) + ret = step_function(*frontend_args, **frontend_kwargs) + return ivy.nested_map(_to_ivy_array, ret, include_derived=True) + + return ivy.rnn( + _new_step_function, + inputs, + initial_states, + go_backwards=go_backwards, + mask=mask, + constants=constants, + unroll=unroll, + input_length=input_length, + time_major=time_major, + zero_output_for_mask=zero_output_for_mask, + return_all_outputs=return_all_outputs, + ) diff --git a/ivy/functional/frontends/tensorflow/math.py b/ivy/functional/frontends/tensorflow/math.py index d0d974b5b6f36..ab281931c99ee 100644 --- a/ivy/functional/frontends/tensorflow/math.py +++ b/ivy/functional/frontends/tensorflow/math.py @@ -13,6 +13,138 @@ ) +# --- Helpers --- # +# --------------- # + + +def _chbevl(x, coef, N): + """Evaluates the series. + + N-1 + - ' + y = > coef[i] T (x/2) + - i + i=0 + + of Chebyshev polynomials Ti at argument x/2. + + Coefficients are stored in reverse order, i.e. the zero + order term is last in the array. Note N is the number of + coefficients, not the order. + + If coefficients are for the interval a to b, x must + have been transformed to x -> 2(2x - b - a)/(b-a) before + entering the routine. This maps x from (a, b) to (-1, 1), + over which the Chebyshev polynomials are defined. + + If the coefficients are for the inverted interval, in + which (a, b) is mapped to (1/b, 1/a), the transformation + required is x -> 2(2ab/x - b - a)/(b-a). If b is infinity, + this becomes x -> 4a/x - 1. + """ + b0 = coef[0:1] + b1 = ivy.zeros_like(x) + i = N - 1 + p = 1 + + while i > 0: + b2 = b1 + b1 = b0 + with ivy.PreciseMode(True): + b0 = x * b1 - b2 + coef[p : p + 1] + p += 1 + i -= 1 + + return 0.5 * (b0 - b2) + + +def _get_chebyshev_coefficients_for_exp_i1(): + """Chebyshev coefficients for exp(-x) I1(x) / x in the interval [0,8]. + + lim(x->0){ exp(-x) I1(x) / x } = 1/2. + + Returns list of 29 float elements + ------- + """ + return ivy.array( + [ + 2.77791411276104639959e-18, + -2.11142121435816608115e-17, + 1.55363195773620046921e-16, + -1.10559694773538630805e-15, + 7.60068429473540693410e-15, + -5.04218550472791168711e-14, + 3.22379336594557470981e-13, + -1.98397439776494371520e-12, + 1.17361862988909016308e-11, + -6.66348972350202774223e-11, + 3.62559028155211703701e-10, + -1.88724975172282928790e-9, + 9.38153738649577178388e-9, + -4.44505912879632808065e-8, + 2.00329475355213526229e-7, + -8.56872026469545474066e-7, + 3.47025130813767847674e-6, + -1.32731636560394358279e-5, + 4.78156510755005422638e-5, + -1.61760815825896745588e-4, + 5.12285956168575772895e-4, + -1.51357245063125314899e-3, + 4.15642294431288815669e-3, + -1.05640848946261981558e-2, + 2.47264490306265168283e-2, + -5.29459812080949914269e-2, + 1.02643658689847095384e-1, + -1.76416518357834055153e-1, + 2.52587186443633654823e-1, + ] + ) + + +def _get_chebyshev_coefficients_for_exp_sqrt_i1(): + """Chebyshev coefficients for exp(-x) sqrt(x) I1(x) in the inverted + interval [8,infinity]. + + lim(x->inf){ exp(-x) sqrt(x) I1(x) } = 1/sqrt(2pi). + + Returns a list of 25 elements containing float + ------- + """ + return ivy.array( + [ + 7.51729631084210481353e-18, + 4.41434832307170791151e-18, + -4.65030536848935832153e-17, + -3.20952592199342395980e-17, + 2.96262899764595013876e-16, + 3.30820231092092828324e-16, + -1.88035477551078244854e-15, + -3.81440307243700780478e-15, + 1.04202769841288027642e-14, + 4.27244001671195135429e-14, + -2.10154184277266431302e-14, + -4.08355111109219731823e-13, + -7.19855177624590851209e-13, + 2.03562854414708950722e-12, + 1.41258074366137813316e-11, + 3.25260358301548823856e-11, + -1.89749581235054123450e-11, + -5.58974346219658380687e-10, + -3.83538038596423702205e-9, + -2.63146884688951950684e-8, + -2.51223623787020892529e-7, + -3.88256480887769039346e-6, + -1.10588938762623716291e-4, + -9.76109749136146840777e-3, + 7.78576235018280120474e-1, + ] + ) + + +# --- Main --- # +# ------------ # + + @with_unsupported_dtypes( { "1.2.0": ("float16", "complex64", "complex128"), @@ -61,15 +193,23 @@ def angle(input, name=None): return ivy.angle(input) +@with_unsupported_dtypes( + {"2.15.0 and below": ("complex",)}, + "tensorflow", +) @to_ivy_arrays_and_back def argmax(input, axis, output_type=None, name=None): output_type = to_ivy_dtype(output_type) - if output_type in ["uint16", "int16", "int32", "int64"]: + if output_type in ["int32", "int64"]: return ivy.astype(ivy.argmax(input, axis=axis), output_type) else: return ivy.astype(ivy.argmax(input, axis=axis), "int64") +@with_unsupported_dtypes( + {"2.15.0 and below": ("complex",)}, + "tensorflow", +) @to_ivy_arrays_and_back def argmin(input, axis=None, output_type="int64", name=None): output_type = to_ivy_dtype(output_type) @@ -104,6 +244,41 @@ def atanh(x, name="atanh"): return ivy.atanh(x) +@with_supported_dtypes( + {"2.15.0 and below": ("float16", "float32", "float64")}, "tensorflow" +) +@to_ivy_arrays_and_back +def bessel_i1(x, name=None): + z = ivy.abs(x) + result = ivy.zeros_like(z) + + mask1 = z <= 8.0 + + if ivy.any(mask1) > 0: + y = (z[mask1] / ivy.array([2.0])) - ivy.array([2.0]) + result[mask1] = ( + _chbevl(y, _get_chebyshev_coefficients_for_exp_i1(), 29) + * z[mask1] + * ivy.exp(z[mask1]) + ) + + mask2 = ~mask1 + if ivy.any(mask2) > 0: + result[mask2] = ( + ivy.exp(z[mask2]) + * _chbevl( + ivy.array([32.0]) / z[mask2] - ivy.array([2.0]), + _get_chebyshev_coefficients_for_exp_sqrt_i1(), + 25, + ) + / ivy.sqrt(z[mask2]) + ) + + result[x < 0.0] = -result[x < 0.0] + + return result + + @with_supported_dtypes( {"2.15.0 and below": ("int32",)}, "tensorflow", @@ -369,9 +544,11 @@ def is_non_decreasing(x, name="is_non_decreasing"): def is_strictly_increasing(x, name="is_strictly_increasing"): if ivy.array(x).size < 2: return ivy.array(True) - if ivy.array(x).size == 2: - return ivy.array(x[0] < x[1]) - return ivy.all(ivy.less(x, ivy.roll(x, -1))) + x = ivy.flatten(x) + res = ivy.less(x, ivy.roll(x, -1)) + if res.size >= 2: + res[res.size - 1] = True # The last comparison must be set to true. + return ivy.all(res) @to_ivy_arrays_and_back @@ -449,12 +626,13 @@ def maximum(x, y, name=None): @to_ivy_arrays_and_back +@with_unsupported_dtypes({"2.15.0 and below": ("complex",)}, "tensorflow") def minimum(x, y, name=None): return ivy.minimum(x, y) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.5.2 and below": ("bfloat16",)}, "paddle") +@with_unsupported_dtypes({"2.6.0 and below": ("bfloat16",)}, "paddle") def mod(x, y, name=None): x, y = check_tensorflow_casting(x, y) return ivy.remainder(x, y) diff --git a/ivy/functional/frontends/tensorflow/nn.py b/ivy/functional/frontends/tensorflow/nn.py index 7c473ff53e72e..7cc55e31428bb 100644 --- a/ivy/functional/frontends/tensorflow/nn.py +++ b/ivy/functional/frontends/tensorflow/nn.py @@ -127,8 +127,8 @@ def bias_add(value, bias, data_format=None, name=None): if data_format is None: data_format = "N...C" - chanel_index = data_format.find("C") - if chanel_index != 1: + channel_index = data_format.find("C") + if channel_index != 1: return ivy.add(value, bias) else: value = ivy.swapaxes(value, 1, -1) @@ -633,3 +633,6 @@ def weighted_moments(x, axes, frequency_weights, keepdims=False, name=None): weighted_mean = ivy.squeeze(weighted_mean, axis=axes) weighted_variance = ivy.squeeze(weighted_variance, axis=axes) return weighted_mean, weighted_variance + + +swish = silu diff --git a/ivy/functional/frontends/tensorflow/raw_ops.py b/ivy/functional/frontends/tensorflow/raw_ops.py index 50ea03ed0cd3d..61c87dcb5c76b 100644 --- a/ivy/functional/frontends/tensorflow/raw_ops.py +++ b/ivy/functional/frontends/tensorflow/raw_ops.py @@ -619,6 +619,15 @@ def Gather(*, params, indices, validate_indices=None, name="Gather"): return ivy.gather(params, indices, axis=0, batch_dims=0) +@with_supported_dtypes( + {"2.15.0 and below": ("int32", "int64", "float32", "float64")}, + "tensorflow", +) +@to_ivy_arrays_and_back +def GatherNd(*, params, indices, name=None): + return ivy.gather_nd(params, indices, batch_dims=0) + + @to_ivy_arrays_and_back def Greater(*, x, y, name="Greater"): x, y = check_tensorflow_casting(x, y) @@ -853,6 +862,39 @@ def Unpack(*, value, num, axis=0, name="Unpack"): return ivy.unstack(value, axis=axis)[:num] +@with_supported_dtypes( + { + "2.15.0 and below": ( + "int8", + "int16", + "int32", + "int64", + "float32", + "float64", + "complex64", + "complex128", + ) + }, + "tensorflow", +) +@to_ivy_arrays_and_back +def UnsortedSegmentProd(*, data, segment_ids, num_segments, name=None): + data = ivy.array(data) + segment_ids = ivy.array(segment_ids) + + ivy.utils.assertions.check_equal( + list(segment_ids.shape), [list(data.shape)[0]], as_array=False + ) + ivy.utils.assertions.check_greater(int(num_segments), int(ivy.max(segment_ids))) + + shape = list(ivy.shape(data)) + shape[0] = int(num_segments) + x = ivy.ones(shape, dtype=data.dtype) + for i in range((segment_ids).shape[0]): + x[segment_ids[i]] = ivy.multiply(x[segment_ids[i]], data[i]) + return x + + @to_ivy_arrays_and_back def Xdivy(*, x, y, name="Xdivy"): if (x == 0).all(): diff --git a/ivy/functional/frontends/tensorflow/variable.py b/ivy/functional/frontends/tensorflow/variable.py index bf6feeedde71d..e97034e4559f1 100644 --- a/ivy/functional/frontends/tensorflow/variable.py +++ b/ivy/functional/frontends/tensorflow/variable.py @@ -188,7 +188,7 @@ def __mul__(self, x, name="mul"): return tf_frontend.math.multiply(x, self._ivy_array, name=name) def __mod__(self, x, name="mod"): - return ivy.remainder(x, self._ivy_array, name=name) + return tf_frontend.math.mod(x, self._ivy_array, name=name) def __ne__(self, other): return tf_frontend.raw_ops.NotEqual( diff --git a/ivy/functional/frontends/torch/__init__.py b/ivy/functional/frontends/torch/__init__.py index d502cb7e90d50..e9f0986016442 100644 --- a/ivy/functional/frontends/torch/__init__.py +++ b/ivy/functional/frontends/torch/__init__.py @@ -210,8 +210,10 @@ def promote_types_torch( ret = torch_frontend.torch_promotion_table[ (ivy.as_ivy_dtype(type1), ivy.as_ivy_dtype(type2)) ] - except KeyError: - raise ivy.utils.exceptions.IvyException("these dtypes are not type promotable") + except KeyError as e: + raise ivy.utils.exceptions.IvyException( + "these dtypes are not type promotable" + ) from e return ret @@ -259,6 +261,7 @@ def promote_types_of_torch_inputs( from . import nn from .nn.functional import softmax, relu, lstm +from . import special from . import tensor from .tensor import * from . import blas_and_lapack_ops diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index 116fb8c80934c..a1c8cd9bbe77b 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -201,7 +201,7 @@ def svd(input, some=True, compute_uv=True, *, out=None): return ret -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def trapezoid(y, x=None, *, dx=None, dim=-1): if x is not None: diff --git a/ivy/functional/frontends/torch/comparison_ops.py b/ivy/functional/frontends/torch/comparison_ops.py index fc7591d156487..051b0cfffd35a 100644 --- a/ivy/functional/frontends/torch/comparison_ops.py +++ b/ivy/functional/frontends/torch/comparison_ops.py @@ -59,6 +59,7 @@ def allclose(input, other, rtol=1e-05, atol=1e-08, equal_nan=False): return ivy.all(ret) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @to_ivy_arrays_and_back def argsort(input, dim=-1, descending=False): return ivy.argsort(input, axis=dim, descending=descending) @@ -73,7 +74,7 @@ def eq(input, other, *, out=None): @to_ivy_arrays_and_back def equal(input, other): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) - return ivy.all_equal(input, other) + return ivy.all(ivy.equal(input, other)) @to_ivy_arrays_and_back @@ -98,14 +99,14 @@ def fmin(input, other, *, out=None): ) -@with_unsupported_dtypes({"2.1.2 and below": ("complex64", "complex128")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("complex64", "complex128")}, "torch") @to_ivy_arrays_and_back def greater(input, other, *, out=None): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) return ivy.greater(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("complex64", "complex128")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("complex64", "complex128")}, "torch") @to_ivy_arrays_and_back def greater_equal(input, other, *, out=None): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) @@ -142,7 +143,9 @@ def isfinite(input): return ivy.isfinite(input) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes( + {"2.2 and below": ("float16", "bfloat16", "complex", "bool")}, "torch" +) @to_ivy_arrays_and_back def isin(elements, test_elements, *, assume_unique=False, invert=False): input_elements_copy = ivy.reshape(ivy.to_ivy(elements), (-1,)) @@ -196,6 +199,7 @@ def isnan(input): return ivy.isnan(input) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @to_ivy_arrays_and_back def isneginf(input, *, out=None): is_inf = ivy.isinf(input) @@ -203,6 +207,7 @@ def isneginf(input, *, out=None): return ivy.logical_and(is_inf, neg_sign_bit, out=out) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @to_ivy_arrays_and_back def isposinf(input, *, out=None): is_inf = ivy.isinf(input) @@ -210,14 +215,14 @@ def isposinf(input, *, out=None): return ivy.logical_and(is_inf, pos_sign_bit, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") @to_ivy_arrays_and_back def isreal(input): return ivy.isreal(input) @with_unsupported_dtypes( - {"2.1.2 and below": ("bfloat16", "float16", "bool", "complex")}, "torch" + {"2.2 and below": ("bfloat16", "float16", "bool", "complex")}, "torch" ) @to_ivy_arrays_and_back def kthvalue(input, k, dim=-1, keepdim=False, *, out=None): @@ -241,44 +246,48 @@ def kthvalue(input, k, dim=-1, keepdim=False, *, out=None): return ret -@with_unsupported_dtypes({"2.1.2 and below": ("complex64", "complex128")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("complex64", "complex128")}, "torch") @to_ivy_arrays_and_back def less(input, other, *, out=None): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) return ivy.less(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("complex64", "complex128")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("complex64", "complex128")}, "torch") @to_ivy_arrays_and_back def less_equal(input, other, *, out=None): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) return ivy.less_equal(input, other, out=out) +@with_unsupported_dtypes({"2.2 and below": ("complex64", "complex128")}, "torch") @to_ivy_arrays_and_back def maximum(input, other, *, out=None): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) return ivy.maximum(input, other, out=out) +@with_unsupported_dtypes({"2.2 and below": ("complex64", "complex128")}, "torch") @to_ivy_arrays_and_back def minimum(input, other, *, out=None): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) return ivy.minimum(input, other, out=out) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @to_ivy_arrays_and_back def msort(input, *, out=None): return ivy.sort(input, axis=0, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def not_equal(input, other, *, out=None): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) return ivy.not_equal(input, other, out=out) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @to_ivy_arrays_and_back # TODO: the original torch.sort places * right before `out` def sort(input, *, dim=-1, descending=False, stable=False, out=None): @@ -287,7 +296,7 @@ def sort(input, *, dim=-1, descending=False, stable=False, out=None): return namedtuple("sort", ["values", "indices"])(values, indices) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") @to_ivy_arrays_and_back def topk(input, k, dim=None, largest=True, sorted=True, *, out=None): if dim is None: diff --git a/ivy/functional/frontends/torch/creation_ops.py b/ivy/functional/frontends/torch/creation_ops.py index 4f4d9134a9738..920756f7e814b 100644 --- a/ivy/functional/frontends/torch/creation_ops.py +++ b/ivy/functional/frontends/torch/creation_ops.py @@ -12,7 +12,7 @@ @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def arange( start=0, end=None, @@ -74,7 +74,7 @@ def asarray( return ivy.asarray(obj, copy=copy, dtype=dtype, device=device) -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") @to_ivy_arrays_and_back def complex( real, @@ -107,7 +107,13 @@ def empty( if args and size: raise TypeError("empty() got multiple values for argument 'shape'") if size is None: - size = args[0] if isinstance(args[0], (tuple, list, ivy.Shape)) else args + size = ( + args[0] + if isinstance(args[0], (tuple, list, ivy.Shape, ivy.NativeShape)) + else args + ) + if isinstance(size, (tuple, list)): + size = tuple(s.to_scalar() if ivy.is_array(s) else s for s in size) return ivy.empty(shape=size, dtype=dtype, device=device, out=out) @@ -208,7 +214,7 @@ def heaviside(input, values, *, out=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def linspace( start, end, @@ -220,12 +226,12 @@ def linspace( layout=None, requires_grad=False, ): - ret = ivy.linspace(start, end, num=steps, dtype=dtype, device=device, out=out) - return ret + dtype = torch_frontend.get_default_dtype() if dtype is None else dtype + return ivy.linspace(start, end, num=steps, dtype=dtype, device=device, out=out) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def logspace( start, end, @@ -250,7 +256,11 @@ def ones(*args, size=None, out=None, dtype=None, device=None, requires_grad=Fals if args and size: raise TypeError("ones() got multiple values for argument 'shape'") if size is None: - size = args[0] if isinstance(args[0], (tuple, list, ivy.Shape)) else args + size = ( + args[0] + if isinstance(args[0], (tuple, list, ivy.Shape, ivy.NativeShape)) + else args + ) return ivy.ones(shape=size, dtype=dtype, device=device, out=out) @@ -273,7 +283,7 @@ def ones_like_v_0p4p0_and_above( return ret -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") @to_ivy_arrays_and_back def polar( abs, @@ -285,7 +295,7 @@ def polar( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def range( *args, dtype=None, @@ -342,7 +352,11 @@ def zeros(*args, size=None, out=None, dtype=None, device=None, requires_grad=Fal if args and size: raise TypeError("zeros() got multiple values for argument 'shape'") if size is None: - size = args[0] if isinstance(args[0], (tuple, list, ivy.Shape)) else args + size = ( + args[0] + if isinstance(args[0], (tuple, list, ivy.Shape, ivy.NativeShape)) + else args + ) return ivy.zeros(shape=size, dtype=dtype, device=device, out=out) diff --git a/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py b/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py index 792c5796e8b03..7244d46ffad01 100644 --- a/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py +++ b/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py @@ -74,7 +74,7 @@ def conj(input): # diagonal_scatter @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "float16", ) @@ -215,7 +215,7 @@ def index_copy(input, dim, index, source, *, out=None): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "uint16", "uint32", "uint64", @@ -342,13 +342,9 @@ def narrow(input, dim, start, length): @to_ivy_arrays_and_back def nonzero(input, *, out=None, as_tuple=False): - ret = ivy.nonzero(input) - if as_tuple is False: - ret = ivy.matrix_transpose(ivy.stack(ret)) - - if ivy.exists(out): - return ivy.inplace_update(out, ret) - return ret + if as_tuple: + return ivy.nonzero(input, as_tuple=as_tuple) + return ivy.argwhere(input != 0, out=out) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/torch/linalg.py b/ivy/functional/frontends/torch/linalg.py index d34c0c5c09e2b..c8b0260412b0b 100644 --- a/ivy/functional/frontends/torch/linalg.py +++ b/ivy/functional/frontends/torch/linalg.py @@ -9,7 +9,7 @@ @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def cholesky(input, *, upper=False, out=None): return ivy.cholesky(input, upper=upper, out=out) @@ -23,7 +23,7 @@ def cholesky_ex(input, *, upper=False, check_errors=False, out=None): return matrix, info except RuntimeError as e: if check_errors: - raise RuntimeError(e) + raise RuntimeError(e) from e else: matrix = input * math.nan info = ivy.ones(input.shape[:-2], dtype=ivy.int32) @@ -31,14 +31,14 @@ def cholesky_ex(input, *, upper=False, check_errors=False, out=None): @to_ivy_arrays_and_back -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64", "complex")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64", "complex")}, "torch") def cond(input, p=None, *, out=None): return ivy.cond(input, p=p, out=out) @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def cross(input, other, *, dim=None, out=None): return torch_frontend.miscellaneous_ops.cross(input, other, dim=dim, out=out) @@ -46,7 +46,7 @@ def cross(input, other, *, dim=None, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def det(A, *, out=None): return ivy.det(A, out=out) @@ -63,13 +63,13 @@ def divide(input, other, *, rounding_mode=None, out=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, "torch") def eig(input, *, out=None): return ivy.eig(input, out=out) @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64", "complex128")}, + {"2.2 and below": ("float32", "float64", "complex32", "complex64", "complex128")}, "torch", ) def eigh(A, UPLO="L", *, out=None): @@ -78,7 +78,7 @@ def eigh(A, UPLO="L", *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def eigvals(input, *, out=None): ret = ivy.eigvals(input) @@ -89,7 +89,7 @@ def eigvals(input, *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def eigvalsh(input, UPLO="L", *, out=None): ret = ivy.eigvalsh(input, UPLO=UPLO, out=out) @@ -102,7 +102,7 @@ def eigvalsh(input, UPLO="L", *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def inv(A, *, out=None): return ivy.inv(A, out=out) @@ -110,7 +110,7 @@ def inv(A, *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def inv_ex(A, *, check_errors=False, out=None): if ivy.any(ivy.det(A) == 0): @@ -129,41 +129,58 @@ def inv_ex(A, *, check_errors=False, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def lu_factor(A, *, pivot=True, out=None): return ivy.lu_factor(A, pivot=pivot, out=out) +@to_ivy_arrays_and_back +def lu_factor_ex(A, *, pivot=True, check_errors=False, out=None): + try: + LU = ivy.lu_factor(A, pivot=pivot, out=out) + info = ivy.zeros(A.shape[:-2], dtype=ivy.int32) + return LU, info + except RuntimeError as e: + if check_errors: + raise RuntimeError(e) from e + else: + matrix = A * math.nan + info = ivy.ones(A.shape[:-2], dtype=ivy.int32) + return matrix, info + + +def lu_solve(LU, pivots, B, *, left=True, adjoint=False, out=None): + return ivy.lu_solve(LU, pivots, B, out=out) + + @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def matmul(input, other, *, out=None): return ivy.matmul(input, other, out=out) @to_ivy_arrays_and_back -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64", "complex")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64", "complex")}, "torch") def matrix_exp(A): return ivy.matrix_exp(A) @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def matrix_norm(input, ord="fro", dim=(-2, -1), keepdim=False, *, dtype=None, out=None): - if "complex" in ivy.as_ivy_dtype(input.dtype): - input = ivy.abs(input) - if dtype: - input = ivy.astype(input, ivy.as_ivy_dtype(dtype)) + if dtype is not None: + input = ivy.astype(input, dtype) return ivy.matrix_norm(input, ord=ord, axis=dim, keepdims=keepdim, out=out) @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def matrix_power(A, n, *, out=None): return ivy.matrix_power(A, n, out=out) @@ -171,7 +188,7 @@ def matrix_power(A, n, *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def matrix_rank(A, *, atol=None, rtol=None, hermitian=False, out=None): return ivy.matrix_rank(A, atol=atol, rtol=rtol, hermitian=hermitian, out=out) @@ -179,7 +196,7 @@ def matrix_rank(A, *, atol=None, rtol=None, hermitian=False, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def multi_dot(tensors, *, out=None): return ivy.multi_dot(tensors, out=out) @@ -187,7 +204,7 @@ def multi_dot(tensors, *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex64", "complex128")}, "torch" + {"2.2 and below": ("float32", "float64", "complex64", "complex128")}, "torch" ) def norm(input, ord=None, dim=None, keepdim=False, *, dtype=None, out=None): if dim is None and (ord is not None): @@ -207,7 +224,7 @@ def norm(input, ord=None, dim=None, keepdim=False, *, dtype=None, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def pinv(input, *, atol=None, rtol=None, hermitian=False, out=None): # TODO: add handling for hermitian @@ -226,7 +243,7 @@ def pinv(input, *, atol=None, rtol=None, hermitian=False, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def qr(A, mode="reduced", *, out=None): if mode == "reduced": @@ -244,7 +261,7 @@ def qr(A, mode="reduced", *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def slogdet(A, *, out=None): sign, logabsdet = ivy.slogdet(A) @@ -260,7 +277,7 @@ def slogdet(A, *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def solve(A, B, *, left=True, out=None): if left: @@ -274,7 +291,7 @@ def solve(A, B, *, left=True, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def solve_ex(A, B, *, left=True, check_errors=False, out=None): try: @@ -292,7 +309,7 @@ def solve_ex(A, B, *, left=True, check_errors=False, out=None): return result, info except RuntimeError as e: if check_errors: - raise RuntimeError(e) + raise RuntimeError(e) from e else: result = A * math.nan info = ivy.ones(A.shape[:-2], dtype=ivy.int32) @@ -302,7 +319,7 @@ def solve_ex(A, B, *, left=True, check_errors=False, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def svd(A, /, *, full_matrices=True, driver=None, out=None): # TODO: add handling for driver and out @@ -311,7 +328,7 @@ def svd(A, /, *, full_matrices=True, driver=None, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def svdvals(A, *, driver=None, out=None): if driver in ["gesvd", "gesvdj", "gesvda", None]: @@ -322,7 +339,7 @@ def svdvals(A, *, driver=None, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def tensorinv(input, ind=2, *, out=None): not_invertible = "Reshaped tensor is not invertible" @@ -349,14 +366,14 @@ def tensorinv(input, ind=2, *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def tensorsolve(A, B, dims=None, *, out=None): return ivy.tensorsolve(A, B, axes=dims, out=out) @to_ivy_arrays_and_back -@with_supported_dtypes({"2.1.2 and below": ("integer", "float", "complex")}, "torch") +@with_supported_dtypes({"2.2 and below": ("integer", "float", "complex")}, "torch") def vander(x, N=None): if len(x.shape) < 1: raise RuntimeError("Input dim must be greater than or equal to 1.") @@ -389,7 +406,7 @@ def vander(x, N=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def vecdot(x, y, *, dim=-1, out=None): if "complex" in ivy.as_ivy_dtype(x.dtype): @@ -399,7 +416,7 @@ def vecdot(x, y, *, dim=-1, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def vector_norm(input, ord=2, dim=None, keepdim=False, *, dtype=None, out=None): return ivy.vector_norm( diff --git a/ivy/functional/frontends/torch/miscellaneous_ops.py b/ivy/functional/frontends/torch/miscellaneous_ops.py index 9369885c74745..1cf7aa6d03416 100644 --- a/ivy/functional/frontends/torch/miscellaneous_ops.py +++ b/ivy/functional/frontends/torch/miscellaneous_ops.py @@ -5,6 +5,9 @@ import ivy.functional.frontends.torch as torch_frontend +erfinv = torch_frontend.special.erfinv + + @to_ivy_arrays_and_back def atleast_1d(*tensors): return ivy.atleast_1d(*tensors) @@ -74,7 +77,7 @@ def broadcast_shapes(*shapes): return ivy.broadcast_shapes(*shapes) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") @to_ivy_arrays_and_back def broadcast_to(tensor, shape): return ivy.broadcast_to(tensor, shape) @@ -92,11 +95,53 @@ def cartesian_prod(*tensors): return ret +@with_unsupported_dtypes({"2.2 and below": "float16"}, "torch") +@to_ivy_arrays_and_back +def cdist(x1, x2, p=2.0, compute_mode="use_mm_for_euclid_dist_if_necessary"): + if len(x1.shape) == 2 and len(x2.shape) == 2: + x1_first_dim, x2_first_dim = x1.shape[0], x2.shape[0] + if ( + compute_mode == "use_mm_for_euclid_dist_if_necessary" + and (x1_first_dim > 25 or x2_first_dim > 25) + or compute_mode == "use_mm_for_euclid_dist" + ): + return ivy.vector_norm(x1[:, None, :] - x2[None, :, :], axis=-1, ord=p) + else: + distances = ivy.zeros((x1_first_dim, x2_first_dim), dtype=x1.dtype) + for i in range(x1_first_dim): + for j in range(x2_first_dim): + distances[i, j] = ivy.vector_norm(x1[i, :] - x2[j, :], ord=p) + return distances + if p == 2: + B, P, M = x1.shape + _, R, _ = x2.shape + if ( + compute_mode == "use_mm_for_euclid_dist_if_necessary" + and (P > 25 or R > 25) + or compute_mode == "use_mm_for_euclid_dist" + ): + return ivy.vector_norm( + x1[:, :, None, :] - x2[:, None, :, :], axis=-1, ord=p + ) + else: + distances = ivy.zeros((B, P, R), dtype=x1.dtype) + for b in range(B): + for i in range(P): + for j in range(R): + distances[b, i, j] = ivy.vector_norm( + x1[b, i, :] - x2[b, j, :], ord=p + ) + return distances + else: + return ivy.vector_norm(x1[:, :, None, :] - x2[:, None, :, :], axis=-1, ord=p) + + @to_ivy_arrays_and_back def clone(input, *, memory_format=None): return ivy.copy_array(input) +@with_unsupported_dtypes({"2.2 and below": ("float16", "bool")}, "torch") @to_ivy_arrays_and_back def corrcoef(input): if len(ivy.shape(input)) > 2: @@ -113,7 +158,7 @@ def cov(input, /, *, correction=1, fweights=None, aweights=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def cross(input, other, dim=None, *, out=None): if dim is None: dim = -1 @@ -124,7 +169,7 @@ def cross(input, other, dim=None, *, out=None): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "uint16", "uint32", "uint64", @@ -152,7 +197,7 @@ def cumprod(input, dim, *, dtype=None, out=None): @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"2.1.2 and below": ("uint8", "bfloat16", "float16"), "1.12.1": ()}, + {"2.2 and below": ("uint8", "bfloat16", "float16"), "1.12.1": ()}, "torch", ) def cumsum(input, dim, *, dtype=None, out=None): @@ -166,8 +211,57 @@ def diag(input, diagonal=0, *, out=None): return ivy.diag(input, k=diagonal) +@to_ivy_arrays_and_back +def diag_embed( + input, + offset=0, + dim1=-2, + dim2=-1, +): + def _handle_dim(rank, idx): + if idx >= 0 and idx < rank: + return idx + if idx < 0: + idx = idx + rank + if idx < 0 or idx >= rank: + raise IndexError + return idx + + input_type = ivy.dtype(input) + rank = input.ndim + 1 + dim1 = _handle_dim(rank, dim1) + dim2 = _handle_dim(rank, dim2) + if dim1 > dim2: + dim1, dim2 = dim2, dim1 + offset = -offset + last_dim = list(input.shape)[-1] + if offset != 0: + # add padding to match the new size + t_shape = list(input.shape) + t_shape[-1] = abs(offset) + z = ivy.zeros(t_shape, dtype=input.dtype, device=input.device) + pair = (z, input) if offset > 0 else (input, z) + input = ivy.concat(pair, axis=-1) + last_dim += abs(offset) + input = input.expand_dims(axis=dim1).moveaxis(-1, dim2) + # generate ranges shifting indices based on offset + a_range = ivy.arange(last_dim, device=input.device, dtype=ivy.int64) + b_range = ivy.arange( + offset, last_dim + offset, device=input.device, dtype=ivy.int64 + ) + # broadcast + cond = a_range == b_range.expand_dims(axis=-1) + cond_shape = [last_dim if i in (dim1, dim2) else 1 for i in range(len(input.shape))] + cond = cond.reshape(cond_shape) + if input.dtype == ivy.bool: + ret = cond.logical_and(input) + else: + ret = ivy.where(cond, input, 0) + return ret.astype(input_type) + + @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) @to_ivy_arrays_and_back def diagflat(x, offset=0, name=None): @@ -175,7 +269,7 @@ def diagflat(x, offset=0, name=None): return arr -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def diagonal(input, offset=0, dim1=0, dim2=1): return ivy.diagonal(input, offset=offset, axis1=dim1, axis2=dim2) @@ -183,20 +277,25 @@ def diagonal(input, offset=0, dim1=0, dim2=1): @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"2.1.2 and below": ("int8", "float16", "bfloat16", "bool")}, "torch" + {"2.2 and below": ("int8", "float16", "bfloat16", "bool")}, "torch" ) def diff(input, n=1, dim=-1, prepend=None, append=None): return ivy.diff(input, n=n, axis=dim, prepend=prepend, append=append, out=None) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def einsum(equation, *operands): if len(operands) == 1 and isinstance(operands[0], (list, tuple)): operands = operands[0] return ivy.einsum(equation, *operands) +@to_ivy_arrays_and_back +def finfo(dtype): + return ivy.finfo(dtype) + + @to_ivy_arrays_and_back def flatten(input, start_dim=0, end_dim=-1): return ivy.flatten(input, start_dim=start_dim, end_dim=end_dim) @@ -242,14 +341,14 @@ def kron(input, other, *, out=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("int8",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("int8",)}, "torch") def lcm(input, other, *, out=None): return ivy.lcm(input, other, out=out) @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", "integer", @@ -273,6 +372,11 @@ def logcumsumexp(input, dim, *, out=None): return ret +@to_ivy_arrays_and_back +def lu_solve(b, LU_data, LU_pivots, *, out=None): + return torch_frontend.linalg.lu_solve(LU_data, LU_pivots, b, out=out) + + @to_ivy_arrays_and_back def meshgrid(*tensors, indexing=None): if indexing is None: @@ -287,7 +391,7 @@ def ravel(input): return ivy.reshape(input, (-1,)) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def renorm(input, p, dim, maxnorm, *, out=None): # Torch hardcodes this magic number @@ -328,7 +432,7 @@ def renorm(input, p, dim, maxnorm, *, out=None): @with_supported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "int32", "int64", ) @@ -441,24 +545,25 @@ def searchsorted( *, out_int32=False, right=False, - side="left", + side=None, out=None, sorter=None, ): - if right and side == "left": - raise ivy.exceptions.IvyError( - "side and right can't be set to opposites, got side of left" - " while right was True" - ) - if right: - side = "right" + if side == "left": + if right: + raise ivy.exceptions.IvyError( + "side and right can't be set to opposites, got side of left" + " while right was True" + ) + elif side is None: + side = "right" if right else "left" ret = ivy.searchsorted(sorted_sequence, values, side=side, out=out, sorter=sorter) if out_int32: ret = ivy.astype(ret, "int32") return ret -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def tensordot(a, b, dims=2, out=None): a, b = promote_types_of_torch_inputs(a, b) @@ -466,7 +571,7 @@ def tensordot(a, b, dims=2, out=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def trace(input): if "int" in input.dtype: input = input.astype("int64") @@ -480,7 +585,7 @@ def tril(input, diagonal=0, *, out=None): return ivy.tril(input, k=diagonal, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("int8", "uint8", "int16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("int8", "uint8", "int16")}, "torch") @to_ivy_arrays_and_back def tril_indices(row, col, offset=0, *, dtype=ivy.int64, device="cpu", layout=None): sample_matrix = ivy.tril(ivy.ones((row, col), device=device), k=offset) @@ -502,6 +607,11 @@ def triu_indices(row, col, offset=0, dtype="int64", device="cpu", layout=None): return ivy.stack(ivy.nonzero(sample_matrix)).astype(dtype) +@to_ivy_arrays_and_back +def unflatten(input, dim, sizes): + return ivy.unflatten(input, dim=dim, shape=sizes, out=None) + + @to_ivy_arrays_and_back def vander(x, N=None, increasing=False): # if N == 0: @@ -511,7 +621,7 @@ def vander(x, N=None, increasing=False): @to_ivy_arrays_and_back -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") def view_as_complex(input): if ivy.shape(input)[-1] != 2: raise ivy.exceptions.IvyError("The last dimension must have a size of 2") @@ -529,7 +639,7 @@ def view_as_complex(input): @with_supported_dtypes( - {"2.1.2 and below": ("complex64", "complex128")}, + {"2.2 and below": ("complex64", "complex128")}, "torch", ) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/torch/nn/functional/convolution_functions.py b/ivy/functional/frontends/torch/nn/functional/convolution_functions.py index 2ca1b3a09086b..89b4bcf3c7f67 100644 --- a/ivy/functional/frontends/torch/nn/functional/convolution_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/convolution_functions.py @@ -107,7 +107,7 @@ def _get_transpose_pad(padding, output_padding, dims): # ------------ # -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def conv1d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1): return _conv( @@ -121,7 +121,7 @@ def conv1d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1): ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1): return _conv( @@ -135,7 +135,7 @@ def conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1): ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def conv3d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1): return _conv( @@ -149,7 +149,7 @@ def conv3d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1): ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def conv_transpose1d( input, @@ -188,7 +188,7 @@ def conv_transpose1d( ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def conv_transpose2d( input, @@ -227,7 +227,7 @@ def conv_transpose2d( ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def conv_transpose3d( input, diff --git a/ivy/functional/frontends/torch/nn/functional/distance_functions.py b/ivy/functional/frontends/torch/nn/functional/distance_functions.py index 029079540ca98..04429e99172d0 100644 --- a/ivy/functional/frontends/torch/nn/functional/distance_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/distance_functions.py @@ -4,7 +4,7 @@ from ivy.func_wrapper import with_unsupported_dtypes -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def cosine_similarity(x1, x2, *, dim=1, eps=1e-08): x1, x2 = torch_frontend.promote_types_of_torch_inputs(x1, x2) @@ -28,7 +28,7 @@ def cosine_similarity(x1, x2, *, dim=1, eps=1e-08): return cosine -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def pairwise_distance(x1, x2, *, p=2.0, eps=1e-06, keepdim=False): x1, x2 = torch_frontend.promote_types_of_torch_inputs(x1, x2) @@ -42,7 +42,7 @@ def pairwise_distance(x1, x2, *, p=2.0, eps=1e-06, keepdim=False): return ivy.vector_norm(x1 - x2 + eps, ord=p, axis=output_dim - 1, keepdims=keepdim) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def pdist(input, p=2): x = ivy.array( diff --git a/ivy/functional/frontends/torch/nn/functional/dropout_functions.py b/ivy/functional/frontends/torch/nn/functional/dropout_functions.py index e384bc25e023e..a4d2b296661ad 100644 --- a/ivy/functional/frontends/torch/nn/functional/dropout_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/dropout_functions.py @@ -7,8 +7,8 @@ # ToDo: this function will be simplified once ivy.alpha_dropout is implemented @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") -@with_unsupported_dtypes({"2.5.2 and below": ("float16", "bfloat16")}, "paddle") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.6.0 and below": ("float16", "bfloat16")}, "paddle") def alpha_dropout(input, p=0.5, training=False, inplace=False): if p == 0.0 or not training or input.shape == () or input.shape == (0,): return input @@ -28,13 +28,13 @@ def alpha_dropout(input, p=0.5, training=False, inplace=False): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def dropout(input, p=0.5, training=True, inplace=False): return ivy.dropout(input, p, scale=True, training=training) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def dropout1d(input, p=0.5, training=True, inplace=False): if inplace: return ivy.dropout1d(input, p, training=training, data_format="NCW", out=input) @@ -42,7 +42,7 @@ def dropout1d(input, p=0.5, training=True, inplace=False): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def dropout2d(input, p=0.5, training=True, inplace=False): if input.ndim < 2: raise ValueError("Feature dropout requires at least 2 dimensions in the input") @@ -55,7 +55,7 @@ def dropout2d(input, p=0.5, training=True, inplace=False): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def dropout3d(input, p=0.5, training=True, inplace=False): if inplace: return ivy.dropout3d( diff --git a/ivy/functional/frontends/torch/nn/functional/layer_functions.py b/ivy/functional/frontends/torch/nn/functional/layer_functions.py index 7ed6d8d90354e..6c7221673e2b0 100644 --- a/ivy/functional/frontends/torch/nn/functional/layer_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/layer_functions.py @@ -1,8 +1,6 @@ import ivy from ivy.func_wrapper import with_supported_device_and_dtypes, with_supported_dtypes from ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back -from ivy.functional.ivy.experimental.manipulation import _slice_along_axis -from ivy.utils.exceptions import IvyNotImplementedException # --- Helpers --- # @@ -17,132 +15,6 @@ def _extract_states(states, batch_sizes): return h -def _generic_lstm( - input, - initial_states, - all_weights, - has_biases, - num_layers, - dropout, - train, - bidirectional, - batch_first=False, - batch_sizes=None, -): - weights_per_layer = 4 if has_biases else 2 - - assert len(all_weights) == num_layers * weights_per_layer * (1 + bidirectional) - layer_weights = [ - all_weights[i : i + weights_per_layer] - for i in range(0, len(all_weights), weights_per_layer) - ] - - if batch_sizes is not None: - input, batch_sizes = _pad_packed_sequence(input, batch_sizes) - - if batch_first: - input = ivy.swapaxes(input, 0, 1) - - if dropout and train: - raise IvyNotImplementedException() - - unidirectional = not bidirectional - - h0, c0 = initial_states - h_outs, c_outs = [], [] - - output = input - for i in range(num_layers): - if unidirectional: - if weights_per_layer == 4: - weight_ih, weight_hh, (bias_i, bias_h) = _transform_weights( - layer_weights, i - ) - else: - weight_ih, weight_hh = _transform_weights_no_bias(layer_weights, i) - bias_i = bias_h = None - - state_indices = i, i + 1 - else: - if weights_per_layer == 4: - weight_ih_f, weight_hh_f, (bias_i_f, bias_h_f) = _transform_weights( - layer_weights, 2 * i - ) - weight_ih_b, weight_hh_b, (bias_i_b, bias_h_b) = _transform_weights( - layer_weights, 2 * i + 1 - ) - else: - weight_ih_f, weight_hh_f = _transform_weights_no_bias( - layer_weights, 2 * i - ) - weight_ih_b, weight_hh_b = _transform_weights_no_bias( - layer_weights, 2 * i + 1 - ) - bias_i_f = bias_h_f = bias_i_b = bias_h_b = None - - weight_ih = weight_ih_f, weight_ih_b - weight_hh = weight_hh_f, weight_hh_b - bias_i = bias_i_f, bias_i_b - bias_h = bias_h_f, bias_h_b - - state_indices = 2 * i, 2 * i + 2 - - output, (h_out, c_out) = _lstm_layer( - output, - ( - _retrieve_state(h0, *state_indices, num_layers), - _retrieve_state(c0, *state_indices, num_layers), - ), - (weight_ih, weight_hh), - (bias_i, bias_h), - bidirectional, - batch_first=batch_first, - batch_sizes=batch_sizes, - ) - h_outs.append(h_out) - c_outs.append(c_out) - - if batch_first: - output = ivy.swapaxes(output, 0, 1) - - h_outs = h_out if num_layers == 1 else ivy.concat(h_outs, axis=0) - c_outs = c_out if num_layers == 1 else ivy.concat(c_outs, axis=0) - - if batch_sizes is not None: - output = _pack_padded_sequence(output, batch_sizes)[0] - - return output, h_outs, c_outs - - -def _lstm_cell( - x, - init_h, - init_c, - kernel, - recurrent_kernel, - bias, - recurrent_bias, - batch_first, - batch_sizes=None, -): - init_h = ivy.squeeze(init_h, axis=0) - init_c = ivy.squeeze(init_c, axis=0) - out, states = ivy.lstm_update( - x, - init_h, - init_c, - kernel, - recurrent_kernel, - bias=bias, - recurrent_bias=recurrent_bias, - time_major=not batch_first, - ) - h, c = states - h = ivy.expand_dims(h) if len(h.shape) == 2 else h - c = ivy.expand_dims(c) if len(c.shape) == 2 else c - return out, (h, c) - - def _lstm_full( input, hx, @@ -154,60 +26,19 @@ def _lstm_full( bidirectional, batch_first, ): - return _generic_lstm( + ret = ivy.lstm( input, hx, params, - has_biases, num_layers, dropout, train, bidirectional, batch_first=batch_first, + has_ih_bias=has_biases, + has_hh_bias=has_biases, ) - - -def _lstm_layer( - x, hidden, weights, biases, bidirectional, batch_first, batch_sizes=None -): - if not bidirectional: - result, (h, c) = _lstm_cell( - x, - *hidden, - *weights, - *biases, - batch_first=batch_first, - batch_sizes=batch_sizes, - ) - else: - result_fw, (h_fw, c_fw) = _lstm_cell( - x, - hidden[0][:1], - hidden[1][:1], - weights[0][0], - weights[1][0], - biases[0][0], - biases[1][0], - batch_first=batch_first, - batch_sizes=batch_sizes, - ) - x_reversed = ivy.flip(x, axis=0) - result_bw, (h_bw, c_bw) = _lstm_cell( - x_reversed, - hidden[0][1:], - hidden[1][1:], - weights[0][1], - weights[1][1], - biases[0][1], - biases[1][1], - batch_first=batch_first, - batch_sizes=batch_sizes, - ) - result_bw = ivy.flip(result_bw, axis=0) - result = ivy.concat([result_fw, result_bw], axis=len(result_fw.shape) - 1) - c = ivy.concat([c_fw, c_bw], axis=0) - h = ivy.concat([h_fw, h_bw], axis=0) - return result, (h, c) + return ret[1], ret[2][0], ret[2][1] def _lstm_packed( @@ -221,70 +52,19 @@ def _lstm_packed( train, bidirectional, ): - return _generic_lstm( + ret = ivy.lstm( data, hx, params, - has_biases, num_layers, dropout, train, bidirectional, batch_sizes=batch_sizes, + has_ih_bias=has_biases, + has_hh_bias=has_biases, ) - - -def _pack_padded_sequence(input, lengths): - input = ivy.swapaxes(input, 0, 1) - data = [] - batch_sizes = [] - for i in range(int(max(lengths))): - valid_data_mask = ivy.array(lengths) > i - data.append(input[valid_data_mask, i]) - batch_sizes.append(int(sum(valid_data_mask))) - data = ivy.concat(data) - batch_sizes = ivy.array(batch_sizes, dtype=ivy.int64) - return data, batch_sizes - - -def _pad_packed_sequence(data, batch_sizes): - padded_data = ivy.full( - (len(batch_sizes), int(max(batch_sizes)), *data.shape[1:]), - 0, - dtype=data.dtype, - device=data.device, - ) - data_offset = 0 - for i, batch_size in enumerate(batch_sizes): - batch_size = int(batch_size) - padded_data[i, :batch_size] = data[data_offset : data_offset + batch_size] - data_offset += batch_size - lengths = ivy.sum( - ivy.arange(1, int(max(batch_sizes)) + 1)[:, ivy.newaxis] <= batch_sizes, - axis=1, - dtype=ivy.int64, - ) - return padded_data, lengths - - -def _retrieve_state(x, start, end, num_layers): - return x if num_layers == 1 else _slice_along_axis(x, start=start, stop=end, axis=0) - - -def _transform_weights(layer_weights, layer_index): - weights = layer_weights[layer_index] - weight_ih, weight_hh, bias_ih, bias_hh = weights - return ( - ivy.swapaxes(weight_ih, 0, 1), - ivy.swapaxes(weight_hh, 0, 1), - (bias_ih, bias_hh), - ) - - -def _transform_weights_no_bias(layer_weights, layer_index): - weights = layer_weights[layer_index] - weight_ih, weight_hh = weights - return ivy.swapaxes(weight_ih, 0, 1), ivy.swapaxes(weight_hh, 0, 1) + return ret[1], ret[2][0], ret[2][1] # --- Main --- # @@ -292,7 +72,7 @@ def _transform_weights_no_bias(layer_weights, layer_index): @with_supported_device_and_dtypes( - {"2.1.2 and below": {"cpu": ("float32", "float64")}}, + {"2.2 and below": {"cpu": ("float32", "float64")}}, "torch", ) @to_ivy_arrays_and_back @@ -304,7 +84,7 @@ def lstm(*args, **kwargs): @to_ivy_arrays_and_back -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") def multi_head_attention_forward( query, key, diff --git a/ivy/functional/frontends/torch/nn/functional/linear_functions.py b/ivy/functional/frontends/torch/nn/functional/linear_functions.py index 6246a013db9e9..fba4a5f50b699 100644 --- a/ivy/functional/frontends/torch/nn/functional/linear_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/linear_functions.py @@ -4,7 +4,7 @@ from ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def linear(input, weight, bias=None): return ivy.linear(input, weight, bias=bias) diff --git a/ivy/functional/frontends/torch/nn/functional/loss_functions.py b/ivy/functional/frontends/torch/nn/functional/loss_functions.py index 6c9acb5fe3578..ef13df7557bfd 100644 --- a/ivy/functional/frontends/torch/nn/functional/loss_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/loss_functions.py @@ -72,7 +72,7 @@ def _get_reduction_string(size_average, reduce): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def binary_cross_entropy( input, target, weight=None, size_average=None, reduce=None, reduction="mean" ): @@ -113,7 +113,7 @@ def binary_cross_entropy_with_logits( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def cosine_embedding_loss( input1, input2, target, margin=0.0, size_average=None, reduce=None, reduction="mean" ): @@ -214,7 +214,7 @@ def cross_entropy( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("bool", "integer")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bool", "integer")}, "torch") def gaussian_nll_loss(input, target, var, full=False, eps=1e-6, reduction="mean"): input, target = torch_frontend.promote_types_of_torch_inputs(input, target) target, var = torch_frontend.promote_types_of_torch_inputs(target, var) @@ -246,7 +246,7 @@ def gaussian_nll_loss(input, target, var, full=False, eps=1e-6, reduction="mean" @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def hinge_embedding_loss( input, @@ -281,7 +281,7 @@ def huber_loss( @to_ivy_arrays_and_back -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") def kl_div( input, target, size_average=None, reduce=None, reduction="mean", log_target=False ): @@ -297,7 +297,7 @@ def kl_div( @to_ivy_arrays_and_back -@with_supported_dtypes({"2.1.2 and below": ("float", "complex")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float", "complex")}, "torch") def l1_loss( input, target, @@ -312,7 +312,7 @@ def l1_loss( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def margin_ranking_loss( input1, input2, @@ -331,7 +331,7 @@ def margin_ranking_loss( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def mse_loss(input, target, size_average=None, reduce=None, reduction="mean"): reduction = _get_reduction(reduction, size_average, reduce) result = ivy.square(input - target) @@ -340,7 +340,7 @@ def mse_loss(input, target, size_average=None, reduce=None, reduction="mean"): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def multilabel_margin_loss( input, target, size_average=None, reduce=None, reduction="mean" ): @@ -360,7 +360,7 @@ def multilabel_margin_loss( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def multilabel_soft_margin_loss( input, target, @@ -390,7 +390,7 @@ def multilabel_soft_margin_loss( @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "int8", "int16", "int32")}, "torch" + {"2.2 and below": ("float16", "int8", "int16", "int32")}, "torch" ) def nll_loss( input, @@ -436,7 +436,7 @@ def pairwise_distance(x1, x2, *, p=2.0, eps=1e-06, keepdim=False): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def poisson_nll_loss( input, target, @@ -463,7 +463,7 @@ def poisson_nll_loss( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def smooth_l1_loss( input, target, @@ -476,7 +476,7 @@ def smooth_l1_loss( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def soft_margin_loss( input, target, @@ -488,7 +488,7 @@ def soft_margin_loss( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def triplet_margin_loss( anchor, positive, @@ -543,7 +543,7 @@ def pairwise_distance(x1, x2, *, p=2.0, eps=1e-06, keepdim=False): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def triplet_margin_with_distance_loss( anchor, positive, diff --git a/ivy/functional/frontends/torch/nn/functional/non_linear_activation_functions.py b/ivy/functional/frontends/torch/nn/functional/non_linear_activation_functions.py index fab88dd69bc05..55a5f5d35371f 100644 --- a/ivy/functional/frontends/torch/nn/functional/non_linear_activation_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/non_linear_activation_functions.py @@ -7,7 +7,7 @@ @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "complex", "float16", ) @@ -38,7 +38,7 @@ def elu_(input, alpha=1.0): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -63,7 +63,7 @@ def glu(input, dim=-1): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def gumbel_softmax(logits, tau=1, hard=False, eps=1e-10, dim=-1): gumbels = -ivy.empty_like(logits).exponential().log() gumbels = (logits + gumbels) / tau @@ -100,30 +100,30 @@ def hardswish(input, inplace=False): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def hardtanh(input, min_val=-1.0, max_val=1.0, inplace=False): less = ivy.where(ivy.less(input, min_val), min_val, input) return ivy.where(ivy.greater(input, max_val), max_val, less).astype(input.dtype) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def hardtanh_(input, min_val=-1.0, max_val=1.0): return hardtanh(input, min_val=min_val, max_val=max_val, inplace=True) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def leaky_relu(input, negative_slope=0.01, inplace=False): return ivy.leaky_relu(input, alpha=negative_slope) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def leaky_relu_(input, negative_slope=0.01): return leaky_relu(input, negative_slope=negative_slope, inplace=True) @to_ivy_arrays_and_back -@with_supported_dtypes({"2.1.2 and below": ("float",)}, "torch") +@with_supported_dtypes({"2.2 and below": ("float",)}, "torch") def local_response_norm(input, size, alpha=0.0001, beta=0.75, k=1.0): non_batched = input.ndim == 3 if non_batched: @@ -137,7 +137,7 @@ def local_response_norm(input, size, alpha=0.0001, beta=0.75, k=1.0): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def log_softmax(input, dim=None, _stacklevel=3, dtype=None): if dtype: input = ivy.astype(ivy.array(input), ivy.as_ivy_dtype(dtype)) @@ -149,7 +149,7 @@ def log_softmax(input, dim=None, _stacklevel=3, dtype=None): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -188,7 +188,7 @@ def relu(input, inplace=False): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") def relu6(input, inplace=False): return ivy.relu6(input) @@ -199,7 +199,7 @@ def relu_(input): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def rrelu(input, lower=1.0 / 8, upper=1.0 / 3, training=False, inplace=False): if training: # alpha = ivy.random_uniform(low=lower, high=upper) @@ -212,13 +212,13 @@ def rrelu(input, lower=1.0 / 8, upper=1.0 / 3, training=False, inplace=False): ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def rrelu_(input, lower=1.0 / 8, upper=1.0 / 3, training=False): return rrelu(input, lower=lower, upper=upper, training=training, inplace=True) @to_ivy_arrays_and_back -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") def scaled_dot_product_attention( query, key, value, attn_mask=None, dropout_p=0.0, is_causal=False, scale=None ): @@ -239,19 +239,19 @@ def selu(input, inplace=False): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def sigmoid(input): return ivy.sigmoid(input) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def silu(input, inplace=False): return ivy.multiply(input, ivy.sigmoid(input)) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def softmax(input, dim=None, _stacklevel=3, dtype=None): if dtype: input = ivy.astype(ivy.array(input), ivy.as_ivy_dtype(dtype)) @@ -259,7 +259,7 @@ def softmax(input, dim=None, _stacklevel=3, dtype=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def softmin(input, dim=None, dtype=None): if dtype: input = ivy.astype(ivy.array(input), ivy.as_ivy_dtype(dtype)) @@ -269,7 +269,7 @@ def softmin(input, dim=None, dtype=None): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -293,23 +293,23 @@ def softsign(input): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def tanh(input): return ivy.tanh(input) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def tanhshrink(input): return ivy.subtract(input, ivy.tanh(input)) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def threshold(input, threshold, value, inplace=False): return ivy.where(ivy.greater(input, threshold), input, value) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def threshold_(input, threshold, value): return threshold(input, threshold, value, inplace=True) diff --git a/ivy/functional/frontends/torch/nn/functional/norms.py b/ivy/functional/frontends/torch/nn/functional/norms.py index b1f5531fcd6aa..7418d9f6f8f9b 100644 --- a/ivy/functional/frontends/torch/nn/functional/norms.py +++ b/ivy/functional/frontends/torch/nn/functional/norms.py @@ -5,7 +5,7 @@ @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "float16", ) @@ -43,7 +43,7 @@ def batch_norm( @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -58,7 +58,7 @@ def group_norm(input, num_groups, weight=None, bias=None, eps=1e-05): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "float16", ) @@ -93,7 +93,7 @@ def instance_norm( @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def layer_norm(input, normalized_shape, weight=None, bias=None, eps=1e-05): shape = ivy.shape(input) if isinstance(normalized_shape, int) and normalized_shape == shape[-1]: diff --git a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py index 03cf6a1e78a12..cdc334a740329 100644 --- a/ivy/functional/frontends/torch/nn/functional/pooling_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/pooling_functions.py @@ -11,7 +11,7 @@ @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "float16", ) @@ -25,7 +25,7 @@ def adaptive_avg_pool1d(input, output_size): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -39,7 +39,7 @@ def adaptive_avg_pool2d(input, output_size): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "float16", ) @@ -57,7 +57,25 @@ def adaptive_max_pool2d( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16",)}, + { + "2.2 and below": ( + "bfloat16", + "float16", + ) + }, + "torch", +) +@to_ivy_arrays_and_back +def adaptive_max_pool3d( + input, + output_size, + return_indices=False, +): + return ivy.adaptive_max_pool3d(input, output_size) + + +@with_unsupported_dtypes( + {"2.2 and below": ("float16",)}, "torch", ) @to_ivy_arrays_and_back @@ -83,7 +101,7 @@ def avg_pool1d( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16",)}, + {"2.2 and below": ("float16",)}, "torch", ) @to_ivy_arrays_and_back @@ -111,7 +129,7 @@ def avg_pool2d( @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16")}, + {"2.2 and below": ("float16", "bfloat16")}, "torch", ) @to_ivy_arrays_and_back @@ -140,7 +158,7 @@ def avg_pool3d( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -172,7 +190,7 @@ def lp_pool1d(input, norm_type, kernel_size, stride=None, ceil_mode=False): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -201,7 +219,7 @@ def lp_pool2d(input, norm_type, kernel_size, stride=None, ceil_mode=False): return ivy.pow(ivy.multiply(out, kernel_mul), p).astype(input.dtype) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def max_pool1d( input, @@ -227,7 +245,7 @@ def max_pool1d( ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def max_pool2d( input, @@ -253,7 +271,7 @@ def max_pool2d( ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def max_pool3d( input, diff --git a/ivy/functional/frontends/torch/nn/functional/sparse_functions.py b/ivy/functional/frontends/torch/nn/functional/sparse_functions.py index d0ef9cd0f3976..a351132d3b362 100644 --- a/ivy/functional/frontends/torch/nn/functional/sparse_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/sparse_functions.py @@ -33,7 +33,7 @@ def embedding( return ret -@with_supported_dtypes({"2.1.2 and below": ("int64",)}, "torch") +@with_supported_dtypes({"2.2 and below": ("int64",)}, "torch") @to_ivy_arrays_and_back def one_hot(tensor, num_classes=-1): return ivy.astype(ivy.one_hot(tensor, num_classes), tensor.dtype) diff --git a/ivy/functional/frontends/torch/nn/functional/vision_functions.py b/ivy/functional/frontends/torch/nn/functional/vision_functions.py index e6d96dbfbb367..513d5fd3f57de 100644 --- a/ivy/functional/frontends/torch/nn/functional/vision_functions.py +++ b/ivy/functional/frontends/torch/nn/functional/vision_functions.py @@ -30,7 +30,7 @@ def _handle_padding_shape(padding, n, mode): # ------------ # -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def affine_grid(theta, size, align_corners=False): if len(size) == 4: @@ -93,7 +93,7 @@ def cubic_conv2(A, x): return ((A * x - 5 * A) * x + 8 * A) * x - 4 * A -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") @to_ivy_arrays_and_back def grid_sample( input, grid, mode="bilinear", padding_mode="zeros", align_corners=False @@ -348,7 +348,7 @@ def grid_sample_padding(grid, padding_mode, align_corners, borders=None): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "float16", ) @@ -395,6 +395,7 @@ def interpolate( @to_ivy_arrays_and_back def pad(input, pad, mode="constant", value=0): + value = 0 if value is None else value mode_dict = { "constant": "constant", "reflect": "reflect", @@ -505,7 +506,7 @@ def reflect(x, low2, high2): return x -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def upsample( input, @@ -523,7 +524,7 @@ def upsample( ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def upsample_bilinear(input, size=None, scale_factor=None): return interpolate( @@ -531,7 +532,7 @@ def upsample_bilinear(input, size=None, scale_factor=None): ) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def upsample_nearest(input, size=None, scale_factor=None): return interpolate(input, size=size, scale_factor=scale_factor, mode="nearest") diff --git a/ivy/functional/frontends/torch/nn/modules/module.py b/ivy/functional/frontends/torch/nn/modules/module.py index 5f33aac3eebc9..e2c6059051fee 100644 --- a/ivy/functional/frontends/torch/nn/modules/module.py +++ b/ivy/functional/frontends/torch/nn/modules/module.py @@ -1,7 +1,7 @@ # global import ivy from collections import OrderedDict -from typing import Any, Dict, Iterator, List, Optional, Set, Tuple +from typing import Any, Dict, Iterator, List, Optional, Set, Tuple, Callable # local from ivy.functional.frontends.torch.nn.parameter import Parameter @@ -26,8 +26,6 @@ def __init__(self, *args, device=None, devices=None, **kwargs) -> None: **kwargs, ) super().__setattr__("_frontend_module", True) - super().__setattr__("_nonetype_param_dict", {}) - super().__setattr__("_nonetype_buffers_dict", {}) super().__setattr__( "_attr_mapping", {"_parameters": "v", "_modules": "module_dict"} ) @@ -41,9 +39,11 @@ def _create_variables(self, device=None, dtype=None): (k.replace(".", "/"), v) for k, v in self.__dict__.items() if isinstance(v, Parameter) + and not k.startswith( + ("_"), + ) ] - ), - dynamic_backend=self._dynamic_backend, + ) ) # Created variables that were added using `register_paramter`, # since those would appear in `self._v` @@ -69,7 +69,7 @@ def _create_variables(self, device=None, dtype=None): def _build(self, *args, **kwargs): for module in self.__dict__.values(): if isinstance(module, Module) and module is not self: - if not module.built: + if not module._built: module.build( *module._args, dynamic_backend=module._dynamic_backend, @@ -107,21 +107,45 @@ def forward(self, *input: Any) -> None: f'Module [{type(self).__name__}] is missing the required "forward" function' ) + def call(self, inputs, *args, training=None, mask=None, **kwargs): + if isinstance(inputs, (list, tuple)): + try: + return self.forward(*inputs, *args, **kwargs) + except Exception: + return self.forward(inputs, *args, **kwargs) + else: + return self.forward(inputs, *args, **kwargs) + def _forward(self, *a, **kw): ret = self._call_impl(*a, **kw) return ret def add_module(self, name: str, module: Optional["Module"]) -> None: + if not isinstance(module, Module) and module is not None: + raise TypeError(f"{type(module)} is not a Module subclass") + elif not isinstance(name, str): + raise TypeError(f"module name should be a string. Got {type(name)}") + elif hasattr(self, name) and name not in self._modules: + raise KeyError(f"attribute '{name}' already exists") + elif "." in name: + raise KeyError(f'module name can\'t contain ".", got: {name}') + elif name == "": + raise KeyError('module name can\'t be empty string ""') + + self._modules[name] = module + super().__setattr__(name, module) + def apply(self, fn: Callable[["Module"], None]): + for module in self.children(): + module.apply(fn) + fn(self) + return self + def register_buffer(self, name: str, value: Optional["Tensor"]) -> None: - if value is None: - self._nonetype_buffers_dict[name] = value super().register_buffer(name, value) def register_parameter(self, name: str, value: Optional["Parameter"]) -> None: - if value is None: - self._nonetype_param_dict[name] = value super().register_parameter(name, value) def register_module(self, name: str, module: Optional["Module"]) -> None: @@ -179,7 +203,7 @@ def parameters(self, recurse: bool = True) -> Iterator[Parameter]: def named_parameters( self, prefix: str = "", recurse: bool = True, remove_duplicate: bool = True ) -> Iterator[Tuple[str, Parameter]]: - if not self.built: + if not getattr(self, "_built", False): self.build( *self._args, dynamic_backend=self._dynamic_backend, **self._kwargs ) @@ -196,6 +220,10 @@ def children(self) -> Iterator["Module"]: yield module def named_children(self) -> Iterator[Tuple[str, "Module"]]: + if not getattr(self, "_built", False): + self.build( + *self._args, dynamic_backend=self._dynamic_backend, **self._kwargs + ) memo = set() for name, module in self._module_dict.items(): if module is not None and id(module) not in memo: @@ -212,6 +240,10 @@ def named_modules( prefix: str = "", remove_duplicate: bool = True, ): + if not getattr(self, "_built", False): + self.build( + *self._args, dynamic_backend=self._dynamic_backend, **self._kwargs + ) if memo is None: memo = set() if id(self) not in memo: @@ -238,7 +270,7 @@ def _extra_repr(self) -> str: return "" def _call_impl(self, *args, **kwargs): - return self.forward(*args, **kwargs) + return self.call(*args, **kwargs) def __getattribute__(self, name: str) -> Any: if name == "__dict__": @@ -255,14 +287,6 @@ def __getattribute__(self, name: str) -> Any: v = self.__dict__["_v"] if name in v: return v[name] - if "_nonetype_param_dict" in self.__dict__: - nonetype_param_dict = self.__dict__["_nonetype_param_dict"] - if name in nonetype_param_dict: - return nonetype_param_dict[name] - if "_nonetype_buffers_dict" in self.__dict__: - nonetype_buffers_dict = self.__dict__["_nonetype_buffers_dict"] - if name in nonetype_buffers_dict: - return nonetype_buffers_dict[name] # Adding this attribute mapping s.t if someone tries # to retrieve self._modules/self._parameters, we # can handle that here @@ -272,6 +296,23 @@ def __getattribute__(self, name: str) -> Any: return super().__getattribute__(mapping[name]) return super().__getattribute__(name) + def __setattr__(self, name, value) -> None: + def remove_from(*dicts_or_sets): + for d in dicts_or_sets: + if name in d: + if isinstance(d, dict): + del d[name] + else: + d.discard(name) + + params = self.__dict__.get("_v") + if params is not None and name in params and isinstance(value, Parameter): + remove_from(self.__dict__, self._buffers, self._module_dict) + self.register_parameter(name, value) + super().__setattr__(name, value) + else: + super().__setattr__(name, value) + def __repr__(self): # We treat the extra repr like the sub-module, one item per line extra_lines = [] diff --git a/ivy/functional/frontends/torch/pointwise_ops.py b/ivy/functional/frontends/torch/pointwise_ops.py index 33e7e15db2ba9..9c0c4601c3522 100644 --- a/ivy/functional/frontends/torch/pointwise_ops.py +++ b/ivy/functional/frontends/torch/pointwise_ops.py @@ -5,7 +5,12 @@ with_supported_dtypes, ) import ivy.functional.frontends.torch as torch_frontend -from ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back +from ivy.functional.frontends.torch.func_wrapper import ( + to_ivy_arrays_and_back, +) + + +erfc = torch_frontend.special.erfc @to_ivy_arrays_and_back @@ -13,13 +18,13 @@ def abs(input, *, out=None): return ivy.abs(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def acos(input, *, out=None): return ivy.acos(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def acosh(input, *, out=None): return ivy.acosh(input, out=out) @@ -35,13 +40,13 @@ def add(input, other, *, alpha=1, out=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def addcdiv(input, tensor1, tensor2, *, value=1, out=None): return ivy.add(input, ivy.multiply(value, ivy.divide(tensor1, tensor2)), out=out) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def addcmul(input, tensor1, tensor2, *, value=1, out=None): return ivy.add(input, ivy.multiply(value, ivy.multiply(tensor1, tensor2)), out=out) @@ -51,32 +56,32 @@ def angle(input, *, out=None): return ivy.angle(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def asin(input, *, out=None): return ivy.asin(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def asinh(input, *, out=None): return ivy.asinh(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def atan(input, *, out=None): return ivy.atan(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def atan2(input, other, *, out=None): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) return ivy.atan2(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def atanh(input, *, out=None): return ivy.atanh(input, out=out) @@ -117,13 +122,13 @@ def bitwise_xor(input, other, *, out=None): return ivy.bitwise_xor(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def ceil(input, *, out=None): return ivy.ceil(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") @to_ivy_arrays_and_back def clamp(input, min=None, max=None, *, out=None): ivy.utils.assertions.check_all_or_any_fn( @@ -152,7 +157,7 @@ def copysign(input, other, *, out=None): return ivy.copysign(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def cos(input, *, out=None): return ivy.cos(input, out=out) @@ -181,31 +186,25 @@ def div(input, other, *, rounding_mode=None, out=None): return ivy.divide(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") @to_ivy_arrays_and_back def erf(input, *, out=None): return ivy.erf(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") -@to_ivy_arrays_and_back -def erfc(input, *, out=None): - return 1.0 - ivy.erf(input, out=out) - - -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def exp(input, *, out=None): return ivy.exp(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def exp2(input, out=None): return ivy.exp2(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def expm1(input, out=None): return ivy.expm1(input, out=out) @@ -223,7 +222,7 @@ def float_power(input, exponent, *, out=None): return ivy.float_power(input, exponent, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def floor(input, *, out=None): return ivy.floor(input, out=out) @@ -234,7 +233,7 @@ def floor_divide(input, other, *, out=None): return ivy.floor_divide(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def fmod(x1, x2, out=None): return ivy.fmod(x1, x2, out=out) @@ -245,31 +244,31 @@ def frac(input, *, out=None): return input - ivy.sign(input) * ivy.floor(ivy.abs(input)) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def frexp(input, *, out=None): return ivy.frexp(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") @to_ivy_arrays_and_back def gradient(input, *, spacing=1, dim=None, edge_order=1): return ivy.gradient(input, spacing=spacing, edge_order=edge_order, axis=dim) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def hypot(input, other, *, out=None): return ivy.hypot(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def i0(input, *, out=None): return ivy.i0(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") @to_ivy_arrays_and_back def igamma(input, other, *, out=None): return ivy.igamma(input, x=other, out=out) @@ -280,7 +279,7 @@ def imag(input): return ivy.imag(input) -@with_supported_dtypes({"2.1.2 and below": ("float16", "float32", "float64")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float16", "float32", "float64")}, "torch") @to_ivy_arrays_and_back def ldexp(input, other, *, out=None): value = ivy.pow(2, other, out=out) @@ -288,49 +287,49 @@ def ldexp(input, other, *, out=None): return value -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def lerp(input, end, weight, *, out=None): return ivy.lerp(input, end, weight, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def lgamma(input, *, out=None): return ivy.lgamma(input, out=out) @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def log(input, *, out=None): return ivy.log(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def log10(input, *, out=None): return ivy.log10(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def log1p(input, *, out=None): return ivy.log1p(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def log2(input, *, out=None): return ivy.log2(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def logaddexp(x1, x2, out=None): return ivy.logaddexp(x1, x2, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def logaddexp2(x1, x2, out=None): return ivy.logaddexp2(x1, x2, out=out) @@ -359,13 +358,13 @@ def logical_xor(input, other, *, out=None): return ivy.logical_xor(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") @to_ivy_arrays_and_back def logit(input, eps=None, *, out=None): return ivy.logit(input, eps=eps, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") @to_ivy_arrays_and_back def masked_fill(input, mask, value): return ivy.where(mask, value, input, out=input) @@ -378,7 +377,7 @@ def mul(input, other, *, out=None): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def mvlgamma(input, p, *, out=None): ivy.assertions.check_greater( p, 1, allow_equal=True, message="p has to be greater than or equal to 1" @@ -393,19 +392,19 @@ def mvlgamma(input, p, *, out=None): ) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "tensorflow") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "tensorflow") @to_ivy_arrays_and_back def nan_to_num(input, nan=0.0, posinf=None, neginf=None, *, out=None): return ivy.nan_to_num(input, nan=nan, posinf=posinf, neginf=neginf, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("bool",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bool",)}, "torch") @to_ivy_arrays_and_back def negative(input, *, out=None): return ivy.negative(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, "torch") @to_ivy_arrays_and_back def nextafter(input, other, *, out=None): input, other = torch_frontend.promote_types_of_torch_inputs(input, other) @@ -417,7 +416,7 @@ def positive(input, *, out=None): return ivy.positive(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("bool",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bool",)}, "torch") @to_ivy_arrays_and_back def pow(input, exponent, *, out=None): if not ivy.is_array(exponent): @@ -460,16 +459,16 @@ def remainder(input, other, *, out=None): return ivy.remainder(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") @to_ivy_arrays_and_back def round(input, *, decimals=0, out=None): m = ivy.full(input.shape, 10.0**decimals) upscale = ivy.multiply(input, m) rounded = ivy.round(upscale) - return ivy.divide(rounded, m, out=out) + return ivy.divide(rounded, m, out=out).astype(input.dtype) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def rsqrt(input, *, out=None): return ivy.reciprocal(ivy.sqrt(input), out=out) @@ -488,43 +487,43 @@ def sgn(input, *, out=None): return ivy.sign(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def sigmoid(input, *, out=None): return ivy.sigmoid(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @to_ivy_arrays_and_back def sign(input, *, out=None): return ivy.sign(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @to_ivy_arrays_and_back def signbit(input, *, out=None): return ivy.signbit(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def sin(input, *, out=None): return ivy.sin(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def sinc(input, *, out=None): return ivy.sinc(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def sinh(input, *, out=None): return ivy.sinh(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def sqrt(input, *, out=None): return ivy.sqrt(input, out=out) @@ -541,13 +540,13 @@ def subtract(input, other, *, alpha=1, out=None): return ivy.subtract(input, other * alpha, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def tan(input, *, out=None): return ivy.tan(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def tanh(input, *, out=None): return ivy.tanh(input, out=out) @@ -559,13 +558,13 @@ def true_divide(input, other, *, out=None): return ivy.divide(input, other, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") @to_ivy_arrays_and_back def trunc(input, *, out=None): return ivy.trunc(input, out=out) -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "tensorflow") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "tensorflow") @to_ivy_arrays_and_back def xlogy(input, other, *, out=None): return ivy.xlogy(input, other, out=out) diff --git a/ivy/functional/frontends/torch/random_sampling.py b/ivy/functional/frontends/torch/random_sampling.py index 16f7b8494105d..105e983209e64 100644 --- a/ivy/functional/frontends/torch/random_sampling.py +++ b/ivy/functional/frontends/torch/random_sampling.py @@ -5,7 +5,7 @@ @with_supported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float32", "float64", ) @@ -13,9 +13,9 @@ "torch", ) @to_ivy_arrays_and_back -def bernoulli(input, *, generator=None, out=None): +def bernoulli(input, p, *, generator=None, out=None): seed = generator.initial_seed() if generator is not None else None - return ivy.bernoulli(input, seed=seed, out=out) + return ivy.bernoulli(p, logits=input, seed=seed, out=out) @to_ivy_arrays_and_back @@ -26,7 +26,7 @@ def manual_seed(seed: int): @with_supported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float32", "float64", ) @@ -49,7 +49,7 @@ def multinomial(input, num_samples, replacement=False, *, generator=None, out=No @with_supported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float32", "float64", ) @@ -64,7 +64,7 @@ def normal(mean, std, *, generator=None, out=None): @with_supported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float32", "float64", ) @@ -95,7 +95,7 @@ def rand( if ( isinstance(size, (list, tuple)) and len(size) == 1 - and isinstance(size[0], (list, tuple)) + and isinstance(size[0], (list, tuple, ivy.Shape)) ): size = size[0] seed = generator.initial_seed() if generator is not None else None @@ -195,7 +195,7 @@ def randn( if ( isinstance(size, (list, tuple)) and len(size) == 1 - and isinstance(size[0], (list, tuple)) + and isinstance(size[0], (list, tuple, ivy.Shape)) ): size = size[0] seed = generator.initial_seed() if generator is not None else None @@ -255,6 +255,10 @@ def seed() -> int: return int(ivy.randint(-(2**63), 2**63 - 1)) +@with_supported_dtypes( + {"2.2 and below": ("uint8",)}, + "torch", +) @to_ivy_arrays_and_back def set_rng_state(new_state): return ivy.seed(seed_value=new_state) diff --git a/ivy/functional/frontends/torch/reduction_ops.py b/ivy/functional/frontends/torch/reduction_ops.py index c40bb033b9824..03d6ec6d91fb8 100644 --- a/ivy/functional/frontends/torch/reduction_ops.py +++ b/ivy/functional/frontends/torch/reduction_ops.py @@ -18,12 +18,14 @@ def all(input, dim=None, keepdim=False, *, out=None): return ret +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @numpy_to_torch_style_args @to_ivy_arrays_and_back def amax(input, dim=None, keepdim=False, *, out=None): return ivy.max(input, axis=dim, keepdims=keepdim, out=out) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @numpy_to_torch_style_args @to_ivy_arrays_and_back def amin(input, dim=None, keepdim=False, *, out=None): @@ -32,7 +34,7 @@ def amin(input, dim=None, keepdim=False, *, out=None): @numpy_to_torch_style_args @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16", "complex")}, "torch") def aminmax(input, *, dim=None, keepdim=False, out=None): minmax_tuple = namedtuple("minmax", ["min", "max"]) return minmax_tuple( @@ -51,7 +53,7 @@ def any(input, dim=None, keepdim=False, *, out=None): return ret -@with_unsupported_dtypes({"2.1.2 and below": ("complex", "bool")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("complex", "bool")}, "torch") @numpy_to_torch_style_args @to_ivy_arrays_and_back def argmax(input, dim=None, keepdim=False): @@ -67,7 +69,7 @@ def argmin(input, dim=None, keepdim=False): @numpy_to_torch_style_args @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"2.1.2 and below": ("uint8", "int8")}, + {"2.2 and below": ("uint8", "int8")}, "torch", ) def count_nonzero(input, dim=None): @@ -127,6 +129,7 @@ def mean(input, dim=None, keepdim=False, *, dtype=None, out=None): return ivy.mean(input, axis=dim, keepdims=keepdim, out=out) +@with_unsupported_dtypes({"2.2 and below": ("complex", "float16", "bool")}, "torch") @numpy_to_torch_style_args @to_ivy_arrays_and_back def median(input, dim=None, keepdim=False, *, out=None): @@ -163,7 +166,7 @@ def median(input, dim=None, keepdim=False, *, out=None): @numpy_to_torch_style_args @to_ivy_arrays_and_back @with_unsupported_dtypes( - {"2.1.2 and below": ("complex64", "complex128")}, + {"2.2 and below": ("complex64", "complex128")}, "torch", ) def min(*input, dim=None, keepdim=False, out=None): @@ -190,6 +193,7 @@ def moveaxis(input, source, destination): return ivy.moveaxis(input, source, destination) +@with_supported_dtypes({"2.2 and below": ("float",)}, "torch") @numpy_to_torch_style_args @to_ivy_arrays_and_back def nanmean(input, dim=None, keepdim=False, *, dtype=None, out=None): @@ -234,7 +238,7 @@ def nanmedian(input, dim=None, keepdim=False, *, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float", "int")}, + {"2.2 and below": ("float", "int")}, "torch", ) def nansum(input, dim=None, keepdim=False, *, dtype=None): @@ -244,7 +248,7 @@ def nansum(input, dim=None, keepdim=False, *, dtype=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float", "complex")}, + {"2.2 and below": ("float", "complex")}, "torch", ) def norm(input, p="fro", dim=None, keepdim=False, out=None, dtype=None): @@ -270,7 +274,7 @@ def norm(input, p="fro", dim=None, keepdim=False, out=None, dtype=None): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -286,7 +290,7 @@ def prod(input, dim=None, keepdim=False, *, dtype=None): @numpy_to_torch_style_args @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def quantile(input, q, dim=None, keepdim=False, *, interpolation="linear", out=None): return ivy.quantile( input, q, axis=dim, keepdims=keepdim, interpolation=interpolation, out=out @@ -295,14 +299,14 @@ def quantile(input, q, dim=None, keepdim=False, *, interpolation="linear", out=N @numpy_to_torch_style_args @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("float16", "bool", "integer")}, "torch") def std(input, dim=None, unbiased=True, keepdim=False, *, out=None): return ivy.std(input, axis=dim, correction=int(unbiased), keepdims=keepdim, out=out) @numpy_to_torch_style_args @to_ivy_arrays_and_back -@with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") +@with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def std_mean(input, dim, unbiased, keepdim=False, *, out=None): temp_std = ivy.std( input, axis=dim, correction=int(unbiased), keepdims=keepdim, out=out @@ -317,37 +321,26 @@ def sum(input, dim=None, keepdim=False, *, dtype=None, out=None): return ivy.sum(input, axis=dim, dtype=dtype, keepdims=keepdim, out=out) +@with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") @to_ivy_arrays_and_back def unique(input, sorted=True, return_inverse=False, return_counts=False, dim=None): if dim is not None: sorted = True results = ivy.unique_all(input, axis=dim, by_value=sorted) - - fields = ["output"] - if return_inverse: - fields.append("inverse_indices") - if return_counts: - fields.append("counts") - - Results = namedtuple("Results", fields) - - values = [results.values] + ret = (results.values,) if return_counts or return_inverse else results.values if return_inverse: inverse_indices = results.inverse_indices - if dim is None: inverse_indices = inverse_indices.reshape(input.shape) - - values.append(inverse_indices) + ret += (inverse_indices,) if return_counts: - values.append(results.counts) - - return Results(*values) + ret += (results.counts,) + return ret @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "complex", ) @@ -355,7 +348,7 @@ def unique(input, sorted=True, return_inverse=False, return_counts=False, dim=No "torch", ) @to_ivy_arrays_and_back -def unique_consecutive(input, return_inverse, return_counts, dim): +def unique_consecutive(input, return_inverse=False, return_counts=False, dim=None): output, inverse_indices, counts = ivy.unique_consecutive(input, axis=dim) ret = (output,) if return_inverse: @@ -369,7 +362,7 @@ def unique_consecutive(input, return_inverse, return_counts, dim): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -384,7 +377,7 @@ def var(input, dim, unbiased, keepdim=False, *, out=None): @to_ivy_arrays_and_back @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) diff --git a/ivy/functional/frontends/torch/special/__init__.py b/ivy/functional/frontends/torch/special/__init__.py new file mode 100644 index 0000000000000..7dc36a681a948 --- /dev/null +++ b/ivy/functional/frontends/torch/special/__init__.py @@ -0,0 +1 @@ +from .special_funcs import * diff --git a/ivy/functional/frontends/torch/special/special_funcs.py b/ivy/functional/frontends/torch/special/special_funcs.py new file mode 100644 index 0000000000000..738fcaf278fa2 --- /dev/null +++ b/ivy/functional/frontends/torch/special/special_funcs.py @@ -0,0 +1,25 @@ +import ivy +from ivy.func_wrapper import ( + with_unsupported_dtypes, +) +from ivy.functional.frontends.torch.func_wrapper import ( + to_ivy_arrays_and_back, +) + + +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") +@to_ivy_arrays_and_back +def erfc(input, *, out=None): + return 1.0 - ivy.erf(input, out=out) + + +@with_unsupported_dtypes({"2.2 and below": ("float16", "complex", "bfloat16")}, "torch") +@to_ivy_arrays_and_back +def erfcx(input, *, out=None): + ret = erfc(input) * ivy.exp(input**2) + return ret + + +@to_ivy_arrays_and_back +def erfinv(input, *, out=None): + return ivy.erfinv(input, out=out) diff --git a/ivy/functional/frontends/torch/tensor.py b/ivy/functional/frontends/torch/tensor.py index ba131b8fa34d7..95d737be609a3 100644 --- a/ivy/functional/frontends/torch/tensor.py +++ b/ivy/functional/frontends/torch/tensor.py @@ -5,7 +5,6 @@ # local import ivy import ivy.functional.frontends.torch as torch_frontend -import ivy.functional.frontends.torch.nn.functional as torch_frontend_nn from ivy.functional.frontends.numpy.creation_routines.from_existing_data import ( array as np_frontend_array, ) @@ -85,6 +84,10 @@ def T(self): return self return torch_frontend.permute(self, list(range(self.ndim))[::-1]) + @property + def mH(self): + return torch_frontend.adjoint(self) + @property def data(self): return torch_frontend.tensor( @@ -138,7 +141,7 @@ def reshape(self, *args, shape=None): if shape is not None: return torch_frontend.reshape(self, shape) if args: - if isinstance(args[0], (tuple, list, ivy.Shape)): + if isinstance(args[0], (tuple, list, ivy.Shape, ivy.NativeShape)): shape = args[0] return torch_frontend.reshape(self, shape) else: @@ -146,20 +149,20 @@ def reshape(self, *args, shape=None): else: raise ValueError("reshape() got no values for argument 'shape'") - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") - @with_unsupported_dtypes({"2.5.1 and below": ("float16",)}, "paddle") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.6.0 and below": ("float16",)}, "paddle") def reshape_as(self, other): return torch_frontend.reshape(self, other.shape) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def add(self, other, *, alpha=1): return torch_frontend.add(self, other, alpha=alpha) - # @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + # @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def divide(self, other, *, out=None): return torch_frontend.divide(self, other, out=out) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def sub(self, other, *, alpha=1): return torch_frontend.sub(self, other, alpha=alpha) @@ -174,105 +177,105 @@ def any(self, dim=None, keepdim=False): def all(self, dim=None, keepdim=False): return torch_frontend.all(self, dim=dim, keepdim=keepdim) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def add_(self, other, *, alpha=1): self.ivy_array = self.add(other, alpha=alpha).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addmm(self, mat1, mat2, *, beta=1, alpha=1): return torch_frontend.addmm(self, mat1, mat2, beta=beta, alpha=alpha) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addmm_(self, mat1, mat2, *, beta=1, alpha=1): self.ivy_array = self.addmm(mat1, mat2, beta=beta, alpha=alpha).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addmv(self, mat, vec, *, beta=1, alpha=1): return torch_frontend.addmv(self, mat, vec, beta=beta, alpha=alpha) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addmv_(self, mat, vec, *, beta=1, alpha=1): self.ivy_array = torch_frontend.addmv( self, mat, vec, beta=beta, alpha=alpha ).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addbmm(self, batch1, batch2, *, beta=1, alpha=1): return torch_frontend.addbmm(self, batch1, batch2, beta=beta, alpha=alpha) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addbmm_(self, batch1, batch2, *, beta=1, alpha=1): self.ivy_array = self.addbmm(batch1, batch2, beta=beta, alpha=alpha).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def subtract_(self, other, *, alpha=1): self.ivy_array = self.sub(other, alpha=alpha).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def asin(self): return torch_frontend.asin(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def asin_(self): self.ivy_array = self.asin().ivy_array return self @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def sum(self, dim=None, keepdim=False, *, dtype=None): return torch_frontend.sum(self, dim=dim, keepdim=keepdim, dtype=dtype) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def sin(self): return torch_frontend.sin(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def sin_(self): self.ivy_array = self.sin().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def sinh(self): return torch_frontend.sinh(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def sinh_(self): self.ivy_array = self.sinh().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def cos(self): return torch_frontend.cos(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def cos_(self): self.ivy_array = self.cos().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def cosh(self): return torch_frontend.cosh(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def cosh_(self): self.ivy_array = self.cosh().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def atan(self): return torch_frontend.atan(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def atan_(self): self.ivy_array = self.atan().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def atan2(self, other): return torch_frontend.atan2(self, other) @@ -298,7 +301,7 @@ def view(self, *args, size=None): shape_tup = size elif args and not ivy.exists(size): if ( - isinstance(args[0], (tuple, list, ivy.Shape)) + isinstance(args[0], (tuple, list, ivy.Shape, ivy.NativeShape)) or type(args[0]).__name__ == "Size" ) and len(args) == 1: shape_tup = args[0] @@ -318,56 +321,56 @@ def float(self, memory_format=None): def double(self): return self.to(torch_frontend.float64) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def asinh(self): return torch_frontend.asinh(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def asinh_(self): self.ivy_array = self.asinh().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def tan(self): return torch_frontend.tan(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def tan_(self): self.ivy_array = self.tan().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def tanh(self): return torch_frontend.tanh(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def tanh_(self): self.ivy_array = self.tanh().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def atanh(self): return torch_frontend.atanh(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def atanh_(self): self.ivy_array = self.atanh().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def log(self): return torch_frontend.log(self) - @with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") + @with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") def log2_(self): self.ivy_array = self.log2().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def logit(self): return torch_frontend.logit(self) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "uint16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "uint16")}, "torch") def copy_(self, other, non_blocking=False): ivy.utils.assertions.check_one_way_broadcastable( self.ivy_array.shape, torch_frontend.tensor(other).ivy_array.shape @@ -375,31 +378,31 @@ def copy_(self, other, non_blocking=False): self._ivy_array = torch_frontend.tensor(other).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def log_(self): self.ivy_array = self.log().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def log2(self): return torch_frontend.log2(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def relu(self): - return torch_frontend_nn.relu(self) + return torch_frontend.nn.functional.relu(self) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") def amax(self, dim=None, keepdim=False): return torch_frontend.amax(self, dim=dim, keepdim=keepdim) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") def amin(self, dim=None, keepdim=False): return torch_frontend.amin(self, dim=dim, keepdim=keepdim) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("complex", "float16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("complex", "float16")}, "torch") def aminmax(self, dim=None, keepdim=False): return torch_frontend.aminmax(self, dim=dim, keepdim=keepdim) @@ -410,7 +413,7 @@ def abs_(self): self.ivy_array = self.abs().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def logical_and(self, other): return torch_frontend.logical_and(self, other) @@ -421,11 +424,11 @@ def logical_not_(self): self.ivy_array = ivy.astype(self.logical_not().ivy_array, self.dtype) return self - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def logical_or(self, other): return torch_frontend.logical_or(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def logical_xor(self, other): return torch_frontend.logical_xor(self, other) @@ -435,14 +438,14 @@ def bitwise_not(self): def bitwise_and(self, other): return torch_frontend.bitwise_and(self, other) - @with_supported_dtypes({"2.1.2 and below": ("integer",)}, "torch") + @with_supported_dtypes({"2.2 and below": ("integer",)}, "torch") def bitwise_or(self, other): return torch_frontend.bitwise_or(self, other) def bitwise_left_shift(self, other): return torch_frontend.bitwise_left_shift(self, other) - @with_supported_dtypes({"2.1.2 and below": ("integer",)}, "torch") + @with_supported_dtypes({"2.2 and below": ("integer",)}, "torch") def bitwise_or_(self, other): self.ivy_array = self.bitwise_or(other).ivy_array return self @@ -465,18 +468,22 @@ def new_ones( if device is None: device = self.device if size is None: - size = args[0] if isinstance(args[0], (tuple, list, ivy.Shape)) else args + size = ( + args[0] + if isinstance(args[0], (tuple, list, ivy.Shape, ivy.NativeShape)) + else args + ) return torch_frontend.ones( size, dtype=dtype, device=device, requires_grad=requires_grad ) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def floor(self, *, out=None): return torch_frontend.floor(self) @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "uint8", "uint32", @@ -493,7 +500,7 @@ def not_equal(self, other, *, out=None): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "uint8", "uint32", @@ -509,22 +516,25 @@ def not_equal_(self, other, *, out=None): self.ivy_array = self.not_equal(other).ivy_array return self + def eq(self, other): + return torch_frontend.eq(self, other) + def equal(self, other): return torch_frontend.equal(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def erf(self, *, out=None): return torch_frontend.erf(self, out=out) @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "bfloat16")}, "torch" + {"2.2 and below": ("float32", "float64", "bfloat16")}, "torch" ) def erf_(self, *, out=None): self.ivy_array = self.erf(out=out).ivy_array return self @with_supported_device_and_dtypes( - {"2.1.0 and below": {"cpu": ("float32", "float64")}}, + {"2.2 and below": {"cpu": ("float32", "float64")}}, "torch", ) def erfc_(self, *, out=None): @@ -566,7 +576,9 @@ def to(self, *args, **kwargs): ) return cast_tensor if ( - isinstance(args[0], (ivy.Dtype, ivy.NativeDtype)) + isinstance(args[0], ivy.NativeDtype) + or isinstance(args[0], ivy.Dtype) + and hasattr(args[0], "as_native_dtype") or args[0] in ivy._all_ivy_dtypes_str ): if self.dtype == ivy.as_ivy_dtype(args[0]): @@ -624,11 +636,11 @@ def to(self, *args, **kwargs): ) return cast_tensor - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def acos(self): return torch_frontend.acos(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def acos_(self): self.ivy_array = self.acos().ivy_array return self @@ -648,7 +660,7 @@ def new_tensor( _data = ivy.asarray(data, copy=True, dtype=dtype, device=device) return torch_frontend.tensor(_data) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def view_as(self, other): return self.view(size=other.shape) @@ -656,11 +668,14 @@ def expand(self, *args, size=None): if args and size: raise TypeError("expand() got multiple values for argument 'size'") if args: - if isinstance(args[0], (tuple, list, ivy.Shape)): + if isinstance(args[0], (tuple, list, ivy.Shape, ivy.NativeShape)): size = args[0] else: size = args - + if isinstance(size, (tuple, list)): + size = tuple( + s.item() if isinstance(s, torch_frontend.Tensor) else s for s in size + ) return torch_frontend.tensor(ivy.expand(self.ivy_array, tuple(size))) def expand_as(self, other): @@ -677,7 +692,7 @@ def detach_(self): self.ivy_array = self.detach().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("uint16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("uint16",)}, "torch") @numpy_to_torch_style_args def unsqueeze(self, dim): return torch_frontend.unsqueeze(self, dim) @@ -751,9 +766,20 @@ def new_empty( def unfold(self, dimension, size, step): slices = [] - for i in range(0, self.shape[dimension] - size + 1, step): - slices.append(self.ivy_array[i : i + size]) - return torch_frontend.stack(slices) + self_shape = tuple(self.shape) + for i in range(0, self_shape[dimension] - size + 1, step): + slicing = [slice(None)] * len(self.shape) + slicing[dimension] = slice(i, i + size) + slices.append(self.ivy_array[tuple(slicing)]) + stacked = torch_frontend.stack(slices, dim=dimension) + new_shape = list(self.shape) + num_slices = (self.shape[dimension] - size) // step + 1 + new_shape[dimension] = num_slices + new_shape.insert(dimension + 1, size) + reshaped = stacked.reshape(new_shape) + dims = list(range(len(stacked.shape))) + dims[-2], dims[-1] = dims[-1], dims[-2] + return reshaped.permute(*dims) def long(self, memory_format=None): self.ivy_array = ivy.astype(self.ivy_array, ivy.int64, copy=False) @@ -765,7 +791,7 @@ def max(self, dim=None, keepdim=False): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "complex", "bfloat16", "bool", @@ -791,15 +817,18 @@ def is_cuda(self): def is_meta(self): return "meta" in ivy.dev(self.ivy_array) - @with_unsupported_dtypes({"2.1.2 and below": ("uint16", "bool")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("uint16", "bool")}, "torch") def positive(self): return torch_frontend.positive(self) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def pow(self, exponent): return torch_frontend.pow(self, exponent) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + def unflatten(self, dim, sizes): + return torch_frontend.unflatten(self, dim, sizes) + + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def pow_(self, exponent): self.ivy_array = self.pow(exponent).ivy_array return self @@ -810,17 +839,17 @@ def size(self, dim=None): return shape try: return shape[dim] - except IndexError: + except IndexError as e: raise IndexError( f"Dimension out of range (expected to be in range of [{len(shape)}," f" {len(shape) - 1}], but got {dim}" - ) + ) from e def matmul(self, other): return torch_frontend.matmul(self, other) @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def matrix_power(self, n, *, out=None): return torch_frontend.linalg.matrix_power(self, n, out=out) @@ -829,20 +858,20 @@ def argwhere(self): return torch_frontend.argwhere(self) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("complex", "bool")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("complex", "bool")}, "torch") def argmax(self, dim=None, keepdim=False): return torch_frontend.argmax(self, dim=dim, keepdim=keepdim) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") def argmin(self, dim=None, keepdim=False): return torch_frontend.argmin(self, dim=dim, keepdim=keepdim) - @with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") def argsort(self, dim=-1, descending=False): return torch_frontend.argsort(self, dim=dim, descending=descending) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def ceil(self): return torch_frontend.ceil(self) @@ -856,7 +885,7 @@ def permute(self, *args, dims=None): if dims is not None: return torch_frontend.permute(self, dims) if args: - if isinstance(args[0], (tuple, list, ivy.Shape)): + if isinstance(args[0], (tuple, list, ivy.Shape, ivy.NativeShape)): dims = args[0] return torch_frontend.permute(self, dims) else: @@ -865,22 +894,22 @@ def permute(self, *args, dims=None): raise ValueError("permute() got no values for argument 'dims'") @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def mean(self, dim=None, keepdim=False): return torch_frontend.mean(self, dim=dim, keepdim=keepdim) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") @numpy_to_torch_style_args def nanmean(self, dim=None, keepdim=False): return torch_frontend.nanmean(self, dim=dim, keepdim=keepdim) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") @numpy_to_torch_style_args def nansum(self, dim=None, keepdim=False): return torch_frontend.nansum(self, dim=dim, keepdim=keepdim) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def median(self, dim=None, keepdim=False): return torch_frontend.median(self, dim=dim, keepdim=keepdim) @@ -898,32 +927,32 @@ def flatten(self, start_dim=0, end_dim=-1): return torch_frontend.flatten(self, start_dim, end_dim) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def cumsum(self, dim, *, dtype=None): return torch_frontend.cumsum(self, dim, dtype=dtype) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def cumsum_(self, dim, *, dtype=None): self.ivy_array = self.cumsum(dim, dtype=dtype).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def inverse(self): return torch_frontend.inverse(self) - @with_unsupported_dtypes({"2.1.2 and below": ("bool", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bool", "bfloat16")}, "torch") def neg(self): return torch_frontend.negative(self) - @with_unsupported_dtypes({"2.1.2 and below": ("bool",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bool",)}, "torch") def neg_(self): self.ivy_array = torch_frontend.negative(self).ivy_array return self __neg__ = neg - @with_unsupported_dtypes({"2.1.2 and below": ("bool", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bool", "bfloat16")}, "torch") def negative(self): return torch_frontend.negative(self) @@ -946,10 +975,10 @@ def type(self, dtype=None, non_blocking=False, **kwargs): else: return str(self.dtype) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def type_as(self, other): if self.dtype != other.dtype: - self.ivy_array = ivy.astype(self.ivy_array, other.dtype) + return torch_frontend.tensor(ivy.astype(self.ivy_array, other.dtype)) return self def byte(self, memory_format=None): @@ -961,7 +990,7 @@ def squeeze(self, dim=None): return torch_frontend.squeeze(self, dim) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("uint16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("uint16",)}, "torch") def squeeze_(self, dim=None): self.ivy_array = self.squeeze(dim).ivy_array return self @@ -985,35 +1014,39 @@ def tril_(self, diagonal=0): def index_select(self, dim, index): return torch_frontend.index_select(self, dim, index) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def clamp(self, min=None, max=None): return torch_frontend.clamp(self, min=min, max=max) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def clamp_(self, min=None, max=None): self.ivy_array = self.clamp(min=min, max=max).ivy_array return self @with_unsupported_dtypes( - {"2.1.2 and below": ("bool", "bfloat16", "float16", "complex")}, "torch" + {"2.2 and below": ("bool", "bfloat16", "float16", "complex")}, "torch" ) def clamp_min(self, min=None): return torch_frontend.clamp(self, min=min) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + def clamp_min_(self, min=None): + self.ivy_array = self.clamp_min(min).ivy_array + return self + + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def sqrt(self): return torch_frontend.sqrt(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def rsqrt(self): return torch_frontend.rsqrt(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def rsqrt_(self): self.ivy_array = self.rsqrt().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def sqrt_(self): self.ivy_array = self.sqrt().ivy_array return self @@ -1024,7 +1057,7 @@ def where(self, condition, other): def clone(self, memory_format=None): return torch_frontend.tensor(ivy.array(self.ivy_array, copy=True)) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def acosh(self): return torch_frontend.acosh(self) @@ -1037,38 +1070,38 @@ def masked_fill_(self, mask, value): self.ivy_array = self.masked_fill(mask, value).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def index_add_(self, dim, index, source, *, alpha=1): self.ivy_array = torch_frontend.index_add( self, dim, index, source, alpha=alpha ).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def index_add(self, dim, index, source, *, alpha=1): return torch_frontend.index_add( self._ivy_array, dim, index, source, alpha=alpha ) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def acosh_(self): self.ivy_array = self.acosh().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def numpy(self): return np_frontend_array(self.ivy_array) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def sigmoid(self): return torch_frontend.sigmoid(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def sigmoid_(self): self.ivy_array = self.sigmoid().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def softmax(self, dim=None, dtype=None): return torch_frontend.nn.functional.softmax(self, dim=dim, dtype=dtype) @@ -1081,7 +1114,7 @@ def repeat(self, *args, repeats=None): "repeat() got multiple values for argument 'repeats'" ) if args: - if isinstance(args[0], (tuple, list, ivy.Shape)): + if isinstance(args[0], (tuple, list, ivy.Shape, ivy.NativeShape)): repeats = args[0] else: repeats = args @@ -1100,7 +1133,7 @@ def remainder(self, other, *, out=None): return torch_frontend.remainder(self, other, out=out) @with_supported_dtypes( - {"2.1.2 and below": ("float16", "float32", "float64", "bfloat16")}, "torch" + {"2.2 and below": ("float16", "float32", "float64", "bfloat16")}, "torch" ) def reciprocal_(self): self.ivy_array = torch_frontend.reciprocal(self).ivy_array @@ -1118,35 +1151,42 @@ def bitwise_and_(self, other): self.ivy_array = self.bitwise_and(other).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def atan2_(self, other): self.ivy_array = self.atan2(other).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def fmax(self, other): return torch_frontend.fmax(self, other) def fmin(self, other): return torch_frontend.fmin(self, other) + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") + def log_softmax(self, dim=None, _stack_level=3, dtype=None): + return torch_frontend.nn.functional.log_softmax(self, dim=dim, dtype=dtype) + + def isfinite(self): + return torch_frontend.isfinite(self) + def msort(self): return torch_frontend.msort(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def trunc(self): return torch_frontend.trunc(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def trunc_(self): self.ivy_array = self.trunc().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def fix(self): return torch_frontend.fix(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def fix_(self): self.ivy_array = self.fix().ivy_array return self @@ -1157,11 +1197,11 @@ def isinf(self): def is_complex(self): return torch_frontend.is_complex(self._ivy_array) - @with_unsupported_dtypes({"2.1.2 and below": ("uint16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("uint16", "bfloat16")}, "torch") def is_floating_point(self): return torch_frontend.is_floating_point(self._ivy_array) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def isreal(self): return torch_frontend.isreal(self._ivy_array) @@ -1172,38 +1212,49 @@ def addr_(self, vec1, vec2, *, beta=1, alpha=1): self.ivy_array = self.addr(vec1, vec2, beta=beta, alpha=alpha).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def dot(self, tensor): return torch_frontend.dot(self, tensor) - @with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") - def bernoulli(self, *, generator=None, out=None): - return torch_frontend.bernoulli(self._ivy_array, generator=generator, out=out) + @with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") + def bernoulli(self, p, *, generator=None, out=None): + return torch_frontend.bernoulli( + self._ivy_array, p, generator=generator, out=out + ) + + @with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") + def bernoulli_(self, p, *, generator=None, out=None): + self.ivy_array = self.bernoulli(p, generator=generator, out=out).ivy_array + return self + + def numel(self): + shape = self.shape + return int(ivy.astype(ivy.prod(shape), ivy.int64)) # Special Methods # # -------------------# def __bool__(self): if len(self.shape) == sum(self.shape): - return torch_frontend.tensor(self.ivy_array.to_scalar().__bool__()) + return self.ivy_array.to_scalar().__bool__() raise ValueError( "The truth value of an array with more than one element is ambiguous. " "Use a.any() or a.all()" ) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __add__(self, other): return torch_frontend.add(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __mod__(self, other): return torch_frontend.remainder(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __pow__(self, exponent): return self.pow(exponent) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __rpow__(self, other): return torch_frontend.pow(other, self) @@ -1225,30 +1276,41 @@ def __iter__(self): for i in range(self.shape[0]): yield self[i] - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __radd__(self, other): return torch_frontend.add(other, self) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __mul__(self, other): return torch_frontend.mul(self, other) - @with_unsupported_dtypes({"2.1.2 and below": "bfloat16"}, "torch") + @with_unsupported_dtypes({"2.2 and below": "bfloat16"}, "torch") def __matmul__(self, other): return torch_frontend.matmul(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes( + { + "2.2 and below": ( + "float16", + "int8", + "int16", + "bool", + "uint8", + ) + }, + "torch", + ) def __rmul__(self, other): return torch_frontend.mul(other, self) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __sub__(self, other): return torch_frontend.subtract(self, other) def __truediv__(self, other): return torch_frontend.div(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def __floordiv__(self, other): return torch_frontend.floor_divide(self, other) @@ -1303,45 +1365,52 @@ def __float__(self): item = item.real return float(item) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __eq__(self, other): return torch_frontend.eq(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("complex",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("complex",)}, "torch") def __gt__(self, other): return torch_frontend.greater(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __ge__(self, other): return torch_frontend.greater_equal(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __ne__(self, other): return self.ne(other) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __rsub__(self, other): return torch_frontend.subtract(other, self) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __lt__(self, other): return torch_frontend.less(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __le__(self, other): return torch_frontend.less_equal(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def __or__(self, other): return torch_frontend.bitwise_or(self, other) - @with_supported_dtypes({"2.1.2 and below": ("integer", "bool")}, "torch") + @with_supported_dtypes({"2.2 and below": ("integer", "bool")}, "torch") def __invert__(self): return torch_frontend.bitwise_not(self) def __and__(self, other): return torch_frontend.bitwise_and(self, other) + def __iand__(self, other): + self.ivy_array = self.bitwise_and(other).ivy_array + return self + + def new(self): + return torch_frontend.tensor([], dtype=self.dtype, device=self.device) + def __array__(self, dtype=None): if dtype is None: return ivy.to_numpy(self.ivy_array) @@ -1369,8 +1438,8 @@ def item(self): ) @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") - def cumprod(self, dim, dtype): + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") + def cumprod(self, dim, dtype=None): return torch_frontend.cumprod(self, dim, dtype=dtype) @numpy_to_torch_style_args @@ -1382,26 +1451,26 @@ def cov(self, /, *, correction=1, fweights=None, aweights=None): self, correction=correction, fweights=fweights, aweights=aweights ) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, "torch") def exp(self): return torch_frontend.exp(self) @with_supported_dtypes( - {"2.1.2 and below": ("bfloat16", "float32", "float64")}, "torch" + {"2.2 and below": ("bfloat16", "float32", "float64")}, "torch" ) def expm1(self): return torch_frontend.expm1(self) # remove "bfloat16" from the below decorator after fixing ivy.Array.__repr__ method @with_unsupported_dtypes( - {"2.1.2 and below": ("bfloat16", "float16", "complex")}, "torch" + {"2.2 and below": ("bfloat16", "float16", "complex")}, "torch" ) def expm1_(self): self.ivy_array = torch_frontend.expm1(self).ivy_array return self # fmt: off - @with_unsupported_dtypes({"2.1.2 and below": ("int8", "int16", "int32", "int64", "uint8", "bool", "float16",)},"torch",) # noqa + @with_unsupported_dtypes({"2.2 and below": ("int8", "int16", "int32", "int64", "uint8", "bool", "float16",)},"torch",) # noqa def exp_(self): self.ivy_array = self.exp().ivy_array return self @@ -1410,33 +1479,33 @@ def exp_(self): def mul(self, other): return torch_frontend.mul(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def ceil_(self): self.ivy_array = torch_frontend.ceil(self).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def mul_(self, other): self.ivy_array = self.mul(other).ivy_array # the return dtype is the same as the input dtype self.ivy_array = self.to(self.dtype).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, "torch") def round(self, *, decimals=0): return torch_frontend.round(self, decimals=decimals) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, "torch") def round_(self, *, decimals=0): self.ivy_array = self.round(decimals=decimals).ivy_array return self @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def cross(self, other, dim=-1): return torch_frontend.cross(self, other, dim=dim) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def det(self): return torch_frontend.det(self) @@ -1444,9 +1513,10 @@ def reciprocal(self): return torch_frontend.reciprocal(self) def fill_(self, value): - self.ivy_array = torch_frontend.full_like( + ret = torch_frontend.full_like( self, value, dtype=self.dtype, device=self.device - ).ivy_array + ) + self.ivy_array = ivy.inplace_update(self.ivy_array, ret) return self def nonzero(self, as_tuple=False): @@ -1455,13 +1525,13 @@ def nonzero(self, as_tuple=False): def mm(self, mat2): return torch_frontend.mm(self, mat2) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, "torch") def square(self): return torch_frontend.square(self._ivy_array) @with_supported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "float32", "float64", @@ -1480,18 +1550,19 @@ def square_(self): self.ivy_array = torch_frontend.square(self._ivy_array).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def log10(self): return torch_frontend.log10(self._ivy_array) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def log10_(self): self.ivy_array = self.log10().ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("uint16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("uint16",)}, "torch") def zero_(self): - self.ivy_array = torch_frontend.zeros_like(self).ivy_array + ret = torch_frontend.zeros_like(self) + self.ivy_array = ivy.inplace_update(self.ivy_array, ret) return self def short(self, memory_format=None): @@ -1499,7 +1570,7 @@ def short(self, memory_format=None): return self @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def prod(self, dim=None, keepdim=False, *, dtype=None): return torch_frontend.prod(self, dim=dim, keepdim=keepdim, dtype=dtype) @@ -1511,7 +1582,7 @@ def div_(self, other, *, rounding_mode=None): return self @with_supported_dtypes( - {"2.1.2 and below": ("float16", "float32", "float64", "bfloat16")}, "torch" + {"2.2 and below": ("float16", "float32", "float64", "bfloat16")}, "torch" ) def true_divide_(self, other): self.ivy_array = self.div(other, rounding_mode=None).ivy_array @@ -1527,26 +1598,26 @@ def normal_(self, mean=0, std=1, *, generator=None): ) return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addcdiv(self, tensor1, tensor2, *, value=1): return torch_frontend.addcdiv(self, tensor1, tensor2, value=value) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addcmul(self, tensor1, tensor2, *, value=1): return torch_frontend.addcmul(self, tensor1, tensor2, value=value) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addcmul_(self, tensor1, tensor2, *, value=1): self.ivy_array = self.addcmul(tensor1, tensor2, value=value).ivy_array return self sign_decorator_dtypes = ("float16", "complex", "bool") - @with_unsupported_dtypes({"2.1.2 and below": sign_decorator_dtypes}, "torch") + @with_unsupported_dtypes({"2.2 and below": sign_decorator_dtypes}, "torch") def sign(self): return torch_frontend.sign(self._ivy_array) - @with_unsupported_dtypes({"2.1.2 and below": sign_decorator_dtypes}, "torch") + @with_unsupported_dtypes({"2.2 and below": sign_decorator_dtypes}, "torch") def sign_(self): self.ivy_array = self.sign().ivy_array return self @@ -1557,11 +1628,11 @@ def std(self, dim=None, unbiased=True, keepdim=False, *, out=None): self, dim=dim, unbiased=unbiased, keepdim=keepdim, out=out ) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def fmod(self, other, *, out=None): return torch_frontend.fmod(self, other, out=out) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def fmod_(self, other): self.ivy_array = self.fmod(other).ivy_array return self @@ -1572,96 +1643,96 @@ def norm(self, p="fro", dim=None, keepdim=False, dtype=None): def tolist(self): return self._ivy_array.to_list() - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def multiply(self, other, *, out=None): return torch_frontend.multiply(self, other, out=out) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def multiply_(self, other, *, out=None): self.ivy_array = torch_frontend.multiply(self, other, out=out).ivy_array return self @numpy_to_torch_style_args - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "complex")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") def topk(self, k, dim=None, largest=True, sorted=True): return torch_frontend.topk(self, k, dim=dim, largest=largest, sorted=sorted) rshift_dtypes = ("float16", "bfloat16", "float32", "float64", "bool", "complex") - @with_unsupported_dtypes({"2.1.2 and below": rshift_dtypes}, "torch") + @with_unsupported_dtypes({"2.2 and below": rshift_dtypes}, "torch") def bitwise_right_shift(self, other, *, out=None): return torch_frontend.bitwise_right_shift(self._ivy_array, other) @with_supported_dtypes( - {"2.1.2 and below": ("uint8", "int8", "int32", "int64")}, "torch" + {"2.2 and below": ("uint8", "int8", "int32", "int64")}, "torch" ) def bitwise_right_shift_(self, other, *, out=None): self.ivy_array = self.bitwise_right_shift(other, out=out).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def logdet(self): chol = torch_frontend.cholesky(self) return 2 * torch_frontend.sum( torch_frontend.log(torch_frontend.real(torch_frontend.diagonal(chol))) ) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def copysign(self, other, *, out=None): return torch_frontend.copysign(self, other, out=out) @with_supported_dtypes( - {"2.1.2 and below": ("float16", "float32", "float64")}, "torch" + {"2.2 and below": ("float16", "float32", "float64")}, "torch" ) def copysign_(self, other, *, out=None): self.ivy_array = self.copysign(other, out=out).ivy_array return self @with_unsupported_dtypes( - {"2.1.2 and below": ("complex", "bfloat16", "bool")}, "torch" + {"2.2 and below": ("complex", "bfloat16", "bool")}, "torch" ) def greater(self, other, *, out=None): return torch_frontend.greater(self, other, out=out) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "bool")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "bool")}, "torch") def greater_(self, other): self.ivy_array = ivy.astype(self.greater(other).ivy_array, self.dtype) return self @with_unsupported_dtypes( - {"2.1.2 and below": ("complex", "bfloat16", "bool")}, "torch" + {"2.2 and below": ("complex", "bfloat16", "bool")}, "torch" ) def greater_equal(self, other, *, out=None): return torch_frontend.greater_equal(self, other, out=out) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "bool")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "bool")}, "torch") def greater_equal_(self, other): self.ivy_array = ivy.astype(self.greater_equal(other).ivy_array, self.dtype) return self @with_unsupported_dtypes( - {"2.1.2 and below": ("complex", "bfloat16", "bool")}, "torch" + {"2.2 and below": ("complex", "bfloat16", "bool")}, "torch" ) def less(self, other, *, out=None): return torch_frontend.less(self, other, out=out) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "bool")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "bool")}, "torch") def less_(self, other): self.ivy_array = ivy.astype(self.less(other).ivy_array, self.dtype) return self @with_unsupported_dtypes( - {"2.1.2 and below": ("complex", "bfloat16", "bool")}, "torch" + {"2.2 and below": ("complex", "bfloat16", "bool")}, "torch" ) def less_equal(self, other, *, out=None): return torch_frontend.less_equal(self, other, out=out) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "bool")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "bool")}, "torch") def less_equal_(self, other): self.ivy_array = ivy.astype(self.less_equal(other).ivy_array, self.dtype) return self - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def eq_(self, other): self.ivy_array = ivy.astype( torch_frontend.eq(self, other).ivy_array, self.dtype @@ -1690,16 +1761,18 @@ def stride(self, dim=None): return strides @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "bfloat16")}, "torch" + {"2.2 and below": ("float32", "float64", "bfloat16")}, "torch" ) def log1p(self): promoted_type = ivy.promote_types(self.dtype, "float32") - return torch_frontend.log1p(self).to(promoted_type) + res = torch_frontend.log1p(self) + return res.to(promoted_type) - @with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") + @with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") def log1p_(self): promoted_type = ivy.promote_types(self.dtype, "float32") - self.ivy_array = torch_frontend.log1p(self).to(promoted_type).ivy_array + res = torch_frontend.log1p(self) + self.ivy_array = res.to(promoted_type).ivy_array return self def baddbmm(self, batch1, batch2, *, beta=1, alpha=1): @@ -1716,14 +1789,14 @@ def baddbmm_(self, batch1, batch2, *, beta=1, alpha=1): def bmm(self, mat2): return torch_frontend.bmm(self, mat2=mat2) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def floor_(self): self.ivy_array = self.floor().ivy_array return self @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "complex", "float64", @@ -1739,7 +1812,7 @@ def diff(self, n=1, dim=-1, prepend=None, append=None): def diag(self, diagonal=0): return torch_frontend.diag(self, diagonal=diagonal) - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16",)}, "torch") def diagonal(self, offset=0, dim1=0, dim2=1): return torch_frontend.diagonal(self, offset=offset, dim1=dim1, dim2=dim2) @@ -1747,14 +1820,14 @@ def gather(self, dim, index): return torch_frontend.gather(self, dim=dim, index=index) @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) def scatter_add_(self, dim, index, src): self.ivy_array = ivy.put_along_axis(self.ivy_array, index, src, dim, mode="sum") return self @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) def scatter_(self, dim, index, src, *, reduce=None): if reduce is None: @@ -1771,7 +1844,7 @@ def scatter_(self, dim, index, src, *, reduce=None): return self @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) def scatter_reduce_(self, dim, index, src, reduce, *, include_self=True): if reduce == "prod": @@ -1782,19 +1855,19 @@ def scatter_reduce_(self, dim, index, src, reduce, *, include_self=True): return self @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) def scatter_add(self, dim, index, src): return torch_frontend.scatter_add(self, dim, index, src) @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) def scatter(self, dim, index, src): return torch_frontend.scatter_reduce(self, dim, index, src, reduce="replace") @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) def scatter_reduce(self, dim, index, src, reduce, *, include_self=True): return torch_frontend.scatter_reduce(self, dim, index, src, reduce=reduce) @@ -1805,14 +1878,14 @@ def take_along_dim(self, indices, dim): def movedim(self, source, destination): return torch_frontend.movedim(self, source=source, destination=destination) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def addcdiv_(self, tensor1, tensor2, *, value=1): self.ivy_array = self.addcdiv( tensor1=tensor1, tensor2=tensor2, value=value ).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("bfloat16", "float16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("bfloat16", "float16")}, "torch") def cholesky(self, upper=False): return torch_frontend.cholesky(self, upper=upper) @@ -1851,11 +1924,11 @@ def backward(self, gradient=None, retain_graph=None, create_graph=False): else: next_function(_grad_list[idx]) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def logaddexp(self, other): return torch_frontend.logaddexp(self, other) - @with_unsupported_dtypes({"2.1.2 and below": ("float16",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16",)}, "torch") def logaddexp2(self, other): self.ivy_array = torch_frontend.logaddexp2(self, other).ivy_array return self @@ -1880,17 +1953,17 @@ def adjoint(self): return torch_frontend.adjoint(self) @with_unsupported_dtypes( - {"2.1.2 and below": ("int16", "float16", "bfloat16")}, "torch" + {"2.2 and below": ("int16", "float16", "bfloat16")}, "torch" ) def conj(self): return torch_frontend.conj(self) - @with_unsupported_dtypes({"2.1.2 and below": ("float16", "bfloat16")}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") def svd(self, some=True, compute_uv=True, *, out=None): return torch_frontend.svd(self, some=some, compute_uv=compute_uv, out=out) @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16", "float32", "float64", "complex")}, + {"2.2 and below": ("float16", "bfloat16", "float32", "float64", "complex")}, "torch", ) def gcd(self, other, *, out=None): @@ -1898,7 +1971,7 @@ def gcd(self, other, *, out=None): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", "uint16", @@ -1918,7 +1991,7 @@ def char(self): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", "float32", @@ -1935,7 +2008,7 @@ def lcm(self, other, *, out=None): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", "float32", @@ -1956,7 +2029,7 @@ def lcm_(self, other, *, out=None): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "int8", "uint8", @@ -1973,7 +2046,7 @@ def triu_(self, diagonal=0): return self @with_unsupported_dtypes( - {"2.1.2 and below": ("float16", "bfloat16")}, + {"2.2 and below": ("float16", "bfloat16")}, "torch", ) def quantile(self, q, dim=None, keepdim=False, *, interpolation="linear", out=None): @@ -1983,7 +2056,7 @@ def quantile(self, q, dim=None, keepdim=False, *, interpolation="linear", out=No @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "int8", "int16", "uint8", @@ -2015,7 +2088,7 @@ def random_( @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "integer", "unsigned", "bfloat16", @@ -2034,13 +2107,13 @@ def uniform_(self, from_=0, to=1, *, generator=None): ) return self - @with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") + @with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") def frac(self, name=None): return torch_frontend.frac(self._ivy_array) @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -2052,7 +2125,7 @@ def sinc(self): @with_supported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float32", "float64", "bfloat16", @@ -2064,7 +2137,7 @@ def sinc_(self): self.ivy_array = torch_frontend.sinc(self).ivy_array return self - @with_unsupported_dtypes({"2.1.2 and below": ("uint8",)}, "torch") + @with_unsupported_dtypes({"2.2 and below": ("uint8",)}, "torch") def index_fill(self, dim, index, value): arr = torch_frontend.moveaxis(self, dim, 0) arr[ivy.to_list(index)] = value @@ -2073,7 +2146,7 @@ def index_fill(self, dim, index, value): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "int8", "uint8", @@ -2096,7 +2169,7 @@ def unique_consecutive(self, return_inverse, return_counts, dim): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "uint16", "uint32", "uint64", @@ -2113,7 +2186,7 @@ def cummax(self, dim): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "int8", "uint8", @@ -2131,7 +2204,7 @@ def triu(self, diagonal=0): return torch_frontend.triu(self, diagonal) @with_unsupported_dtypes( - {"2.1.2 and below": ("bfloat16",)}, + {"2.2 and below": ("bfloat16",)}, "torch", ) def xlogy_(self, *, other, out=None): @@ -2140,7 +2213,7 @@ def xlogy_(self, *, other, out=None): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "uint8", "uint32", @@ -2157,7 +2230,7 @@ def ne(self, other): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "uint8", "uint32", @@ -2174,7 +2247,7 @@ def ne_(self, other): @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "bfloat16", "int8", "uint8", @@ -2185,6 +2258,7 @@ def ne_(self, other): "float16", "complex128", "complex64", + "bool", ) }, "torch", @@ -2194,7 +2268,7 @@ def unique(self, sorted=True, return_inverse=False, return_counts=False, dim=Non @with_unsupported_dtypes( { - "2.1.2 and below": ( + "2.2 and below": ( "float16", "bfloat16", ) @@ -2204,7 +2278,7 @@ def unique(self, sorted=True, return_inverse=False, return_counts=False, dim=Non def xlogy(self, *, other, out=None): return torch_frontend.xlogy(self, other, out=out) - @with_unsupported_dtypes({"2.1.2 and below": "complex"}, "torch") + @with_unsupported_dtypes({"2.2 and below": "complex"}, "torch") def minimum(self, other, *, out=None): return torch_frontend.minimum(self, other=other, out=out) @@ -2212,7 +2286,7 @@ def rad2deg(self, *, out=None): return torch_frontend.rad2deg(self, out=out) @with_supported_dtypes( - {"2.1.2 and below": "valid"}, + {"2.2 and below": "valid"}, "torch", ) def corrcoef(self): @@ -2227,10 +2301,29 @@ def index_put(self, indices, values, accumulate=False): return ret def index_put_(self, indices, values, accumulate=False): + def _set_add(index): + self[index] += values + + def _set(index): + self[index] = values + if accumulate: - self[indices] += values + ivy.map(fn=_set_add, unique={"index": indices}) else: - self[indices] = values + ivy.map(fn=_set, unique={"index": indices}) + + return self + + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") + def erfinv(self, *, out=None): + return torch_frontend.erfinv(self, out=out) + + @with_unsupported_dtypes({"2.2 and below": ("float16", "complex")}, "torch") + def erfinv_(self, *, out=None): + ret = self.erfinv(out=out) + self._ivy_array = ivy.inplace_update( + self._ivy_array, ivy.astype(ret.ivy_array, self._ivy_array.dtype) + ) return self # Method aliases @@ -2239,7 +2332,6 @@ def index_put_(self, indices, values, accumulate=False): ndimension = dim subtract = sub sub_ = subtract_ - eq = equal arctan = atan arctan_ = atan_ arctan2 = atan2 @@ -2266,6 +2358,7 @@ def index_put_(self, indices, values, accumulate=False): class Size(tuple): def __new__(cls, iterable=()): + iterable = ivy.Shape([]) if iterable == () else iterable new_iterable = [] for i, item in enumerate(iterable): if isinstance(item, int): @@ -2273,11 +2366,14 @@ def __new__(cls, iterable=()): continue try: new_iterable.append(int(item)) - except Exception: - raise TypeError(f"Expected int, but got {type(item)} at index {i}") + except Exception as e: + raise TypeError( + f"Expected int, but got {type(item)} at index {i}" + ) from e return super().__new__(cls, tuple(new_iterable)) - def __init__(self, shape) -> None: + def __init__(self, shape=()) -> None: + shape = ivy.Shape([]) if shape == () else shape self._ivy_shape = shape if isinstance(shape, ivy.Shape) else ivy.shape(shape) def __repr__(self): @@ -2286,3 +2382,6 @@ def __repr__(self): @property def ivy_shape(self): return self._ivy_shape + + def numel(self): + return int(ivy.astype(ivy.prod(self), ivy.int64)) diff --git a/ivy/functional/frontends/torch/tensor_functions.py b/ivy/functional/frontends/torch/tensor_functions.py index 34fa5f29d7034..36dc356c96e7c 100644 --- a/ivy/functional/frontends/torch/tensor_functions.py +++ b/ivy/functional/frontends/torch/tensor_functions.py @@ -4,6 +4,11 @@ from ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back +@to_ivy_arrays_and_back +def broadcast_tensors(*tensors): + return ivy.broadcast_arrays(*tensors) + + @to_ivy_arrays_and_back def is_complex(input): return ivy.is_complex_dtype(input) @@ -31,7 +36,7 @@ def numel(input): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) def scatter(input, dim, index, src): return ivy.put_along_axis(input, index, src, dim, mode="replace") @@ -39,7 +44,7 @@ def scatter(input, dim, index, src): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) def scatter_add(input, dim, index, src): return ivy.put_along_axis(input, index, src, dim, mode="sum") @@ -47,7 +52,7 @@ def scatter_add(input, dim, index, src): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.1.2 and below": ("float32", "float64", "int32", "int64")}, "torch" + {"2.2 and below": ("float32", "float64", "int32", "int64")}, "torch" ) def scatter_reduce(input, dim, index, src, reduce, *, include_self=True): mode_mappings = { diff --git a/ivy/functional/frontends/torch/utilities.py b/ivy/functional/frontends/torch/utilities.py index 48fa393c14410..b53e5fe6aa8e0 100644 --- a/ivy/functional/frontends/torch/utilities.py +++ b/ivy/functional/frontends/torch/utilities.py @@ -20,14 +20,14 @@ def _assert(condition, message): # ------------ # -@with_supported_dtypes({"2.1.2 and above": ("int64",)}, "torch") +@with_supported_dtypes({"2.2 and above": ("int64",)}, "torch") @to_ivy_arrays_and_back def bincount(x, weights=None, minlength=0): return ivy.bincount(x, weights=weights, minlength=minlength) def if_else(cond_fn, body_fn, orelse_fn, vars): - cond_keys = inspect.getargspec(cond_fn).args + cond_keys = inspect.getfullargspec(cond_fn).args cond_vars = dict(zip(cond_keys, vars)) return ivy.if_else(cond_fn, body_fn, orelse_fn, cond_vars) diff --git a/ivy/functional/frontends/torchvision/ops.py b/ivy/functional/frontends/torchvision/ops.py index 4ef4e86eecf44..4d1a27185730e 100644 --- a/ivy/functional/frontends/torchvision/ops.py +++ b/ivy/functional/frontends/torchvision/ops.py @@ -23,9 +23,22 @@ def box_area(boxes): return ivy.prod(boxes[..., 2:] - boxes[..., :2], axis=-1) +@to_ivy_arrays_and_back +def box_iou(boxes1, boxes2): + area1 = box_area(boxes1) + area2 = box_area(boxes2) + lt = ivy.maximum(boxes1[:, None, :2], boxes2[:, :2]) + rb = ivy.minimum(boxes1[:, None, 2:], boxes2[:, 2:]) + wh = (rb - lt).clip(x_min=0) + inter = wh[:, :, 0] * wh[:, :, 1] + union = area1[:, None] + area2 - inter + iou = inter / union + return iou + + @with_unsupported_device_and_dtypes( { - "2.1.2 and below": { + "2.2 and below": { "cpu": ("float16",), } }, @@ -51,7 +64,7 @@ def remove_small_boxes(boxes, min_size): return ivy.nonzero((w >= min_size) & (h >= min_size))[0] -@with_supported_dtypes({"2.1.2 and below": ("float32", "float64")}, "torch") +@with_supported_dtypes({"2.2 and below": ("float32", "float64")}, "torch") @to_ivy_arrays_and_back def roi_align( input, boxes, output_size, spatial_scale=1.0, sampling_ratio=1, aligned=False diff --git a/ivy/functional/ivy/creation.py b/ivy/functional/ivy/creation.py index c032bc3b69134..5a837dcd93bcc 100644 --- a/ivy/functional/ivy/creation.py +++ b/ivy/functional/ivy/creation.py @@ -153,6 +153,7 @@ def _asarray_to_native_arrays_and_back_wrapper(*args, dtype=None, **kwargs): dtype = ivy.default_dtype(dtype=dtype, as_native=True) return to_ivy(fn(*new_args, dtype=dtype, **kwargs)) + _asarray_to_native_arrays_and_back_wrapper._asarray_to_native_arrays_and_back = True return _asarray_to_native_arrays_and_back_wrapper @@ -2021,7 +2022,7 @@ def one_hot( } >>> x = ivy.Container(a=ivy.array([2]), \ - b=ivy.array([]), c=ivy.native_array([4])) + b=ivy.array([], dtype=ivy.int32), c=ivy.native_array([4])) >>> y = 7 >>> z = x.one_hot(y) >>> print(z) diff --git a/ivy/functional/ivy/data_type.py b/ivy/functional/ivy/data_type.py index 8c55058f0d3ce..4b074b58a3795 100644 --- a/ivy/functional/ivy/data_type.py +++ b/ivy/functional/ivy/data_type.py @@ -3,6 +3,7 @@ import logging import inspect import math +import functools from numbers import Number from typing import Union, Tuple, List, Optional, Callable, Iterable, Any import numpy as np @@ -48,6 +49,7 @@ def _is_valid_dtypes_attributes(fn: Callable) -> bool: def _handle_nestable_dtype_info(fn): + @functools.wraps(fn) def _handle_nestable_dtype_info_wrapper(type): if isinstance(type, ivy.Container): type = type.cont_map(lambda x, kc: fn(x)) @@ -96,9 +98,10 @@ def _get_function_list(func): hasattr(nodef, "value") and hasattr(nodef.value, "id") and nodef.value.id not in ["ivy", "self"] + and "_frontend" not in nodef.value.id ): continue - names[nodef.attr] = getattr( + names[ast.unparse(nodef)] = getattr( func, "__self__", getattr( @@ -115,13 +118,14 @@ def _get_function_list(func): def _get_functions_from_string(func_names, module): ret = set() # We only care about the functions in the ivy or the same module - for func_name in func_names.keys(): + for orig_func_name in func_names.keys(): + func_name = orig_func_name.split(".")[-1] if hasattr(ivy, func_name) and callable(getattr(ivy, func_name, None)): ret.add(getattr(ivy, func_name)) - elif hasattr(module, func_name) and callable(getattr(ivy, func_name, None)): + elif hasattr(module, func_name) and callable(getattr(module, func_name, None)): ret.add(getattr(module, func_name)) - elif callable(getattr(func_names[func_name], func_name, None)): - ret.add(getattr(func_names[func_name], func_name)) + elif callable(getattr(func_names[orig_func_name], func_name, None)): + ret.add(getattr(func_names[orig_func_name], func_name)) return ret @@ -147,7 +151,10 @@ def _nested_get(f, base_set, merge_fn, get_fn, wrapper=set): # if it's einops, we need to recurse if not getattr(fn, "__module__", None): continue - if "backend" in fn.__module__: + is_frontend_fn = "frontend" in fn.__module__ + is_backend_fn = "backend" in fn.__module__ and not is_frontend_fn + is_einops_fn = hasattr(fn, "__name__") and "einops" in fn.__name__ + if is_backend_fn: f_supported = get_fn(fn, False) if hasattr(fn, "partial_mixed_handler"): f_supported = merge_fn( @@ -162,9 +169,7 @@ def _nested_get(f, base_set, merge_fn, get_fn, wrapper=set): ) out = merge_fn(wrapper(f_supported), out) continue - elif "frontend" in fn.__module__ or ( - hasattr(fn, "__name__") and "einops" in fn.__name__ - ): + elif is_frontend_fn or (hasattr(fn, "__name__") and is_einops_fn): f_supported = wrapper(get_fn(fn, False)) out = merge_fn(f_supported, out) @@ -174,8 +179,36 @@ def _nested_get(f, base_set, merge_fn, get_fn, wrapper=set): continue fl = _get_function_list(fn) - res = _get_functions_from_string(fl, __import__(fn.__module__)) - to_visit.extend(res) + res = list(_get_functions_from_string(fl, __import__(fn.__module__))) + if is_frontend_fn: + frontends = { + "jax_frontend": "ivy.functional.frontends.jax", + "jnp_frontend": "ivy.functional.frontends.jax.numpy", + "np_frontend": "ivy.functional.frontends.numpy", + "tf_frontend": "ivy.functional.frontends.tensorflow", + "torch_frontend": "ivy.functional.frontends.torch", + "paddle_frontend": "ivy.functional.frontends.paddle", + } + for key in fl: + if "frontend" in key: + frontend_fn = fl[key] + for frontend in frontends: + if frontend in key: + key = key.replace(frontend, frontends[frontend]) + if "(" in key: + key = key.split("(")[0] + frontend_module = ".".join(key.split(".")[:-1]) + if ( + frontend_module == "" + ): # single edge case: fn='frontend_outputs_to_ivy_arrays' + continue + frontend_fl = {key: frontend_fn} + res += list( + _get_functions_from_string( + frontend_fl, importlib.import_module(frontend_module) + ) + ) + to_visit.extend(set(res)) return out @@ -208,8 +241,8 @@ def _get_dtypes(fn, complement=True): # We only care about getting dtype info from the base function # if we do need to at some point use dtype information from the parent function # we can comment out the following condition - is_backend_fn = "backend" in fn.__module__ is_frontend_fn = "frontend" in fn.__module__ + is_backend_fn = "backend" in fn.__module__ and not is_frontend_fn has_unsupported_dtypes_attr = hasattr(fn, "unsupported_dtypes") if not is_backend_fn and not is_frontend_fn and not has_unsupported_dtypes_attr: if complement: @@ -652,7 +685,7 @@ def finfo( >>> x = ivy.array([1.3,2.1,3.4], dtype=ivy.float64) >>> print(ivy.finfo(x)) - finfo(resolution=1e-15, min=-1.7976931348623157e+308, / + finfo(resolution=1e-15, min=-1.7976931348623157e+308, \ max=1.7976931348623157e+308, dtype=float64) >>> x = ivy.array([0.7,8.4,3.14], dtype=ivy.float16) @@ -666,7 +699,7 @@ def finfo( >>> print(ivy.finfo(c)) { x: finfo(resolution=0.001, min=-6.55040e+04, max=6.55040e+04, dtype=float16), - y: finfo(resolution=1e-15, min=-1.7976931348623157e+308, / + y: finfo(resolution=1e-15, min=-1.7976931348623157e+308, \ max=1.7976931348623157e+308, dtype=float64) } """ diff --git a/ivy/functional/ivy/device.py b/ivy/functional/ivy/device.py index 9187040ad1ffc..b3c1c7a72845b 100644 --- a/ivy/functional/ivy/device.py +++ b/ivy/functional/ivy/device.py @@ -743,7 +743,7 @@ def tpu_is_available() -> bool: -------- >>> ivy.set_backend("torch") >>> print(ivy.tpu_is_available()) - True + False """ return ivy.current_backend().tpu_is_available() @@ -826,30 +826,47 @@ def default_device( @handle_exceptions def set_default_device(device: Union[ivy.Device, ivy.NativeDevice], /) -> None: - """Set the default device to given device instance. + """Sets the default device to the argument provided in the function. Parameters ---------- device - The device to set as the default device + The device to be set as the default device. + + Returns + ------- + ret + The new default device. Examples -------- - >>> ivy.set_default_device("cpu") >>> ivy.default_device() 'cpu' - >>> ivy.set_backend("torch") - >>> ivy.set_default_device("gpu:0") - >>> ivy.default_device(as_native=True) - device(type='cuda', index=0) + >>> ivy.set_backend('jax') + >>> ivy.set_default_device('gpu:0') + >>> ivy.default_device() + 'gpu:0' - >>> import torch - >>> ivy.set_backend("torch") - >>> device = torch.device("cuda") - >>> ivy.set_default_device(device) - >>> ivy.default_device(as_native=True) - device(type='cuda') + >>> ivy.set_backend('torch') + >>> ivy.set_default_device('gpu:1') + >>> ivy.default_device() + 'gpu:1 + + >>> ivy.set_backend('tensorflow') + >>> ivy.set_default_device('tpu:0) + >>> ivy.default_device() + 'tpu:0 + + >>> ivy.set_backend('paddle') + >>> ivy.set_default_device('cpu) + >>> ivy.default_device() + 'cpu' + + >>> ivy.set_backend('mxnet') + >>> ivy.set_default_device('cpu') + >>> ivy.default_device() + 'cpu' """ global default_device_stack default_device_stack.append(device) @@ -1169,7 +1186,7 @@ def _get_devices(fn: Callable, complement: bool = True) -> Tuple: is_backend_fn = "backend" in fn.__module__ is_frontend_fn = "frontend" in fn.__module__ - is_einops_fn = "einops" in fn.__name__ + is_einops_fn = hasattr(fn, "__name__") and "einops" in fn.__name__ if not is_backend_fn and not is_frontend_fn and not is_einops_fn: if complement: supported = set(all_devices).difference(supported) @@ -1221,7 +1238,13 @@ def function_supported_devices( Examples -------- >>> import ivy + >>> ivy.set_backend('numpy') >>> print(ivy.function_supported_devices(ivy.ones)) + ('cpu',) + + >>> ivy.set_backend('torch') + >>> x = ivy.function_supported_devices(ivy.ones) + >>> x = sorted(x) ('cpu', 'gpu') """ ivy.utils.assertions.check_true( diff --git a/ivy/functional/ivy/elementwise.py b/ivy/functional/ivy/elementwise.py index b4bbe720a143d..793da8e10e05d 100644 --- a/ivy/functional/ivy/elementwise.py +++ b/ivy/functional/ivy/elementwise.py @@ -121,7 +121,7 @@ def abs( a: ivy.array([0., 2.6, 3.5]), b: ivy.array([4.5, 5.3, 0., 2.3]) } - """ + """ # noqa: E501 return ivy.current_backend(x).abs(x, out=out) @@ -333,7 +333,7 @@ def acosh( With :class:`ivy.Container` input: - >>> x = ivy.Container(a=ivy.array([1, 2, 10]), b=ivy.array([1., 10, 6])) + >>> x = ivy.Container(a=ivy.array([1., 2., 10.]), b=ivy.array([1., 10., 6.])) >>> y = ivy.acosh(x) >>> print(y) { @@ -1200,7 +1200,8 @@ def bitwise_invert( With :class:`ivy.Container` input: - >>> x = ivy.Container(a=[False, True, False], b=[True, True, False]) + >>> x = ivy.Container(a=ivy.array([False, True, False]), + ... b=ivy.array([True, True, False])) >>> y = ivy.bitwise_invert(x) >>> print(y) { @@ -1220,7 +1221,7 @@ def bitwise_invert( >>> x = False >>> y = ivy.bitwise_invert(x) >>> print(y) - ivy.array(True) + True """ return ivy.current_backend(x).bitwise_invert(x, out=out) @@ -1851,7 +1852,7 @@ def cosh( -------- With :class:`ivy.Array` input: - >>> x = ivy.array([1, 2, 3, 4]) + >>> x = ivy.array([1., 2., 3., 4.]) >>> y = ivy.cosh(x) >>> print(y) ivy.array([1.54,3.76,10.1,27.3]) @@ -2287,7 +2288,7 @@ def exp( -------- With :class:Number: - >>> x = 3 + >>> x = 3. >>> y = ivy.exp(x) >>> print(y) ivy.array(20.08553692) @@ -4230,12 +4231,12 @@ def log2( >>> y = ivy.empty_like(x) >>> ivy.log2(x, out=y) >>> print(y) - ivy.array([[nan, 0., 2.58, inf],[inf, nan, nan, nan]]) + ivy.array([[nan, 0., 2.58, inf],[-inf, nan, nan, nan]]) >>> x = ivy.array([[float('nan'), 1, 7.0, float('+inf')], ... [+0, -3.0, -8, float('-inf')]]) >>> ivy.log2(x, out=x) >>> print(x) - ivy.array([[nan, 0., 2.81, inf],[inf, nan, nan, nan]]) + ivy.array([[nan, 0., 2.81, inf],[-inf, nan, nan, nan]]) With :class:`ivy.Container` input: >>> x = ivy.Container(a=ivy.array([0.0, float('nan')]), @@ -5959,7 +5960,7 @@ def sinh( -------- With :class:`ivy.Array` input: - >>> x = ivy.array([1, 2, 3]) + >>> x = ivy.array([1., 2., 3.]) >>> y = ivy.sinh(x) >>> print(y) ivy.array([1.18, 3.63, 10.]) @@ -6109,7 +6110,7 @@ def sqrt( b: ivy.array([[7., 1.], [0., 4.47]]) } - """ + """ # noqa: E501 return ivy.current_backend(x).sqrt(x, out=out) @@ -6757,12 +6758,12 @@ def maximum( >>> x = ivy.array([1, 5, 9, 8, 3, 7]) >>> y = ivy.array([[9], [3], [2]]) - >>> z = ivy.zeros((3, 6)) + >>> z = ivy.zeros((3, 6), dtype=ivy.int32) >>> ivy.maximum(x, y, out=z) >>> print(z) - ivy.array([[9., 9., 9., 9., 9., 9.], - [3., 5., 9., 8., 3., 7.], - [2., 5., 9., 8., 3., 7.]]) + ivy.array([[9, 9, 9, 9, 9, 9], + [3, 5, 9, 8, 3, 7], + [2, 5, 9, 8, 3, 7]]) >>> x = ivy.array([[7, 3]]) >>> y = ivy.array([0, 7]) @@ -6847,12 +6848,12 @@ def minimum( >>> x = ivy.array([1, 5, 9, 8, 3, 7]) >>> y = ivy.array([[9], [3], [2]]) - >>> z = ivy.zeros((3, 6)) + >>> z = ivy.zeros((3, 6), dtype=ivy.int32) >>> ivy.minimum(x, y, out=z) >>> print(z) - ivy.array([[1.,5.,9.,8.,3.,7.], - [1.,3.,3.,3.,3.,3.], - [1.,2.,2.,2.,2.,2.]]) + ivy.array([[1, 5, 9, 8, 3, 7], + [1, 3, 3, 3, 3, 3], + [1, 2, 2, 2, 2, 2]]) >>> x = ivy.array([[7, 3]]) >>> y = ivy.array([0, 7]) @@ -6962,7 +6963,7 @@ def deg2rad( -------- With :class:`ivy.Array` input: - >>> x=ivy.array([0,90,180,270,360]) + >>> x=ivy.array([0,90,180,270,360], dtype=ivy.float32) >>> y=ivy.deg2rad(x) >>> print(y) ivy.array([0., 1.57079633, 3.14159265, 4.71238898, 6.28318531]) @@ -6988,7 +6989,7 @@ def deg2rad( With :class:`ivy.Container` input: >>> x=ivy.Container(a=ivy.array([-0,20.1,-50.5,-ivy.nan]), - ... b=ivy.array([0,90,180,270,360])) + ... b=ivy.array([0,90.,180,270,360], dtype=ivy.float32)) >>> y=ivy.deg2rad(x) >>> print(y) { @@ -6996,7 +6997,7 @@ def deg2rad( b: ivy.array([0., 1.57079633, 3.14159265, 4.71238898, 6.28318531]) } - >>> x=ivy.Container(a=ivy.array([0,90,180,270,360]), + >>> x=ivy.Container(a=ivy.array([0,90,180,270,360], dtype=ivy.float32), ... b=ivy.native_array([0,-1.5,-50,ivy.nan])) >>> y=ivy.deg2rad(x) >>> print(y) diff --git a/ivy/functional/ivy/experimental/activations.py b/ivy/functional/ivy/experimental/activations.py index f9788a93ffadf..736fcf1c6e647 100644 --- a/ivy/functional/ivy/experimental/activations.py +++ b/ivy/functional/ivy/experimental/activations.py @@ -559,15 +559,14 @@ def hardtanh( >>> ivy.hardtanh(x, out=y) >>> print(y) ivy.array([ 1., 0.7, -1.]) - >>> x = ivy.array([[1.1, 2.2, 3.3], - ... [-0.4, 0.5, -6.6]]) + >>> x = ivy.array([[1.1, 2.2, 3.3],[-0.4, 0.5, -6.6]]) >>> ivy.hardtanh(x, out=x) >>> print(x) - ivy.array([[ 1., 1., 1.], - [-0.4, 0.5, -1.]]) + ivy.array([[ 1., 1., 1.],[-0.4, 0.5, -1.]]) + With :class:`ivy.Container` input: >>> x = ivy.Container(a=ivy.array([0.0, -1.2]), b=ivy.array([0.4, -0.2])) - >>> x = ivy.hardtanhx, out=x) + >>> x = ivy.hardtanh(x, out=x) >>> print(x) { a: ivy.array([0., -1.]), @@ -953,7 +952,7 @@ def hardshrink( >>> x = ivy.array([-1.0, 1.0, 2.0]) >>> y = x.hardshrink() >>> print(y) - ivy.array([-0.5, 0.5, 1.5]) + ivy.array([-1., 1., 2.]) >>> x = ivy.array([[-1.3, 3.8, 2.1], [1.7, 4.2, -6.6]]) >>> y = ivy.hardshrink(x) >>> print(y) @@ -961,3 +960,55 @@ def hardshrink( [ 1.70000005, 4.19999981, -6.5999999 ]]) """ return current_backend(x).hardshrink(x, lambd=lambd, out=out) + + +@handle_exceptions +@handle_backend_invalid +@handle_nestable +@handle_array_like_without_promotion +@handle_out_argument +@to_native_arrays_and_back +@handle_device +def hardsilu( + x: Union[ivy.Array, ivy.NativeArray], /, *, out: Optional[ivy.Array] = None +) -> ivy.Array: + """Apply the hardsilu/hardswish function element-wise. + + Parameters + ---------- + x + input array + out + optional output array, for writing the result to. It must have a shape that the + inputs broadcast to. + + Returns + ------- + an array containing the output of the hardsilu/hardswish function applied + to each element in ``x``. + + Examples + -------- + With :class:`ivy.Array` input: + + >>> x = ivy.array([1., 2., 3.]) + >>> y = ivy.hardsilu(x) + >>> print(y) + ivy.array([0.66666669, 1.66666663, 3. ]) + >>> x = ivy.array([-2.1241, 1.4897, 4.4090]) + >>> y = ivy.zeros(3) + >>> ivy.hardsilu(x, out=y) + >>> print(y) + ivy.array([-0.31008321, 1.1147176 , 4.40899992]) + + With :class:`ivy.Container` input: + + >>> x = ivy.Container(a=ivy.array([-0.5, -1, 0]), b=ivy.array([0.5, 1., 2])) + >>> y = ivy.hardsilu(x) + >>> print(y) + { + a: ivy.array([-0.20833333, -0.33333334, 0.]), + b: ivy.array([0.29166666, 0.66666669, 1.66666663]) + } + """ + return current_backend(x).hardsilu(x, out=out) diff --git a/ivy/functional/ivy/experimental/elementwise.py b/ivy/functional/ivy/experimental/elementwise.py index 83025fd5dd56f..c2680ceb4fe06 100644 --- a/ivy/functional/ivy/experimental/elementwise.py +++ b/ivy/functional/ivy/experimental/elementwise.py @@ -1637,3 +1637,39 @@ def erfc( ivy.array([0.00467773, 1.84270084, 1. ]) """ return ivy.current_backend(x).erfc(x, out=out) + + +@handle_exceptions +@handle_nestable +@handle_array_like_without_promotion +@handle_out_argument +@to_native_arrays_and_back +@handle_device +def erfinv( + x: Union[ivy.Array, ivy.NativeArray], + /, + *, + out: Optional[ivy.Array] = None, +): + """Compute the inverse error function. + + Parameters + ---------- + x + Input array of real or complex valued argument. + out + optional output array, for writing the result to. + It must have a shape that the inputs broadcast to. + + Returns + ------- + ret + Values of the inverse error function. + + Examples + -------- + >>> x = ivy.array([0, 0.5, -1.]) + >>> ivy.erfinv(x) + ivy.array([0.0000, 0.4769, -inf]) + """ + return ivy.current_backend(x).erfinv(x, out=out) diff --git a/ivy/functional/ivy/experimental/layers.py b/ivy/functional/ivy/experimental/layers.py index 5b24e7aa82f11..b73a463288590 100644 --- a/ivy/functional/ivy/experimental/layers.py +++ b/ivy/functional/ivy/experimental/layers.py @@ -92,15 +92,15 @@ def max_pool1d( [[16., 17., 18., 19.]]]) >>> x = ivy.arange(0, 24.).reshape((2, 3, 4)) - >>> print(ivy.max_pool1d(x, 2, 2, [(1,0)], data_format="NCW", dilation=2, ceil_mode=True)) # noqa - ivy.array([[[ 1., 3.], - [ 5., 7.], - [ 9., 11.]], - - [[13., 15.], - [17., 19.], - [21., 23.]]]) - """ + >>> print(ivy.max_pool1d(x, 2, 2, [(1,0)], data_format="NCW", dilation=1, ceil_mode=True)) + ivy.array([[[ 0., 2., 3.], + [ 4., 6., 7.], + [ 8., 10., 11.]], + + [[12., 14., 15.], + [16., 18., 19.], + [20., 22., 23.]]]) + """ # noqa: E501 return ivy.current_backend(x).max_pool1d( x, kernel, @@ -591,7 +591,7 @@ def pool( Examples -------- >>> x = ivy.arange(12.).reshape((2, 1, 3, 2)) - >>> print(ivy.pool(x, (2, 2), 'MAX', (1, 1), 'SAME')) + >>> print(ivy.pool(x, (2, 2), 'MAX', strides=(1, 1), padding='SAME')) ivy.array([[[[ 1., 2.], [ 3., 4.], [ 4., 5.]]], @@ -599,7 +599,7 @@ def pool( [ 9., 10.], [10., 11.]]]]) >>> x = ivy.arange(48.).reshape((2, 4, 3, 2)) - >>> print(ivy.pool(x, 3, 'AVG', 1, 'VALID')) + >>> print(ivy.pool(x, 3, 'AVG', strides=1, padding='VALID')) ivy.array([[[[ 8., 9.]], [[14., 15.]]], [[[32., 33.]], @@ -1405,11 +1405,13 @@ def _tf_area_interpolate(x, size, scale, dims): d_in, d_in1, d_index = _tf_area_indices(d_dim, scale[0]) h_in, h_in1, h_index = _tf_area_indices(h_dim, scale[1]) w_in, w_in1, w_index = _tf_area_indices(w_dim, scale[2]) - sum_data = ivy.zeros(( - d_index[1] - d_index[0], - h_index[1] - h_index[0], - w_index[1] - w_index[0], - )) + sum_data = ivy.zeros( + ( + d_index[1] - d_index[0], + h_index[1] - h_index[0], + w_index[1] - w_index[0], + ) + ) for d_ind in range(d_index[0], d_index[1]): scale_z = _tf_area_dim_scale( d_ind, d_in, scale[0], d_in1 @@ -1473,7 +1475,11 @@ def nearest_interpolate(x, dims, size, scale, exact): for d in range(dims): n = size[d] offsets = (ivy.arange(n, dtype="float32") + off) * scale[d] - offsets = ivy.astype(ivy.floor(ivy.astype(offsets, "float32")), "int32") + offsets = ivy.astype(ivy.floor(ivy.astype(offsets, "float32")), "int64") + num_dims_to_add = x.ndim - offsets.ndim + if num_dims_to_add > 0: + for _ in range(num_dims_to_add): + offsets = ivy.expand_dims(offsets, axis=0) x = ivy.gather(x, offsets, axis=d + 2) return x @@ -1689,11 +1695,20 @@ def area_interpolate(x, dims, size, scale): def get_interpolate_kernel(mode): kernel_func = _triangle_kernel if mode == "tf_bicubic": - kernel_func = lambda inputs: _cubic_kernel(inputs) + + def kernel_func(inputs): # noqa F811 + return _cubic_kernel(inputs) + elif mode == "lanczos3": - kernel_func = lambda inputs: _lanczos_kernel(3, inputs) + + def kernel_func(inputs): + return _lanczos_kernel(3, inputs) + elif mode == "lanczos5": - kernel_func = lambda inputs: _lanczos_kernel(5, inputs) + + def kernel_func(inputs): + return _lanczos_kernel(5, inputs) + return kernel_func @@ -1899,14 +1914,18 @@ def interpolate( right = int(math.ceil(p_j + 2)) top = int(math.floor(p_i - 2)) bottom = int(math.ceil(p_i + 2)) - kernel_w = ivy.array([ - _mitchellcubic_kernel((p_j - j) * scale_w) - for i in range(left, right) - ]) - kernel_h = ivy.array([ - _mitchellcubic_kernel((p_i - i) * scale_h) - for j in range(top, bottom) - ]) + kernel_w = ivy.array( + [ + _mitchellcubic_kernel((p_j - j) * scale_w) + for i in range(left, right) + ] + ) + kernel_h = ivy.array( + [ + _mitchellcubic_kernel((p_i - i) * scale_h) + for j in range(top, bottom) + ] + ) left_pad = max(0, -left) right_pad = max(0, right - in_width) top_pad = max(0, -top) @@ -2176,6 +2195,106 @@ def adaptive_max_pool2d( } +@handle_nestable +@inputs_to_ivy_arrays +def adaptive_max_pool3d( + input: Union[ivy.Array, ivy.NativeArray], + output_size: Union[Sequence[int], int], +): + """Apply a 3D adaptive maximum pooling over an input signal composed of + several input planes. + + Parameters + ---------- + input + Input array. Must have shape (N, C, D_in, H_in, W_in) or (C, D_in, H_in, W_in) + where N is the batch dimension, C is the feature dimension, and D_in, H_in, + and W_in are the 3 spatial dimensions. + output_size + Spatial output size. + + Returns + ------- + The result of the pooling operation. Will have shape (N, C, D_out, H_out, W_out) + or (C, D_out, H_out, W_out), where D_out, H_out, W_out = `output_size` + """ + squeeze = False + if input.ndim == 4: + input = ivy.expand_dims(input, axis=0) + squeeze = True + elif input.ndim != 5: + raise ivy.utils.exceptions.IvyException( + f"Got {len(input.shape)}D input, but only 4D and 5D inputs are supported.", + ) + + if isinstance(output_size, int): + output_size = (output_size, output_size, output_size) + + if all(i_s % o_s == 0 for i_s, o_s in zip(input.shape[-3:], output_size)): + stride = tuple(i_s // o_s for i_s, o_s in zip(input.shape[-3:], output_size)) + kernel_size = stride + pooled_output = ivy.max_pool3d( + input, kernel_size, stride, "VALID", data_format="NCDHW" + ) + if squeeze: + return ivy.squeeze(pooled_output, axis=0) + return pooled_output + + idxd, length_d, range_max_d, adaptive_d = _compute_idx( + input.shape[-3], output_size[-3], input.device + ) + idxh, length_h, range_max_h, adaptive_h = _compute_idx( + input.shape[-2], output_size[-2], input.device + ) + idxw, length_w, range_max_w, adaptive_w = _compute_idx( + input.shape[-1], output_size[-1], input.device + ) + + # to numpy and back in order to bypass a slicing error in tensorflow + vals = ivy.array( + input.to_numpy()[..., _expand_to_dim(idxd, 5), _expand_to_dim(idxh, 4), idxw], + device=input.device, + ) + + if not (adaptive_d or adaptive_h or adaptive_w): + ret = ivy.max(vals, axis=(-3, -1)) + ret = ivy.squeeze(ret, axis=0) if squeeze else ret + return ret + + vals, length_d = _mask( + vals, length_d, range_max_d, dim=-3, mask_value=float("-inf") + ) + vals, length_h = _mask( + vals, length_h, range_max_h, dim=-2, mask_value=float("-inf") + ) + vals, length_w = _mask( + vals, length_w, range_max_w, dim=-1, mask_value=float("-inf") + ) + + ret = None + for i, j, k in itertools.product( + range(vals.shape[-4]), range(vals.shape[-2]), range(vals.shape[-1]) + ): + if ret is None: + ret = vals[..., i, :, j, k] + else: + ret = ivy.maximum(ret, vals[..., i, :, j, k]) + pooled_output = ret.astype(vals.dtype) + pooled_output = ivy.squeeze(pooled_output, axis=0) if squeeze else pooled_output + return pooled_output + + +adaptive_max_pool3d.mixed_backend_wrappers = { + "to_add": ( + "handle_backend_invalid", + "inputs_to_native_arrays", + "outputs_to_ivy_arrays", + "handle_device", + ), + "to_skip": ("inputs_to_ivy_arrays",), +} + + @handle_nestable @inputs_to_ivy_arrays def adaptive_avg_pool1d( @@ -2938,7 +3057,8 @@ def rfft( >>> x = ivy.array([2.3,3.14,7.2]) >>> y = ivy.zeros(2) >>> ivy.rfft(x, out=y) - ivy.array([12.639999+0.j , -2.87 +3.516063j]) + >>> print(x) + ivy.array([2.29999995, 3.1400001 , 7.19999981]) >>> x = ivy.array([-1.2, 3.4, -5.6]) >>> ivy.rfft(x, n=4, out=x) @@ -3022,7 +3142,7 @@ def rfftn( Examples -------- >>> x = ivy.array([1, 2, 3, 4], dtype=ivy.float32) - >>> result = ivy.rfftn(x, s=(4,)) + >>> result = ivy.rfftn(x, s=(4,), axes=(0,)) >>> print(result) ivy.array([10.+0.j, -2.+2.j, -2.+0.j]) @@ -3310,6 +3430,303 @@ def adaptive_max_pool1d( "inputs_to_native_arrays", "outputs_to_ivy_arrays", "handle_device_shifting", + + +@handle_backend_invalid +@handle_nestable +@inputs_to_ivy_arrays +@handle_device +def rnn( + step_function: Callable, + inputs: ivy.Array, + initial_states: List[ivy.Array], + /, + *, + go_backwards: bool = False, + mask: Optional[ivy.Array] = None, + constants: Optional[ivy.Array] = None, + unroll: bool = False, + input_length: Optional[int] = None, + time_major: bool = False, + zero_output_for_mask: bool = False, + return_all_outputs: bool = True, +): + """Iterate over the time dimension of a tensor. + + Parameters + ---------- + step_function + RNN step function. + inputs + Array of temporal data of shape (samples, time, ...). + initial_states + Array with shape (samples, state_size). + go_backwards + If True, do the iteration over the time dimension in reverse order and return + the reversed sequence. + mask + Binary array with shape (samples, time, 1), with a zero for every element that + is masked. + constants + List of constant values passed at each step. + unroll + Whether to use a pythonic while loop or ivy.while_loop + input_length + An integer or 1-D array, depending on whether the time dimension is + fixed-length. In case of variable length input, it is used for masking in case + there is no mask specified. + time_major + If True, the inputs and outputs will be in shape (timesteps, batch, ...) whereas + in the False case, it will be (batch, timesteps, ...). + zero_output_for_mask + If True, the otput for masked timestep will be zeros, whereas in the False case, + output from previous timestep is returned + return_all_outputs + If True, return the recurrent outputs for all timesteps in the sequence. If + False, only return the output for the last timestep. + + Returns + ------- + ret + A tuple of + - the latest output of the rnn of shape (samples, ...) + - the output of the rnn of shape (samples, time, ...) if + return_all_outputs=True else (samples, 1, ...) + - list of tensors, latest states returned by the step funciton, of shape + (samples, ...) + + Both the description and the type hints above assumes an array input for simplicity, + but this function is *nestable*, and therefore also accepts :class:`ivy.Container` + instances in place of any of the arguments. + """ + # an ivy implementation of rnn inspired from + # https://github.com/keras-team/keras/blob/v2.14.0/keras/backend.py#L4723-L5202 + + # Swap the batch and timestep dim for the incoming tensor. + if not time_major: + inputs = ivy.permute_dims(inputs, (1, 0, *range(2, len(inputs.shape)))) + + time_steps = inputs.shape[0] + batch = inputs.shape[1] + time_steps_t = ivy.asarray(inputs.shape[0]) + + if mask is not None: + if not ivy.is_bool_dtype(mask): + mask = ivy.astype(mask, ivy.bool) + if len(mask.shape) == 2: + mask = ivy.expand_dims(mask, axis=-1) + if not time_major: + mask = ivy.permute_dims(mask, (1, 0, *range(2, len(mask.shape)))) + + if constants is None: + constants = [] + + def _expand_mask(mask_t, input_t, fixed_dim=1): + rank_diff = len(input_t.shape) - len(mask_t.shape) + for _ in range(rank_diff): + mask_t = ivy.expand_dims(mask_t, axis=-1) + multiples = [1] * fixed_dim + list(input_t.shape[fixed_dim:]) + return ivy.tile(mask_t, repeats=multiples) + + if unroll: + states = tuple(initial_states) + successive_states = [] + successive_outputs = [] + + processed_input = ivy.unstack(inputs) + if go_backwards: + processed_input.reverse() + + if mask is not None: + mask_list = ivy.unstack(mask) + if go_backwards: + mask_list.reverse() + + for i in range(time_steps): + input_t = processed_input[i] + mask_t = mask_list[i] + output_t, new_states = step_function( + input_t, tuple(states) + tuple(constants) + ) + tiled_mask_t = _expand_mask(mask_t, output_t) + + if not successive_outputs: + prev_output = ivy.zeros_like(output_t) + else: + prev_output = successive_outputs[-1] + + output = ivy.where(tiled_mask_t, output_t, prev_output) + + tiled_mask_t = tuple(_expand_mask(mask_t, s) for s in states) + final_states = tuple( + ivy.where(m, s, ps) + for m, s, ps in zip(tiled_mask_t, new_states, states) + ) + states = final_states + + if return_all_outputs: + successive_outputs.append(output) + successive_states.append(states) + else: + successive_outputs = [output] + successive_states = [states] + last_output = successive_outputs[-1] + new_states = successive_states[-1] + outputs = ivy.stack(successive_outputs) + + if zero_output_for_mask: + last_output = ivy.where( + _expand_mask(mask_list[-1], last_output), + last_output, + ivy.zeros_like(last_output), + ) + outputs = ivy.where( + _expand_mask(mask, outputs, fixed_dim=2), + outputs, + ivy.zeros_like(outputs), + ) + + else: + for i in range(time_steps): + input_t = processed_input[i] + output_t, states = step_function( + input_t, tuple(states) + tuple(constants) + ) + if return_all_outputs: + successive_outputs.append(output_t) + successive_states.append(states) + else: + successive_outputs = [output_t] + successive_states = [states] + last_output = successive_outputs[-1] + new_states = successive_states[-1] + outputs = ivy.stack(successive_outputs) + + else: + states = tuple(initial_states) + input_time_zero = inputs[0] + output_time_zero, _ = step_function( + input_time_zero, tuple(initial_states) + tuple(constants) + ) + + if return_all_outputs: + if ivy.is_array(time_steps_t): + output_size = time_steps_t.to_scalar() + else: + output_size = time_steps_t + else: + output_size = 1 + output_loop = ivy.empty( + (output_size, *output_time_zero.shape), dtype=output_time_zero.dtype + ) + + if go_backwards: + inputs = ivy.flip(inputs, axis=0) + time = 0 + + test_fn = lambda time, *_: time < time_steps_t + if mask is not None: + if go_backwards: + mask = ivy.flip(mask, axis=0) + + def masking_fn(time): + return mask[time] + + def compute_masked_output(mask_t, output, mask): + tiled_mask_t = tuple( + _expand_mask(mask_t, o, fixed_dim=len(mask_t.shape)) for o in output + ) + return tuple( + ivy.where(m, o, fm) for m, o, fm in zip(tiled_mask_t, output, mask) + ) + + elif ivy.is_ivy_array(input_length): + if go_backwards: + max_len = ivy.max(input_length) + rev_input_length = ivy.subtract(max_len - 1, input_length) + + def masking_fn(time): + return rev_input_length < time + + else: + + def masking_fn(time): + return input_length > time + + def compute_masked_output(mask_t, output, mask): + return ivy.where(mask_t, output, mask) + + else: + masking_fn = None + + if masking_fn is not None: + zero_output = ivy.zeros_like(output_time_zero) + + def _step(time, output_t, prev_output, *states): + current_input = inputs[time] + mask_t = masking_fn(time) + output, new_states = step_function( + current_input, tuple(states) + tuple(constants) + ) + mask_output = zero_output if zero_output_for_mask else prev_output + new_output = compute_masked_output(mask_t, [output], [mask_output])[0] + + for state, new_state in zip(states, new_states): + if ivy.is_ivy_array(new_state): + ivy.reshape(new_state, shape=state.shape, out=new_state) + final_states = compute_masked_output(mask_t, new_states, states) + new_states = final_states + output_t[time if return_all_outputs else 0] = new_output + + return (time + 1, output_t, new_output) + tuple(new_states) + + final_outputs = ivy.while_loop( + test_fn=test_fn, + body_fn=_step, + vars=(time, output_loop, zero_output) + states, + ) + new_states = final_outputs[3:] + else: + + def _step(time, output_t, *states): + current_input = inputs[time] + output, new_states = step_function( + current_input, tuple(states) + tuple(constants) + ) + + for state, new_state in zip(states, new_states): + if ivy.is_ivy_array(new_state): + ivy.reshape(new_state, shape=state.shape, out=new_state) + + output_t[time if return_all_outputs else 0] = output + return (time + 1, output_t) + tuple(new_states) + + final_outputs = ivy.while_loop( + test_fn=test_fn, body_fn=_step, vars=(time, output_loop) + states + ) + new_states = final_outputs[2:] + + outputs = final_outputs[1] + last_output = outputs[-1] + + shape = list(outputs.shape) + if return_all_outputs: + shape[0] = time_steps + else: + shape[0] = 1 + shape[1] = batch + outputs = ivy.reshape(outputs, shape) + + if not time_major: + outputs = ivy.permute_dims(outputs, (1, 0, *range(2, len(outputs.shape)))) + + return last_output, outputs, new_states + + +rnn.mixed_backend_wrappers = { + "to_add": ( + "inputs_to_native_arrays", + "outputs_to_ivy_arrays", ), "to_skip": ("inputs_to_ivy_arrays",), } diff --git a/ivy/functional/ivy/experimental/linear_algebra.py b/ivy/functional/ivy/experimental/linear_algebra.py index 92e92992e53af..d8a22701bbbd6 100644 --- a/ivy/functional/ivy/experimental/linear_algebra.py +++ b/ivy/functional/ivy/experimental/linear_algebra.py @@ -460,6 +460,59 @@ def adjoint( return current_backend(x).adjoint(x, out=out) +@handle_exceptions +@handle_backend_invalid +@handle_nestable +@handle_array_like_without_promotion +@handle_out_argument +@to_native_arrays_and_back +@handle_device +def lu_factor( + A: Union[ivy.Array, ivy.NativeArray], + /, + *, + pivot: bool = True, + out: Optional[Union[ivy.Array, ivy.NativeArray]] = None, +) -> Tuple[Union[ivy.Array, ivy.NativeArray], Union[ivy.Array, ivy.NativeArray]]: + """ + Parameters + ---------- + A + tensor of shape (*, m, n) where * is zero or more batch dimensions. + + pivot + Whether to compute the LU decomposition with partial pivoting, or the regular LU + decomposition. pivot = False not supported on CPU. Default: True. + + out + tuple of two tensors to write the output to. Ignored if None. Default: None. + + Returns + ------- + ret + A named tuple (LU, pivots). + """ + return current_backend(A).lu_factor(A, pivot=pivot, out=out) + + +@handle_exceptions +@handle_backend_invalid +@handle_nestable +@handle_array_like_without_promotion +@handle_out_argument +@to_native_arrays_and_back +@handle_device +def lu_solve( + lu: Union[ivy.Array, ivy.NativeArray], + p: Union[ivy.Array, ivy.NativeArray], + b: Union[ivy.Array, ivy.NativeArray], + /, + *, + out: Optional[ivy.Array] = None, +) -> ivy.Array: + return current_backend(lu, p, b).lu_solve(lu, p, b, out=out) + + @handle_exceptions @handle_backend_invalid @handle_nestable @@ -922,8 +975,8 @@ def multi_mode_dot( Notes ----- If no modes are specified, just assumes there is one matrix or vector per mode and returns: - :math:`\\text{x }\\times_0 \\text{ matrix or vec list[0] }\\times_1 \\cdots \\times_n \\text{ matrix or vec list[n] }` # noqa - """ + :math:`\\text{x }\\times_0 \\text{ matrix or vec list[0] }\\times_1 \\cdots \\times_n \\text{ matrix or vec list[n] }` + """ # noqa: E501 if modes is None: modes = range(len(mat_or_vec_list)) @@ -1051,12 +1104,14 @@ def svd_flip( ) V = V * signs[:, None] if ivy.shape(U)[1] > ivy.shape(V)[0]: - signs = ivy.concat(( - signs, - ivy.ones( - ivy.shape(U)[1] - ivy.shape(V)[0], - ), - )) + signs = ivy.concat( + ( + signs, + ivy.ones( + ivy.shape(U)[1] - ivy.shape(V)[0], + ), + ) + ) U = U * signs[: ivy.shape(U)[1]] return U, V @@ -1385,11 +1440,11 @@ def initialize_tucker( """ try: assert len(x.shape) >= 2 - except ValueError: + except ValueError as e: raise ValueError( "expected x to have at least 2 dimensions but it has only" f" {len(x.shape)} dimension(s)" - ) + ) from e # Initialisation if init == "svd": @@ -1667,11 +1722,11 @@ def tucker( if fixed_factors: try: (core, factors) = init - except ValueError: + except ValueError as e: raise ValueError( f"Got fixed_factor={fixed_factors} but no appropriate Tucker tensor was" ' passed for "init".' - ) + ) from e if len(fixed_factors) == len(factors): return ivy.TuckerTensor((core, factors)) @@ -1903,7 +1958,7 @@ def general_inner_product( >>> a = ivy.array([1, 2, 3]) >>> b = ivy.array([4, 5, 6]) - >>> result = ivy.general_inner_product(a, b, n_modes=1) + >>> result = ivy.general_inner_product(a, b, 1) >>> print(result) ivy.array(32) @@ -1915,7 +1970,7 @@ def general_inner_product( >>> a = ivy.array([[1, 1], [1, 1]]) >>> b = ivy.array([[1, 2, 3, 4],[1, 1, 1, 1]]) - >>> result = ivy.general_inner_product(a, b, n_modes=1) + >>> result = ivy.general_inner_product(a, b, 1) >>> print(result) ivy.array([[2, 3, 4, 5], [2, 3, 4, 5]]) diff --git a/ivy/functional/ivy/experimental/losses.py b/ivy/functional/ivy/experimental/losses.py index 0824093ca069d..11177553a1cef 100644 --- a/ivy/functional/ivy/experimental/losses.py +++ b/ivy/functional/ivy/experimental/losses.py @@ -107,7 +107,7 @@ def l1_loss( target: Union[ivy.Array, ivy.NativeArray], /, *, - reduction: Optional[str] = "mean", + reduction: str = "mean", out: Optional[ivy.Array] = None, ) -> ivy.Array: """ @@ -138,11 +138,11 @@ def l1_loss( -------- >>> x = ivy.array([1.0, 2.0, 3.0]) >>> y = ivy.array([0.5, 2.5, 2.0]) - >>> print(ivy.l1_loss(x, y)) - ivy.array(0.6) + >>> ivy.l1_loss(x, y) + ivy.array(0.666) >>> a = ivy.array([[1.0, 2.0], [3.0, 4.0]]) >>> b = ivy.array([[0.5, 1.5], [2.5, 3.5]]) - >>> print(ivy.l1_loss(a, b)) + >>> ivy.l1_loss(a, b) ivy.array(0.5) """ loss = ivy.abs(target - input) @@ -165,8 +165,8 @@ def huber_loss( pred: Union[ivy.Array, ivy.NativeArray], /, *, - delta: Optional[float] = 1.0, - reduction: Optional[str] = "mean", + delta: float = 1.0, + reduction: str = "mean", out: Optional[ivy.Array] = None, ) -> ivy.Array: """Compute the Huber loss (smooth L1 loss) between true and predicted @@ -230,8 +230,8 @@ def smooth_l1_loss( target: Union[ivy.Array, ivy.NativeArray], /, *, - beta: Optional[float] = 1.0, - reduction: Optional[str] = "mean", + beta: float = 1.0, + reduction: str = "mean", out: Optional[ivy.Array] = None, ) -> ivy.Array: """Compute the smooth L1 loss between two input tensors. @@ -258,12 +258,12 @@ def smooth_l1_loss( Examples -------- - >>> input = ivy.array([1.0, 2.0, 3.0]) - >>> target = ivy.array([2.5, 1.8, 3.2]) + >>> x = ivy.array([1.0, 2.0, 3.0]) + >>> y = ivy.array([2.5, 1.8, 3.2]) >>> ivy.smooth_l1_loss(x, y, beta=1.0) ivy.array(0.3467) - >>> input = ivy.array([1.0, 2.0, 3.0]) - >>> target = ivy.array([6.0, 2.0, 3.0]) + >>> x = ivy.array([1.0, 2.0, 3.0]) + >>> y = ivy.array([6.0, 2.0, 3.0]) >>> ivy.smooth_l1_loss(x, y, beta=1.0) ivy.array(1.5) >>> input = ivy.array([2.0, 3.0, 5.0, 7.0]) @@ -359,7 +359,7 @@ def soft_margin_loss( target: Union[ivy.Array, ivy.NativeArray], /, *, - reduction: Optional[str] = "mean", + reduction: str = "mean", out: Optional[ivy.Array] = None, ) -> ivy.Array: """Compute the soft-margin hinge loss between predicted scores and true @@ -419,7 +419,7 @@ def kl_div( target: Union[ivy.Array, ivy.NativeArray], /, *, - reduction: Optional[str] = "mean", + reduction: str = "mean", log_target=False, out: Optional[ivy.Array] = None, ) -> ivy.Array: @@ -559,7 +559,7 @@ def poisson_nll_loss( -------- >>> input_tensor = ivy.array([1, 2, 3, 4], dtype=ivy.float64) >>> target_tensor = ivy.array([2, 2, 2, 2], dtype=ivy.float64) - >>> loss = poisson_nll_loss(input_tensor, target_tensor, log_input=False) + >>> loss = ivy.poisson_nll_loss(input_tensor, target_tensor, log_input=False) >>> print(loss) ivy.array(0.91097307) """ @@ -571,3 +571,92 @@ def poisson_nll_loss( eps=eps, reduction=reduction, ) + + +@handle_exceptions +@handle_nestable +@handle_array_like_without_promotion +@to_native_arrays_and_back +def hinge_embedding_loss( + input: Union[ivy.Array, ivy.NativeArray], + target: Union[ivy.Array, ivy.NativeArray], + *, + margin: float = 1.0, + reduction: str = "mean", +) -> ivy.Array: + r"""Measures loss from input `x` and label `y` with values 1 or -1. It + evaluates if two inputs are similar or not, often used for embedding or + semi-supervised learning. + + Loss for the `n`-th sample: + .. math:: + l_n = \begin{cases} + x_n, & \text{if}\; y_n = 1,\\ + \max \{0, margin - x_n\}, & \text{if}\; y_n = -1, + \end{cases} + + Total loss: + .. math:: + \ell(x, y) = \begin{cases} + \operatorname{mean}(L), & \text{if reduction} = \text{`mean';}\\ + \operatorname{sum}(L), & \text{if reduction} = \text{`sum'.} + \end{cases} + + where :math:`L = \{l_1,\dots,l_N\}^\top` . + + Parameters + ---------- + input + Input tensor with dtype float. + The shape is [N, \*], where N is batch size and `\*` represents + any number of additional dimensions. + label + Label tensor containing 1 or -1 with dtype float32 or float64. + Its shape matches that of the input. + margin + Sets the hyperparameter margin. Determines the necessary input size + for hinge_embedding_loss calculations when label is -1. Inputs smaller + than the margin are minimized with hinge_embedding_loss. + Default is 1.0. + reduction + Specifies how to aggregate the loss across the batch. Options are: + - ``'none'``: Returns the unreduced loss. + - ``'mean'``: Returns the mean loss. + - ``'sum'``: Returns the summed loss. + Default is ``'mean'``. + + Shape + ----- + - Input: :math:`(*)` where :math:`*` means, any number of dimensions. \ + The sum operation operates over all the elements. + - Target: :math:`(*)`, same shape as the input + - Output: scalar. If :attr:`reduction` is ``'none'``, + then same shape as the input + + Returns + ------- + ret + Hinge embedding loss calculated from the input and label, + shaped based on the reduction method. + + Examples + -------- + >>> input_tensor = ivy.array([1, 2, 3, 4], dtype=ivy.float64) + >>> target_tensor = ivy.array([1, 1, 1, 1], dtype=ivy.float64) + >>> loss = ivy.hinge_embedding_loss(input_tensor, target_tensor, reduction="none") + >>> loss + ivy.array([1., 2., 3., 4.]) + + >>> input_tensor = ivy.array([21, 22], dtype=ivy.float32) + >>> target_tensor = ivy.array([-1, 1], dtype=ivy.float32) + >>> loss = ivy.hinge_embedding_loss(input_tensor,target_tensor, + ... margin=2.0, reduction="sum") + >>> loss + ivy.array(22.) + """ + return ivy.current_backend().hinge_embedding_loss( + input, + target, + margin=margin, + reduction=reduction, + ) diff --git a/ivy/functional/ivy/experimental/manipulation.py b/ivy/functional/ivy/experimental/manipulation.py index 8fe94fbf57f2b..a1467eddf7271 100644 --- a/ivy/functional/ivy/experimental/manipulation.py +++ b/ivy/functional/ivy/experimental/manipulation.py @@ -98,9 +98,9 @@ def flatten( /, *, copy: Optional[bool] = None, - start_dim: Optional[int] = 0, - end_dim: Optional[int] = -1, - order: Optional[str] = "C", + start_dim: int = 0, + end_dim: int = -1, + order: str = "C", out: Optional[ivy.Array] = None, ) -> ivy.Array: """Flattens input by reshaping it into a one-dimensional tensor. If @@ -1797,10 +1797,10 @@ def put_along_axis( >>> axis = 1 >>> indices = ivy.argmax(arr, axis=axis, keepdims=True) >>> value = 100 - >>> ivy.put_along_axis(arr, indices, value, axis, mode='add') + >>> ivy.put_along_axis(arr, indices, value, axis, mode='sum') >>> print(arr) - ivy.array([[ 10, 130, 20], - [ 160, 40, 50]]) + ivy.array([[10, 30, 20], + [60, 40, 50]]) """ arr_shape = arr.shape @@ -2231,7 +2231,7 @@ def fill_diagonal( def unfold( x: Union[ivy.Array, ivy.NativeArray], /, - mode: Optional[int] = 0, + mode: int = 0, *, out: Optional[ivy.Array] = None, ) -> ivy.Array: @@ -2303,10 +2303,10 @@ def fold( def partial_unfold( x: Union[ivy.Array, ivy.NativeArray], /, - mode: Optional[int] = 0, - skip_begin: Optional[int] = 1, - skip_end: Optional[int] = 0, - ravel_tensors: Optional[bool] = False, + mode: int = 0, + skip_begin: int = 1, + skip_end: int = 0, + ravel_tensors: bool = False, *, out: Optional[ivy.Array] = None, ) -> ivy.Array: @@ -2363,7 +2363,7 @@ def partial_fold( /, mode: int, shape: Union[ivy.Shape, ivy.NativeShape, Sequence[int]], - skip_begin: Optional[int] = 1, + skip_begin: int = 1, *, out: Optional[ivy.Array] = None, ) -> ivy.Array: @@ -2404,8 +2404,8 @@ def partial_fold( def partial_tensor_to_vec( x: Union[ivy.Array, ivy.NativeArray], /, - skip_begin: Optional[int] = 1, - skip_end: Optional[int] = 0, + skip_begin: int = 1, + skip_end: int = 0, *, out: Optional[ivy.Array] = None, ) -> ivy.Array: @@ -2449,7 +2449,7 @@ def partial_vec_to_tensor( x: Union[ivy.Array, ivy.NativeArray], /, shape: Union[ivy.Shape, ivy.NativeShape, Sequence[int]], - skip_begin: Optional[int] = 1, + skip_begin: int = 1, *, out: Optional[ivy.Array] = None, ) -> ivy.Array: @@ -2627,17 +2627,17 @@ def choose( Examples -------- >>> choices = ivy.array([[0, 1, 2, 3], [10, 11, 12, 13], - [20, 21, 22, 23], [30, 31, 32, 33]]) - >>> print(choose(ivy.array([2, 3, 1, 0]), choices)) + ... [20, 21, 22, 23],[30, 31, 32, 33]]) + >>> print(ivy.choose(choices, ivy.array([2, 3, 1, 0])) ivy.array([20, 31, 12, 3]) >>> arr = ivy.array([2, 4, 1, 0]) - >>> print(choose(arr, choices, mode='clip')) # 4 goes to 3 (4-1) + >>> print(ivy.choose(choices, arr, mode='clip')) # 4 goes to 3 (4-1) ivy.array([20, 31, 12, 3]) >>> arr = ivy.array([2, 4, 1, 0]) - >>> print(choose(arr, choices, mode='wrap')) # 4 goes to (4 mod 4) + >>> print(ivy.choose(choices, arr, mode='wrap')) # 4 goes to (4 mod 4) ivy.array([20, 1, 12, 3]) """ - return ivy.current_backend(arr).choose(arr, choices, out=out, mode=mode) + return ivy.current_backend().choose(arr, choices, out=out, mode=mode) @handle_array_function @@ -2828,7 +2828,7 @@ def trim_zeros( a: Union[ivy.Array, ivy.NativeArray], /, *, - trim: Optional[str] = "fb", + trim: str = "fb", ) -> ivy.Array: """ivy.Container instance method variant of ivy.trim_zeros. This method simply wraps the function, and so the docstring for ivy.trim_zeros also @@ -2870,3 +2870,64 @@ def trim_zeros( ), "to_skip": ("inputs_to_ivy_arrays",), } + + +@handle_exceptions +@handle_backend_invalid +@handle_nestable +@handle_array_like_without_promotion +@handle_view +@handle_out_argument +@to_native_arrays_and_back +@handle_array_function +@handle_device +def unflatten( + x: Union[ivy.Array, ivy.NativeArray], + /, + dim: int, + shape: Tuple[int], + *, + out: Optional[ivy.Array] = None, +) -> ivy.Array: + """Expand a dimension of the input tensor over multiple dimensions. + + Parameters + ---------- + x + input tensor. + dim + dimension to be unflattened, specified as an index into input.shape. + shape + new shape of the unflattened dimension. One of its elements can be -1 in + which case the corresponding output dimension is inferred. Otherwise, + the product of sizes must equal input.shape[dim]. + out + optional output array, for writing the result to. It must have a shape that the + inputs broadcast to. + + Returns + ------- + ret + view of input with the specified dimension unflattened. + + + This function conforms to the `Array API Standard + `_. This docstring is an extension of the + `docstring `_ + in the standard. + + Both the description and the type hints above assumes an array input for simplicity, + but this function is *nestable*, and therefore also accepts :class:`ivy.Container` + instances in place of any of the arguments. + + Examples + -------- + >>> ivy.unflatten(torch.randn(3, 4, 1), dim=1, shape=(2, 2)).shape + torch.Size([3, 2, 2, 1]) + >>> ivy.unflatten(torch.randn(3, 4, 1), dim=1, shape=(-1, 2)).shape + torch.Size([3, 2, 2, 1]) + >>> ivy.unflatten(torch.randn(5, 12, 3), dim=-2, shape=(2, 2, 3, 1, 1)).shape + torch.Size([5, 2, 2, 3, 1, 1, 3]) + """ + return ivy.current_backend(x).unflatten(x, dim=dim, shape=shape, out=out) diff --git a/ivy/functional/ivy/experimental/norms.py b/ivy/functional/ivy/experimental/norms.py index 8688da4dccd0a..5418c3fb50df8 100644 --- a/ivy/functional/ivy/experimental/norms.py +++ b/ivy/functional/ivy/experimental/norms.py @@ -489,7 +489,7 @@ def group_norm( x = ivy.permute_dims(x, axes=(0, xdims - 1, *range(1, xdims - 1))) N = x.shape[0] C = x.shape[1] - S = ivy.to_scalar(ivy.prod(x.shape[2:])) if xdims > 2 else 1 + S = int(ivy.to_scalar(ivy.prod(x.shape[2:])) if xdims > 2 else 1) assert C % num_groups == 0 x_ = ivy.reshape(x, [N, num_groups, C // num_groups, S]) mean = ivy.mean(x_, axis=(2, 3), keepdims=True) diff --git a/ivy/functional/ivy/experimental/random.py b/ivy/functional/ivy/experimental/random.py index e2fc3828473dc..c126aba5c20cf 100644 --- a/ivy/functional/ivy/experimental/random.py +++ b/ivy/functional/ivy/experimental/random.py @@ -245,7 +245,7 @@ def poisson( ivy.array([[0., 2., 2.], [1., 2., 3.]]) """ - return ivy.current_backend().poisson( + return ivy.current_backend(lam).poisson( lam, shape=shape, device=device, diff --git a/ivy/functional/ivy/experimental/sparse_array.py b/ivy/functional/ivy/experimental/sparse_array.py index 623a38a918afa..4a82fb4f97ad9 100644 --- a/ivy/functional/ivy/experimental/sparse_array.py +++ b/ivy/functional/ivy/experimental/sparse_array.py @@ -766,10 +766,12 @@ def _bsr_to_dense_coordinates(self): for col in cols: for col_index in range(nblockcols): for row_index in range(nblockrows): - all_coordinates.append([ - nblockrows * row + row_index, - nblockcols * col + col_index, - ]) + all_coordinates.append( + [ + nblockrows * row + row_index, + nblockcols * col + col_index, + ] + ) return all_coordinates def _bsc_to_dense_coordinates(self): @@ -785,10 +787,12 @@ def _bsc_to_dense_coordinates(self): for row in rows: for col_index in range(nblockcols): for row_index in range(nblockrows): - all_coordinates.append([ - nblockrows * row + row_index, - nblockcols * col + col_index, - ]) + all_coordinates.append( + [ + nblockrows * row + row_index, + nblockcols * col + col_index, + ] + ) return all_coordinates def to_dense_array(self, *, native=False): diff --git a/ivy/functional/ivy/experimental/statistical.py b/ivy/functional/ivy/experimental/statistical.py index 756f066c02ecb..bf69d12cd5cf2 100644 --- a/ivy/functional/ivy/experimental/statistical.py +++ b/ivy/functional/ivy/experimental/statistical.py @@ -478,7 +478,7 @@ def corrcoef( rowvar: bool = True, out: Optional[ivy.Array] = None, ) -> ivy.Array: - return ivy.current_backend().corrcoef(x, y=y, rowvar=rowvar, out=out) + return ivy.current_backend(x).corrcoef(x, y=y, rowvar=rowvar, out=out) @handle_exceptions diff --git a/ivy/functional/ivy/general.py b/ivy/functional/ivy/general.py index a1de906212d34..dfc16539047ef 100644 --- a/ivy/functional/ivy/general.py +++ b/ivy/functional/ivy/general.py @@ -3,6 +3,7 @@ # global import gc import inspect +import itertools import math from functools import wraps from numbers import Number @@ -214,18 +215,11 @@ def get_referrers_recursive( Examples -------- >>> import gc - >>> def example_function(): - ... obj = [1, 2, 3] - ... return get_referrers_recursive(obj, max_depth=2) + >>> example_function = lambda: (obj := [1, 2, 3]) and ivy.get_referrers_recursive(obj, max_depth=2) >>> result = example_function() >>> print(result) - Container( - 'ref_id_1': Container( - 'ref_id_2': 'tracked', - 'ref_id_3': 'tracked' - ) - ) - """ + {repr:[1,2,3]} + """ # noqa: E501 seen_set = ivy.default(seen_set, set()) local_set = ivy.default(local_set, set()) ret_cont = ivy.Container( @@ -1056,7 +1050,7 @@ def clip_vector_norm( >>> print(y) { a: ivy.array([0., 0.894, 1.79]), - b: ivy.array([2.449, 2.65, 2.83]) + b: ivy.array([1.27279221, 1.69705628, 2.12132034]) } """ norm = ivy.vector_norm(x, keepdims=True, ord=p) @@ -1574,7 +1568,7 @@ def to_ivy_shape(shape: Union[ivy.Shape, ivy.NativeShape]) -> ivy.Shape: @handle_exceptions def to_native_shape( - shape: Union[ivy.Array, ivy.Shape, ivy.NativeShape, tuple, int, list] + shape: Union[ivy.Array, ivy.Shape, ivy.NativeShape, tuple, int, list], ) -> ivy.NativeShape: """Return the input shape in its native backend framework form. @@ -2157,13 +2151,16 @@ def set_min_base(val: float) -> None: >>> print(x) 1e-05 - Set the minimum base to 1e-04: + >>> # Set the minimum base to 1e-04: >>> ivy.set_min_base(1e-04) Retrieve the minimum base: >>> y = ivy.min_base >>> print(y) 1e-04 + + >>> # unset the min_base + >>> ivy.unset_min_base() """ global min_base_stack @@ -2547,6 +2544,9 @@ def set_tmp_dir(tmp_dr: str) -> None: >>> y = ivy.tmp_dir >>> print(y) /my_tmp + + >>> # Unset the tmp_dr + >>> ivy.unset_tmp_dir() """ global tmp_dir_stack ivy.utils.assertions.check_isinstance(tmp_dr, str) @@ -2801,11 +2801,17 @@ def get_item( query = ivy.nonzero(query, as_tuple=False) ret = ivy.gather_nd(x, query) else: - indices, target_shape = _parse_query(query, x.shape) - if indices is None: - return ivy.empty(target_shape, dtype=x.dtype) - ret = ivy.gather_nd(x, indices) - ret = ivy.reshape(ret, target_shape) + query, target_shape, vector_inds = _parse_query(query, x.shape) + if vector_inds is not None: + x = ivy.permute_dims( + x, + axes=[ + *vector_inds, + *[i for i in range(len(x.shape)) if i not in vector_inds], + ], + ) + ret = ivy.gather_nd(x, query) + ret = ivy.reshape(ret, target_shape) if target_shape != list(ret.shape) else ret return ret @@ -2859,10 +2865,10 @@ def set_item( >>> val = ivy.array([10, 10]) >>> ivy.set_item(x, query, val) >>> print(x) - ivy.array([10, 10, 20]) + >>> x = ivy.array([[0, -1, 20], [5, 2, -8]]) - >>> query = ([1, 1]) + >>> query = ivy.array([1, 1]) >>> val = ivy.array([10, 10]) >>> y = ivy.set_item(x, query, val, copy=True) >>> print(y) @@ -2881,7 +2887,7 @@ def set_item( target_shape = ivy.get_item(x, query).shape indices = ivy.nonzero(query, as_tuple=False) else: - indices, target_shape = _parse_query(query, x.shape) + indices, target_shape, _ = _parse_query(query, x.shape, scatter=True) if indices is None: return x val = _broadcast_to(val, target_shape).astype(x.dtype) @@ -2899,27 +2905,243 @@ def set_item( } -def _parse_query(query, x_shape): - query = query if isinstance(query, tuple) else (query,) - query_ = tuple(q.to_numpy() if ivy.is_array(q) else q for q in query) +def _parse_query(query, x_shape, scatter=False): + query = (query,) if not isinstance(query, tuple) else query - # array containing all of x's flat indices - x_ = ivy.arange(0, _numel(x_shape)).reshape(x_shape) + # sequence and integer queries are dealt with as array queries + query = [ivy.array(q) if isinstance(q, (tuple, list, int)) else q for q in query] - # use numpy's __getitem__ to get the queried indices - x_idxs = ivy.array(x_.to_numpy()[query_]) - target_shape = x_idxs.shape + # check if non-slice queries are in consecutive positions + # if so, they have to be moved to the front + # https://numpy.org/neps/nep-0021-advanced-indexing.html#mixed-indexing + non_slice_q_idxs = [i for i, q in enumerate(query) if ivy.is_array(q)] + to_front = ( + len(non_slice_q_idxs) > 1 + and any(ivy.diff(non_slice_q_idxs) != 1) + and non_slice_q_idxs[-1] < len(x_shape) + ) - if 0 in x_idxs.shape or 0 in x_shape: - return None, target_shape + # extract newaxis queries + new_axes = [i for i, q in enumerate(query) if q is None] + query = [q for q in query if q is not None] + query = [Ellipsis] if query == [] else query + + # parse ellipsis + ellipsis_inds = None + if any(q is Ellipsis for q in query): + query, ellipsis_inds = _parse_ellipsis(query, len(x_shape)) + + # broadcast array queries + array_inds = [i for i, v in enumerate(query) if ivy.is_array(v)] + if array_inds: + array_queries = ivy.broadcast_arrays( + *[v for i, v in enumerate(query) if i in array_inds] + ) + array_queries = [ + ( + ivy.where(arr < 0, arr + x_shape[i], arr).astype(ivy.int64) + if arr.size + else arr.astype(ivy.int64) + ) + for arr, i in zip(array_queries, array_inds) + ] + for idx, arr in zip(array_inds, array_queries): + query[idx] = arr + + # convert slices to range arrays + query = [ + _parse_slice(q, x_shape[i]).astype(ivy.int64) if isinstance(q, slice) else q + for i, q in enumerate(query) + ] - # convert the flat indices to multi-D indices - x_idxs = ivy.unravel_index(x_idxs, x_shape) + # fill in missing queries + if len(query) < len(x_shape): + query += [ivy.arange(0, s, 1).astype(ivy.int64) for s in x_shape[len(query) :]] + + # calculate target_shape, i.e. the shape the gathered/scattered values should have + if len(array_inds) and to_front: + target_shape = ( + [list(array_queries[0].shape)] + + [list(query[i].shape) for i in range(len(query)) if i not in array_inds] + + [[] for _ in range(len(array_inds) - 1)] + ) + elif len(array_inds): + target_shape = ( + [list(query[i].shape) for i in range(0, array_inds[0])] + + [list(array_queries[0].shape)] + + [[] for _ in range(len(array_inds) - 1)] + + [list(query[i].shape) for i in range(array_inds[-1] + 1, len(query))] + ) + else: + target_shape = [list(q.shape) for q in query] + if ellipsis_inds is not None: + target_shape = ( + target_shape[: ellipsis_inds[0]] + + [target_shape[ellipsis_inds[0] : ellipsis_inds[1]]] + + target_shape[ellipsis_inds[1] :] + ) + for i, ax in enumerate(new_axes): + if len(array_inds) and to_front: + ax -= sum(1 for x in array_inds if x < ax) - 1 + ax = ax + i + target_shape = [*target_shape[:ax], 1, *target_shape[ax:]] + target_shape = _deep_flatten(target_shape) + + # calculate the indices mesh (indices in gather_nd/scatter_nd format) + query = [ivy.expand_dims(q) if not len(q.shape) else q for q in query] + if len(array_inds): + array_queries = [ + ( + arr.reshape((-1,)) + if len(arr.shape) > 1 + else ivy.expand_dims(arr) if not len(arr.shape) else arr + ) + for arr in array_queries + ] + array_queries = ivy.stack(array_queries, axis=1) + if len(array_inds) == len(query): # advanced indexing + indices = array_queries.reshape((*target_shape, len(x_shape))) + elif len(array_inds) == 0: # basic indexing + indices = ivy.stack(ivy.meshgrid(*query, indexing="ij"), axis=-1).reshape( + (*target_shape, len(x_shape)) + ) + else: # mixed indexing + if to_front: + post_array_queries = ( + ivy.stack( + ivy.meshgrid( + *[v for i, v in enumerate(query) if i not in array_inds], + indexing="ij", + ), + axis=-1, + ).reshape((-1, len(query) - len(array_inds))) + if len(array_inds) < len(query) + else ivy.empty((1, 0)) + ) + indices = ivy.array( + [ + (*arr, *post) + for arr, post in itertools.product( + array_queries, post_array_queries + ) + ] + ).reshape((*target_shape, len(x_shape))) + else: + pre_array_queries = ( + ivy.stack( + ivy.meshgrid( + *[v for i, v in enumerate(query) if i < array_inds[0]], + indexing="ij", + ), + axis=-1, + ).reshape((-1, array_inds[0])) + if array_inds[0] > 0 + else ivy.empty((1, 0)) + ) + post_array_queries = ( + ivy.stack( + ivy.meshgrid( + *[v for i, v in enumerate(query) if i > array_inds[-1]], + indexing="ij", + ), + axis=-1, + ).reshape((-1, len(query) - 1 - array_inds[-1])) + if array_inds[-1] < len(query) - 1 + else ivy.empty((1, 0)) + ) + indices = ivy.array( + [ + (*pre, *arr, *post) + for pre, arr, post in itertools.product( + pre_array_queries, array_queries, post_array_queries + ) + ] + ).reshape((*target_shape, len(x_shape))) + + return ( + indices.astype(ivy.int64), + target_shape, + array_inds if len(array_inds) and to_front else None, + ) + + +def _parse_ellipsis(so, ndims): + pre = list() + for s in so: + if s is Ellipsis: + break + pre.append(s) + post = list() + for s in reversed(so): + if s is Ellipsis: + break + post.append(s) + ret = list( + pre + + [slice(None, None, None) for _ in range(ndims - len(pre) - len(post))] + + list(reversed(post)) + ) + return ret, (len(pre), ndims - len(post)) - # stack the multi-D indices to bring them to gather_nd/scatter_nd format - x_idxs = ivy.stack(x_idxs, axis=-1).astype(ivy.int64) - return x_idxs, target_shape +def _parse_slice(idx, s): + step = 1 if idx.step is None else idx.step + if step > 0: + start = 0 if idx.start is None else idx.start + if start >= s: + stop = start + else: + if start <= -s: + start = 0 + elif start < 0: + start = start + s + stop = s if idx.stop is None else idx.stop + if stop > s: + stop = s + elif start <= -s: + stop = 0 + elif stop < 0: + stop = stop + s + else: + start = s - 1 if idx.start is None else idx.start + if start < -s: + stop = start + else: + if start >= s: + start = s - 1 + elif start < 0: + start = start + s + if idx.stop is None: + stop = -1 + else: + stop = idx.stop + if stop > s: + stop = s + elif stop < -s: + stop = -1 + elif stop == -s: + stop = 0 + elif stop < 0: + stop = stop + s + q_i = ivy.arange(start, stop, step).to_list() + q_i = [q for q in q_i if 0 <= q < s] + q_i = ( + ivy.array(q_i) + if len(q_i) or start == stop or idx.stop is not None + else ivy.arange(0, s, 1) + ) + return q_i + + +def _deep_flatten(iterable): + def _flatten_gen(iterable): + for item in iterable: + if isinstance(item, list): + yield from _flatten_gen(item) + else: + yield item + + return list(_flatten_gen(iterable)) def _numel(shape): @@ -2932,16 +3154,6 @@ def _broadcast_to(input, target_shape): return ivy.reshape(input, target_shape) else: input = input if len(input.shape) else ivy.expand_dims(input, axis=0) - new_dims = () - i_i = len(input.shape) - 1 - for i_t in range(len(target_shape) - 1, -1, -1): - if len(input.shape) + len(new_dims) >= len(target_shape): - break - if i_i < 0 or target_shape[i_t] != input.shape[i_i]: - new_dims += (i_t,) - else: - i_i -= 1 - input = ivy.expand_dims(input, axis=new_dims) return ivy.broadcast_to(input, target_shape) @@ -3974,7 +4186,7 @@ def _expand_typesets(dtypes): return dtypes -def _get_devices_and_dtypes(fn, recurse=False, complement=True): +def _get_devices_and_dtypes(fn, recurse=True, complement=True): supported_devices = ivy.function_supported_devices(fn, recurse=recurse) supported_dtypes = ivy.function_supported_dtypes(fn, recurse=recurse) @@ -3987,9 +4199,9 @@ def _get_devices_and_dtypes(fn, recurse=False, complement=True): for device in supported_devices: supported[device] = supported_dtypes - is_backend_fn = "backend" in fn.__module__ is_frontend_fn = "frontend" in fn.__module__ - is_einops_fn = "einops" in fn.__name__ + is_backend_fn = "backend" in fn.__module__ and not is_frontend_fn + is_einops_fn = hasattr(fn, "__name__") and "einops" in fn.__name__ if not is_backend_fn and not is_frontend_fn and not is_einops_fn: if complement: all_comb = _all_dnd_combinations() @@ -4003,7 +4215,7 @@ def _get_devices_and_dtypes(fn, recurse=False, complement=True): if hasattr(fn, "supported_device_and_dtype"): fn_supported_dnd = fn.supported_device_and_dtype.__get__() - if "einops" in fn.__name__ and isinstance(fn_supported_dnd, dict): + if is_einops_fn and isinstance(fn_supported_dnd, dict): fn_supported_dnd = fn_supported_dnd.get(backend, supported) if fn_supported_dnd: @@ -4021,7 +4233,7 @@ def _get_devices_and_dtypes(fn, recurse=False, complement=True): if hasattr(fn, "unsupported_device_and_dtype"): fn_unsupported_dnd = fn.unsupported_device_and_dtype.__get__() - if "einops" in fn.__name__ and isinstance(fn_unsupported_dnd, dict): + if is_einops_fn and isinstance(fn_unsupported_dnd, dict): fn_unsupported_dnd = fn_unsupported_dnd.get(backend, supported) if fn_unsupported_dnd: @@ -4188,7 +4400,7 @@ def vmap( >>> x = ivy.array(ivy.arange(60).reshape((3, 5, 4))) >>> y = ivy.array(ivy.arange(40).reshape((5, 4, 2))) >>> z = ivy.vmap(ivy.matmul, (1, 0), 1)(x, y) - >>> print(z.shape) + >>> z.shape (3, 5, 2) """ # TODO: optimize in the numpy and tensorflow backends and extend functionality diff --git a/ivy/functional/ivy/gradients.py b/ivy/functional/ivy/gradients.py index 8e1a162112909..fb93425a4c4f7 100644 --- a/ivy/functional/ivy/gradients.py +++ b/ivy/functional/ivy/gradients.py @@ -337,7 +337,7 @@ def _is_variable(x, exclusive=False, to_ignore=None) -> bool: def _variable_data( - x: Union[ivy.Array, ivy.NativeArray] + x: Union[ivy.Array, ivy.NativeArray], ) -> Union[ivy.Array, ivy.NativeArray]: """Get the contents of the input. diff --git a/ivy/functional/ivy/layers.py b/ivy/functional/ivy/layers.py index 741aba99eaf5d..d832aa88a4d30 100644 --- a/ivy/functional/ivy/layers.py +++ b/ivy/functional/ivy/layers.py @@ -518,9 +518,9 @@ def scaled_dot_product_attention( >>> result = ivy.scaled_dot_product_attention(q,k,v,scale=1,mask=mask) >>> print(result) - ivy.array([[[0.40000001, 1.29999995], - ... [2.19994521, 3.09994531], - ... [4.30000019, 5.30000019]]]) + ivy.array([[[2.30000019, 3.23333359], + [2.30000019, 3.23333359], + [2.30000019, 3.23333359]]]) >>> q = ivy.array([[[0.2, 1.], [2.2, 3.], [4.4, 5.6]]]) >>> k = ivy.array([[[0.6, 1.5], [2.4, 3.3], [4.2, 5.1]]]) @@ -2379,6 +2379,190 @@ def lstm_update( return ret, (ht, ct) +@handle_exceptions +@handle_nestable +@handle_array_like_without_promotion +@inputs_to_ivy_arrays +@handle_array_function +def lstm( + input: ivy.Array, + initial_states: Tuple[ivy.Array], + all_weights: Tuple[ivy.Array], + num_layers: int, + dropout: float, + train: bool, + bidirectional: bool, + batch_first: bool = False, + batch_sizes: Sequence = None, + weights_transposed: bool = False, + has_ih_bias: bool = True, + has_hh_bias: bool = True, +): + """Applies a multi-layer long-short term memory to an input sequence. + + Parameters + ---------- + input + input array of shape (seq_len, batch, input_size) when `batch_first` is False + or (batch, seq_len, input_size) when `batch_first` is True + initial_states + tuple of two arrays (h_0, c_0) where h_0 is the initial hidden state of shape + (num_layers * num_directions, batch, hidden_size) and c_0 is the initial cell + state of shape (num_layers * num_directions, batch, hidden_size) + + (num_directions being 2 when `bidirectional`, otherwise 1) + all_weights + tuple of arrays representing the learnable weights of the lstm, with each + layer having up to four arrays (w_ih, w_hh, b_ih, b_hh) representing the weights + and biases (if biases are being used) + + w_ih: weight of shape (4 * hidden_size, input_size) + w_hh: weight of shape (4 * hidden_size, hidden_size) + b_ih: bias of shape (4 * hidden_size,) + b_hh: bias of shape (4 * hidden_size,) + num_layers + number of layers for the lstm to use + dropout + dropout rate + train + whether to run the lstm in train mode or eval mode + bidirectional + whether the lstm is bidirectional or unidirectional + batch_first + defines the data format of the input and output arrays + batch_sizes + specifies the batch size at each timestep, when the input is a packed sequence + weights_transposed + whether the weights are transposed compared to the format + in which they are expected (input_size, 4 * hidden_size) + rather than (4 * hidden_size, input_size) + has_ih_bias + whether the `all_weights` argument includes a input-hidden bias + has_hh_bias + whether the `all_weights` argument includes a hidden-hidden bias + + Returns + ------- + output + output array of shape (seq_len, batch, num_directions * hidden_size) or + (batch, seq_len, num_directions * hidden_size), depending on `batch_first` + h_outs + final hidden state of shape (num_layers * num_directions, batch, hidden_size) + c_outs + final cell state of shape (num_layers * num_directions, batch, hidden_size) + """ + # TODO: the test for this function needs to be fixed - + # see ivy_tests/test_ivy/test_functional/test_nn/test_layers.py::test_lstm + + if weights_transposed: + # transpose the weights if they are in the wrong format + all_weights = [ + ivy.swapaxes(weight, 1, 0) if weight.dim() == 2 else weight + for weight in all_weights + ] + else: + all_weights = list(all_weights) + + if (has_ih_bias and not has_hh_bias) or (has_hh_bias and not has_ih_bias): + # insert zero biases into the weights where one set of biases is not used + shapes = [] + for i in range(2, len(all_weights), 3): + shapes.append(tuple(all_weights[i].shape)) + for i, shape in enumerate(shapes): + idx = (i + 1) * 4 - (1 if has_ih_bias else 2) + all_weights.insert(idx, ivy.zeros(shape)) + has_ih_bias = True + has_hh_bias = True + + weights_per_layer = 2 + if has_ih_bias: + weights_per_layer += 1 + if has_hh_bias: + weights_per_layer += 1 + + assert len(all_weights) == num_layers * weights_per_layer * (1 + bidirectional) + layer_weights = [ + all_weights[i : i + weights_per_layer] + for i in range(0, len(all_weights), weights_per_layer) + ] + + if batch_sizes is not None: + input, batch_sizes = _pad_packed_sequence(input, batch_sizes) + + if batch_first: + input = ivy.swapaxes(input, 0, 1) + + if dropout and train: + raise ivy.utils.exceptions.IvyNotImplementedException() + + unidirectional = not bidirectional + + h0, c0 = initial_states + h_outs, c_outs = [], [] + + output = input + for i in range(num_layers): + if unidirectional: + if weights_per_layer == 4: + weight_ih, weight_hh, (bias_i, bias_h) = _transform_weights( + layer_weights, i + ) + else: + weight_ih, weight_hh = _transform_weights_no_bias(layer_weights, i) + bias_i = bias_h = None + + state_indices = i, i + 1 + else: + if weights_per_layer == 4: + weight_ih_f, weight_hh_f, (bias_i_f, bias_h_f) = _transform_weights( + layer_weights, 2 * i + ) + weight_ih_b, weight_hh_b, (bias_i_b, bias_h_b) = _transform_weights( + layer_weights, 2 * i + 1 + ) + else: + weight_ih_f, weight_hh_f = _transform_weights_no_bias( + layer_weights, 2 * i + ) + weight_ih_b, weight_hh_b = _transform_weights_no_bias( + layer_weights, 2 * i + 1 + ) + bias_i_f = bias_h_f = bias_i_b = bias_h_b = None + + weight_ih = weight_ih_f, weight_ih_b + weight_hh = weight_hh_f, weight_hh_b + bias_i = bias_i_f, bias_i_b + bias_h = bias_h_f, bias_h_b + + state_indices = 2 * i, 2 * i + 2 + + output, (h_out, c_out) = _lstm_layer( + output, + ( + _retrieve_state(h0, *state_indices, num_layers), + _retrieve_state(c0, *state_indices, num_layers), + ), + (weight_ih, weight_hh), + (bias_i, bias_h), + bidirectional, + batch_first=False, + batch_sizes=batch_sizes, + ) + h_outs.append(h_out) + c_outs.append(c_out) + + if batch_first: + output = ivy.swapaxes(output, 0, 1) + + h_outs = h_out if num_layers == 1 else ivy.concat(h_outs, axis=0) + c_outs = c_out if num_layers == 1 else ivy.concat(c_outs, axis=0) + + if batch_sizes is not None: + output = _pack_padded_sequence(output, batch_sizes)[0] + + return output[:, -1], output, (h_outs, c_outs) + + # Helpers # @@ -2623,6 +2807,139 @@ def _convert_boxes_to_roi_format(boxes): return rois +def _lstm_cell( + x, + init_h, + init_c, + kernel, + recurrent_kernel, + bias, + recurrent_bias, + batch_first, + batch_sizes=None, +): + init_h = ivy.squeeze(init_h, axis=0) + init_c = ivy.squeeze(init_c, axis=0) + out, states = ivy.lstm_update( + x, + init_h, + init_c, + kernel, + recurrent_kernel, + bias=bias, + recurrent_bias=recurrent_bias, + time_major=not batch_first, + ) + h, c = states + h = ivy.expand_dims(h) if len(h.shape) == 2 else h + c = ivy.expand_dims(c) if len(c.shape) == 2 else c + return out, (h, c) + + +def _lstm_layer( + x, hidden, weights, biases, bidirectional, batch_first, batch_sizes=None +): + if not bidirectional: + result, (h, c) = _lstm_cell( + x, + *hidden, + *weights, + *biases, + batch_first=batch_first, + batch_sizes=batch_sizes, + ) + else: + result_fw, (h_fw, c_fw) = _lstm_cell( + x, + hidden[0][:1], + hidden[1][:1], + weights[0][0], + weights[1][0], + biases[0][0], + biases[1][0], + batch_first=batch_first, + batch_sizes=batch_sizes, + ) + x_reversed = ivy.flip(x, axis=0) + result_bw, (h_bw, c_bw) = _lstm_cell( + x_reversed, + hidden[0][1:], + hidden[1][1:], + weights[0][1], + weights[1][1], + biases[0][1], + biases[1][1], + batch_first=batch_first, + batch_sizes=batch_sizes, + ) + result_bw = ivy.flip(result_bw, axis=0) + result = ivy.concat([result_fw, result_bw], axis=len(result_fw.shape) - 1) + c = ivy.concat([c_fw, c_bw], axis=0) + h = ivy.concat([h_fw, h_bw], axis=0) + return result, (h, c) + + +def _pack_padded_sequence(input, lengths): + input = ivy.swapaxes(input, 0, 1) + data = [] + batch_sizes = [] + for i in range(int(max(lengths))): + valid_data_mask = ivy.array(lengths) > i + data.append(input[valid_data_mask, i]) + batch_sizes.append(int(sum(valid_data_mask))) + data = ivy.concat(data) + batch_sizes = ivy.array(batch_sizes, dtype=ivy.int64) + return data, batch_sizes + + +def _pad_packed_sequence(data, batch_sizes): + padded_data = ivy.full( + (len(batch_sizes), int(max(batch_sizes)), *data.shape[1:]), + 0, + dtype=data.dtype, + device=data.device, + ) + data_offset = 0 + for i, batch_size in enumerate(batch_sizes): + batch_size = int(batch_size) + padded_data[i, :batch_size] = data[data_offset : data_offset + batch_size] + data_offset += batch_size + lengths = ivy.sum( + ivy.arange(1, int(max(batch_sizes)) + 1)[:, ivy.newaxis] <= batch_sizes, + axis=1, + dtype=ivy.int64, + ) + return padded_data, lengths + + +def _retrieve_state(x, start, end, num_layers): + return x if num_layers == 1 else _slice_along_axis(x, start=start, stop=end, axis=0) + + +def _transform_weights(layer_weights, layer_index): + weights = layer_weights[layer_index] + weight_ih, weight_hh, bias_ih, bias_hh = weights + return ( + ivy.swapaxes(weight_ih, 0, 1), + ivy.swapaxes(weight_hh, 0, 1), + (bias_ih, bias_hh), + ) + + +def _transform_weights_no_bias(layer_weights, layer_index): + weights = layer_weights[layer_index] + weight_ih, weight_hh = weights + return ivy.swapaxes(weight_ih, 0, 1), ivy.swapaxes(weight_hh, 0, 1) + + +def _slice_along_axis(x, start=0, stop=None, stride=1, axis=0): + if axis >= 0: + slices = [slice(None)] * axis + [slice(start, stop, stride)] + else: + slices = [Ellipsis, slice(start, stop, stride)] + [slice(None)] * (-1 - axis) + return x[tuple(slices)] + + @handle_exceptions @handle_nestable @handle_array_like_without_promotion diff --git a/ivy/functional/ivy/linear_algebra.py b/ivy/functional/ivy/linear_algebra.py index 8831c28b7b64a..434c25997a68b 100644 --- a/ivy/functional/ivy/linear_algebra.py +++ b/ivy/functional/ivy/linear_algebra.py @@ -1144,6 +1144,7 @@ def matrix_norm( ord: Union[int, float, Literal[inf, -inf, "fro", "nuc"]] = "fro", axis: Tuple[int, int] = (-2, -1), keepdims: bool = False, + dtype: Optional[Union[ivy.Dtype, ivy.NativeDtype]] = None, out: Optional[ivy.Array] = None, ) -> ivy.Array: """Compute the matrix p-norm. @@ -1198,6 +1199,9 @@ def matrix_norm( If this is set to True, the axes which are normed over are left in the result as dimensions with size one. With this option the result will broadcast correctly against the original x. Default is ``False``. + dtype + If specified, the input tensor is cast to dtype before performing the operation, + and the returned tensor's type will be dtype. Default: None out optional output array, for writing the result to. It must have a shape that the inputs broadcast to. @@ -1286,7 +1290,7 @@ def matrix_norm( } """ return current_backend(x).matrix_norm( - x, ord=ord, axis=axis, keepdims=keepdims, out=out + x, ord=ord, axis=axis, keepdims=keepdims, dtype=dtype, out=out ) @@ -1661,16 +1665,8 @@ def outer( [3.], [4.]]) - A 3-D Example - - >>> x = ivy.array([[[1., 2.], - [3., 4.]], - [[5., 6.], - [7., 8.]]]) - >>> y = ivy.array([[[9., 10.], - [11., 12.]], - [[13., 14.], - [15., 16.]]]) + >>> x = ivy.array([[[1., 2.],[3., 4.]],[[5., 6.],[7., 8.]]]) + >>> y = ivy.array([[[9., 10.],[11., 12.]],[[13., 14.],[15., 16.]]]) >>> d = ivy.outer(x, y) >>> print(d) ivy.array([[ 9., 10., 11., 12., 13., 14., 15., 16.], @@ -1953,6 +1949,7 @@ def slogdet( >>> print(y) slogdet(sign=ivy.array(1.), logabsdet=ivy.array(1.60943794)) + >>> ivy.set_backend('numpy') # As the precision of results depends on backend. >>> x = ivy.array([[1.2, 2.0, 3.1], ... [6.0, 5.2, 4.0], ... [9.0, 8.0, 7.0]]) @@ -1962,6 +1959,7 @@ def slogdet( With :class:`ivy.Container` input: + >>> ivy.unset_backend() # unset backend again. >>> x = ivy.Container(a=ivy.array([[1.0, 2.0], ... [3.0, 4.0]]), ... b=ivy.array([[1.0, 2.0], @@ -2037,13 +2035,9 @@ def solve( Examples -------- With class:`ivy.Array` input: - >>> A = ivy.array([[1.1, 1.2, 1.3], - [2.1, 2.2, 2.3], - [3.1, 3.2, 3.3]]), - >>> B = ivy.array([[1.1], - [2.1], - [3.1]]), - >>> x = solve(A,B); + >>> A = ivy.array([[1.1, 1.2, 1.3], [2.1, 2.2, 2.3], [3.1, 3.2, 3.3]]), + >>> B = ivy.array([[1.1], [2.1], [3.1]]), + >>> x = ivy.solve(A,B); >>> print(x) ivy.array([[1], [0], @@ -2052,20 +2046,14 @@ def solve( (1,3) With shape(A) = (2,3,3) and shape(B) = (2,3,1): - >>> A = ivy.array([[[11.1, 11.2, 11.3], - [12.1, 12.2, 12.3], - [13.1, 13.2, 13.3]], - [[21.1, 21.2, 21.3], - [22.1, 22.2, 22.3], - [23.1, 23.2, 23.3]] - ]), + >>> A = ivy.array([[[11.1, 11.2, 11.3],[12.1, 12.2, 12.3],[13.1, 13.2, 13.3]], [[21.1, 21.2, 21.3],[22.1, 22.2, 22.3],[23.1, 23.2, 23.3]]]), >>> B = ivy.array([[[11.1], [12.1], [13.1]], [[21.1], [22.1], [23.1]]]), - >>> x = solve(A,B); + >>> x = ivy.solve(A,B); >>> print(x) ivy.array([[[1], [0], @@ -2077,13 +2065,9 @@ def solve( (2,1,3) With shape(A) = (3,3) and shape(B) = (3,2): - >>> A = ivy.array([[1.1, 1.2, 1.3], - [2.1, 2.2, 2.3], - [3.1, 3.2, 3.3]]), - >>> B = ivy.array([[1.1, 2.2], - [2.1, 4.2], - [3.1, 6.2]]), - >>> x = solve(A,B); + >>> A = ivy.array([[1.1, 1.2, 1.3], [2.1, 2.2, 2.3], [3.1, 3.2, 3.3]]), + >>> B = ivy.array([[1.1, 2.2], [2.1, 4.2], [3.1, 6.2]]), + >>> x = ivy.solve(A,B); >>> print(x) ivy.array([[[1], [0], @@ -2095,18 +2079,16 @@ def solve( (2,1,3) With class:`ivy.Container` input: - >>> A = ivy.array([[1.1, 1.2, 1.3], - [2.1, 2.2, 2.3], - [3.1, 3.2, 3.3]]), + >>> A = ivy.array([[1.1, 1.2, 1.3], [2.1, 2.2, 2.3], [3.1, 3.2, 3.3]]), >>> B = ivy.container(B1 = ivy.array([[1.1], [2.1], [3.1]]), B2 = ivy.array([[2.2], [4.2], [6.2]])) - >>> x = solve(A,B); + >>> x = ivy.solve(A,B); >>> print(x) { B1:([[1],[0],[0]]), B2:([[2],[0],[0]]) } - """ + """ # noqa: E501 return current_backend(x1, x2).solve(x1, x2, adjoint=adjoint, out=out) @@ -2317,7 +2299,7 @@ def svdvals( >>> x = ivy.native_array([[1.0, 2.0, 3.0], [2.0, 3.0, 4.0], ... [2.0, 1.0, 3.0], [3.0, 4.0, 5.0]]) - >>> print(x.shape) + >>> x.shape (4, 3) >>> x = ivy.native_array([[1.0, 2.0, 3.0], [2.0, 3.0, 4.0], @@ -2450,7 +2432,7 @@ def tensordot( >>> x = ivy.native_array([[1., 2.], [2., 3.]]) >>> y = ivy.native_array([[3., 4.], [4., 5.]]) - >>> res = ivy.tensordot(x, y, axes = (1,1)) + >>> res = ivy.tensordot(x, y, axes = ([1],[1])) >>> print(res) ivy.array([[11., 14.], [18., 23.]]) @@ -2632,7 +2614,7 @@ def trace( ... [7, 0, 6]]) ... ) >>> offset = ivy.Container(a=1, b=0) - >>> y = ivy.trace(x, offset) + >>> y = ivy.trace(x, offset=offset) >>> print(y) { a: ivy.array(6), @@ -2882,13 +2864,13 @@ def vector_norm( ivy.array([4.64158917]) - >>> x = ivy.array([1,2,3,4], dtype = ivy.float16) - >>> z = ivy.empty(shape = 1) + >>> x = ivy.array([1.,2.,3.,4.], dtype = ivy.float16) + >>> z = ivy.empty(shape = 1, dtype=ivy.float16) >>> y = ivy.vector_norm(x, ord = 0, out = z) >>> print(y) ivy.array(4.) - >>> x = ivy.arange(8).reshape((2,2,2)) + >>> x = ivy.arange(8, dtype=ivy.float32).reshape((2,2,2)) >>> y = ivy.vector_norm(x, axis = (0,1), ord = float("-inf")) >>> print(y) ivy.array([0, 1]) @@ -3103,41 +3085,6 @@ def vector_to_skew_symmetric_matrix( return current_backend(vector).vector_to_skew_symmetric_matrix(vector, out=out) -@handle_exceptions -@handle_backend_invalid -@handle_nestable -@handle_array_like_without_promotion -@handle_out_argument -@to_native_arrays_and_back -@handle_device -def lu_factor( - A: Union[ivy.Array, ivy.NativeArray], - /, - *, - pivot: bool = True, - out: Optional[Union[ivy.Array, ivy.NativeArray]] = None, -) -> Tuple[Union[ivy.Array, ivy.NativeArray], Union[ivy.Array, ivy.NativeArray]]: - """ - Parameters - ---------- - A - tensor of shape (*, m, n) where * is zero or more batch dimensions. - - pivot - Whether to compute the LU decomposition with partial pivoting, or the regular LU - decomposition. pivot = False not supported on CPU. Default: True. - - out - tuple of two tensors to write the output to. Ignored if None. Default: None. - - Returns - ------- - ret - A named tuple (LU, pivots). - """ - return current_backend(A).lu_factor(A, pivot=pivot, out=out) - - @handle_exceptions @handle_backend_invalid @handle_nestable diff --git a/ivy/functional/ivy/losses.py b/ivy/functional/ivy/losses.py index 56bce17a0e5cc..a76db473ffbd3 100644 --- a/ivy/functional/ivy/losses.py +++ b/ivy/functional/ivy/losses.py @@ -72,11 +72,11 @@ def cross_entropy( >>> x = ivy.array([0, 0, 1, 0]) >>> y = ivy.array([0.25, 0.25, 0.25, 0.25]) >>> print(ivy.cross_entropy(x, y)) - ivy.array(1.3862944) + ivy.array(0.34657359) >>> z = ivy.array([0.1, 0.1, 0.7, 0.1]) >>> print(ivy.cross_entropy(x, z)) - ivy.array(0.35667497) + ivy.array(0.08916873) """ ivy.utils.assertions.check_elem_in_list(reduction, ["none", "sum", "mean"]) pred = ivy.clip(pred, epsilon, 1 - epsilon) @@ -142,7 +142,7 @@ def binary_cross_entropy( >>> y = ivy.array([0.2, 0.8, 0.3, 0.8]) >>> z = ivy.binary_cross_entropy(x, y) >>> print(z) - ivy.array([0.223,0.223,0.357,1.61]) + ivy.array(0.60309976) >>> x = ivy.array([[0, 1, 1, 0]]) >>> y = ivy.array([[2.6, 6.2, 3.7, 5.3]]) @@ -154,24 +154,26 @@ def binary_cross_entropy( >>> y = ivy.array([[2.6, 6.2, 3.7, 5.3]]) >>> pos_weight = ivy.array([1, 2, 3, 4]) >>> z = ivy.binary_cross_entropy(x, y, pos_weight=pos_weight, from_logits=True) - ivy.array([[2.67164493e+00, 4.05471958e-03, 7.32684899e-02, 5.30496836e+00]]) + ivy.array(2.01348412) >>> x = ivy.array([[0, 1, 1, 0]]) >>> y = ivy.array([[2.6, 6.2, 3.7, 5.3]]) >>> pos_weight = ivy.array([1, 2, 3, 4]) - >>> z = ivy.binary_cross_entropy(x, y, pos_weight=pos_weight, from_logits=True, reduction='sum', axis=1) # noqa: E501 + >>> z = ivy.binary_cross_entropy(x, y, pos_weight=pos_weight, from_logits=True, reduction='sum', axis=1) + >>> print(z) ivy.array([8.05393649]) >>> x = ivy.array([[0, 1, 1, 0]]) >>> y = ivy.array([[2.6, 6.2, 3.7, 5.3]]) >>> z = ivy.binary_cross_entropy(x, y, reduction='none', epsilon=0.5) + >>> print(z) ivy.array([[11.49992943, 3.83330965, 3.83330965, 11.49992943]]) >>> x = ivy.array([[0, 1, 0, 0]]) >>> y = ivy.array([[0.6, 0.2, 0.7, 0.3]]) >>> z = ivy.binary_cross_entropy(x, y, epsilon=1e-3) >>> print(z) - ivy.array([[0.916,1.61,1.2,0.357]]) + ivy.array(1.02136981) With :class:`ivy.NativeArray` input: @@ -179,7 +181,7 @@ def binary_cross_entropy( >>> y = ivy.native_array([0.2, 0.7, 0.2, 0.6]) >>> z = ivy.binary_cross_entropy(x, y) >>> print(z) - ivy.array([0.223,0.357,0.223,0.511]) + ivy.array(0.32844672) With a mix of :class:`ivy.Array` and :class:`ivy.NativeArray` inputs: @@ -187,7 +189,7 @@ def binary_cross_entropy( >>> y = ivy.native_array([0.1, 0.2, 0.8, 0.6]) >>> z = ivy.binary_cross_entropy(x, y) >>> print(z) - ivy.array([0.105,0.223,0.223,0.511]) + ivy.array(0.26561815) With :class:`ivy.Container` input: @@ -195,7 +197,10 @@ def binary_cross_entropy( >>> y = ivy.Container(a=ivy.array([0.6, 0.2, 0.3]),b=ivy.array([0.8, 0.2, 0.2])) >>> z = ivy.binary_cross_entropy(x, y) >>> print(z) - {a:ivy.array([0.511,0.223,0.357]),b:ivy.array([1.61,0.223,1.61])} + { + a: ivy.array(0.36354783), + b: ivy.array(1.14733934) + } With a mix of :class:`ivy.Array` and :class:`ivy.Container` inputs: @@ -204,7 +209,7 @@ def binary_cross_entropy( >>> z = ivy.binary_cross_entropy(x, y) >>> print(z) { - a: ivy.array([0.357, 0.223, 0.223]) + a: ivy.array(0.26765382) } Instance Method Examples @@ -215,8 +220,8 @@ def binary_cross_entropy( >>> y = ivy.array([0.8, 0.2, 0.2, 0.2]) >>> z = ivy.binary_cross_entropy(x, y) >>> print(z) - ivy.array([0.223, 0.223, 0.223, 0.223]) - """ + ivy.array(0.22314337) + """ # noqa: E501 ivy.utils.assertions.check_elem_in_list(reduction, ["none", "sum", "mean"]) if not (0.0 <= epsilon <= 1.0): @@ -309,24 +314,24 @@ def sparse_cross_entropy( >> x = ivy.array([2]) >> y = ivy.array([0.1, 0.1, 0.7, 0.1]) >> print(ivy.sparse_cross_entropy(x, y)) - ivy.array([0.35667494]) + ivy.array([0.08916873]) >>> x = ivy.array([3]) >>> y = ivy.array([0.1, 0.1, 0.7, 0.1]) >>> print(ivy.cross_entropy(x, y)) - ivy.array(21.79329094) + ivy.array(5.44832274) >>> x = ivy.array([2,3]) >>> y = ivy.array([0.1, 0.1]) >>> print(ivy.cross_entropy(x, y)) - ivy.array(11.512926) + ivy.array(5.75646281) With :class:`ivy.NativeArray` input: >>> x = ivy.native_array([4]) >>> y = ivy.native_array([0.1, 0.2, 0.1, 0.1, 0.5]) >>> print(ivy.sparse_cross_entropy(x, y)) - ivy.array([0.693]) + ivy.array([0.13862944]) With :class:`ivy.Container` input: @@ -334,7 +339,7 @@ def sparse_cross_entropy( >>> y = ivy.Container(a=ivy.array([0.1, 0.2, 0.1, 0.1, 0.5])) >>> print(ivy.sparse_cross_entropy(x, y)) { - a: ivy.array([0.693]) + a: ivy.array([0.13862944]) } With a mix of :class:`ivy.Array` and :class:`ivy.NativeArray` inputs: @@ -342,7 +347,7 @@ def sparse_cross_entropy( >>> x = ivy.array([0]) >>> y = ivy.native_array([0.1, 0.2, 0.6, 0.1]) >>> print(ivy.sparse_cross_entropy(x,y)) - ivy.array([2.3]) + ivy.array([0.57564628]) With a mix of :class:`ivy.Array` and :class:`ivy.Container` inputs: @@ -350,7 +355,7 @@ def sparse_cross_entropy( >>> y = ivy.Container(a=ivy.array([0.1, 0.2, 0.6, 0.1])) >>> print(ivy.sparse_cross_entropy(x,y)) { - a: ivy.array([2.3]) + a: ivy.array([0.57564628]) } Instance Method Examples @@ -360,7 +365,7 @@ def sparse_cross_entropy( >>> x = ivy.array([2]) >>> y = ivy.array([0.1, 0.1, 0.7, 0.1]) >>> print(x.sparse_cross_entropy(y)) - ivy.array([0.357]) + ivy.array([0.08916873]) With :class:`ivy.Container` input: @@ -368,7 +373,7 @@ def sparse_cross_entropy( >>> y = ivy.Container(a=ivy.array([0.1, 0.1, 0.7, 0.1])) >>> print(x.sparse_cross_entropy(y)) { - a: ivy.array([0.357]) + a: ivy.array([0.08916873]) } """ ivy.utils.assertions.check_elem_in_list(reduction, ["none", "sum", "mean"]) diff --git a/ivy/functional/ivy/manipulation.py b/ivy/functional/ivy/manipulation.py index a039a9159e3a0..b128f99d62f6e 100644 --- a/ivy/functional/ivy/manipulation.py +++ b/ivy/functional/ivy/manipulation.py @@ -1214,9 +1214,17 @@ def split( >>> x = ivy.Container(a=ivy.array([10, 45, 2])) >>> y = ivy.split(x) >>> print(y) - { - a:(list[3],shape=[1]) - } + [ + { + a: ivy.array([10]) + }, + { + a: ivy.array([45]) + }, + { + a: ivy.array([2]) + } + ] """ return current_backend(x).split( x, diff --git a/ivy/functional/ivy/meta.py b/ivy/functional/ivy/meta.py index 5b3151c9accc6..f468ded38a0e3 100644 --- a/ivy/functional/ivy/meta.py +++ b/ivy/functional/ivy/meta.py @@ -88,10 +88,12 @@ def cost_fn_with_variable(v): else variables.cont_prune_key_chains(outer_v, ignore_none=True) ) - inner_grads = ivy.Container({ - k: ivy.zeros_like(v) if k not in inner_grads else inner_grads[k] - for k, v in var.cont_to_iterator() - }) + inner_grads = ivy.Container( + { + k: ivy.zeros_like(v) if k not in inner_grads else inner_grads[k] + for k, v in var.cont_to_iterator() + } + ) if batched: inner_grads = ivy.multiply(inner_grads, num_tasks) @@ -151,14 +153,16 @@ def _train_task( if keep_innver_v else variables.cont_prune_key_chains(inner_v, ignore_none=True) ) - inner_update_grads = ivy.Container({ - k: ( - ivy.zeros_like(v) - if k not in inner_update_grads - else inner_update_grads[k] - ) - for k, v in var.cont_to_iterator() - }) + inner_update_grads = ivy.Container( + { + k: ( + ivy.zeros_like(v) + if k not in inner_update_grads + else inner_update_grads[k] + ) + for k, v in var.cont_to_iterator() + } + ) if batched: inner_update_grads = ivy.multiply(inner_update_grads, num_tasks) diff --git a/ivy/functional/ivy/nest.py b/ivy/functional/ivy/nest.py index 39b49a647ea89..2725361c86bba 100644 --- a/ivy/functional/ivy/nest.py +++ b/ivy/functional/ivy/nest.py @@ -239,7 +239,7 @@ def insert_into_nest_at_index(nest: Iterable, index: Tuple, value) -> None: >>> nest = [[1, 2], [3, 4]] >>> index = (1, 1) >>> value = 99 - >>> insert_into_nest_at_index(nest, index, value) + >>> ivy.insert_into_nest_at_index(nest, index, value) >>> print(nest) [[1, 2], [3, 99, 4]] """ @@ -369,7 +369,10 @@ def map_nest_at_index( try: _result = nest_type(_result) except TypeError: - _result = nest_type(*_result) + try: + _result = nest_type(*_result) + except TypeError: + pass return _result @@ -1090,18 +1093,12 @@ def nested_map( ... ) >>> function = lambda a : a + 1 >>> ivy.nested_map(function, x) - { - a: ivy.array([[2, 3, 4], - [10, 9, 8]]), - b: ivy.array([[5, 6, 7], - [13, 14, 15]]) - } >>> print(x) { - a: ivy.array([[2, 3, 4], - [10, 9, 8]]), - b: ivy.array([[5, 6, 7], - [13, 14, 15]]) + a: ivy.array([[1, 2, 3], + [9, 8, 7]]), + b: ivy.array([[4, 5, 6], + [12, 13, 14]]) } >>> nest = ([1, 2], [3, 4], [5, 6], {"a": 1, "b": 2, "c": 3}) @@ -1344,14 +1341,16 @@ def copy_nest( return class_instance(**dict(zip(nest._fields, ret_list))) return class_instance(tuple(ret_list)) elif check_fn(nest, list): - return class_instance([ - copy_nest( - i, - include_derived=include_derived, - to_mutable=to_mutable, - ) - for i in nest - ]) + return class_instance( + [ + copy_nest( + i, + include_derived=include_derived, + to_mutable=to_mutable, + ) + for i in nest + ] + ) elif check_fn(nest, dict): class_instance = type(nest) dict_ = { @@ -1510,7 +1509,7 @@ def _found_in_index_chains(this_index_chain, index_chains): ) ) ret = func(values, this_index_chain) - if to_ivy: + if to_ivy and ret is not None: if isinstance(nest, (ivy.Array, ivy.NativeArray)): return ret else: diff --git a/ivy/functional/ivy/searching.py b/ivy/functional/ivy/searching.py index 0faf2e0efd258..9dd2c434990c8 100644 --- a/ivy/functional/ivy/searching.py +++ b/ivy/functional/ivy/searching.py @@ -92,9 +92,10 @@ def argmax( ivy.array([1]) >>> x = ivy.array([-0., 1., -1.]) - >>> ivy.argmax(x, out=x) - >>> print(x) - ivy.array([1]) + >>> z = ivy.zeros((1,3), dtype=ivy.int64) + >>> ivy.argmax(x, out=z) + >>> print(z) + ivy.array(1) >>> x = ivy.array([[1., -0., -1.], [-2., 3., 2.]]) >>> y = ivy.argmax(x, axis=1) @@ -112,7 +113,7 @@ def argmax( ivy.array([0, 2]) int64 >>> x = ivy.array([[4., 0., -1.],[2., -3., 6], [2., -3., 6]]) - >>> z = ivy.zeros((1,3), dtype=ivy.int64) + >>> z = ivy.zeros((3,1), dtype=ivy.int64) >>> y = ivy.argmax(x, axis=1, keepdims=True, out=z) >>> print(z) ivy.array([[0],[2],[2]]) diff --git a/ivy/functional/ivy/set.py b/ivy/functional/ivy/set.py index 10ae870d1b89a..5f9e92f400918 100644 --- a/ivy/functional/ivy/set.py +++ b/ivy/functional/ivy/set.py @@ -243,20 +243,6 @@ def unique_inverse( >>> print(y) Results(values=ivy.array([0.2, 0.3, 0.5, 0.8, 1.2, 2.4]), inverse_indices=ivy.array([2, 1, 3, 0, 4, 5, 1])) - - With :class:`ivy.Container` input: - - >>> x = ivy.Container(a=ivy.array([1., 4., 3. , 5. , 3. , 7.]), - ... b=ivy.array([3, 2, 6, 3, 7, 4, 9])) - >>> y = ivy.ivy.unique_inverse(x) - >>> print(y) - [{ - a: ivy.array([1., 3., 4., 5., 7.]), - b: ivy.array([2, 3, 4, 6, 7, 9]) - }, { - a: ivy.array([0, 2, 1, 3, 1, 4]), - b: ivy.array([1, 0, 3, 1, 4, 2, 5]) - }] """ return ivy.current_backend(x).unique_inverse(x, axis=axis) diff --git a/ivy/functional/ivy/statistical.py b/ivy/functional/ivy/statistical.py index 59c0cc0ccc303..d160973ae184f 100644 --- a/ivy/functional/ivy/statistical.py +++ b/ivy/functional/ivy/statistical.py @@ -48,6 +48,8 @@ def min( *, axis: Optional[Union[int, Sequence[int]]] = None, keepdims: bool = False, + initial: Optional[Union[int, float, complex]] = None, + where: Optional[ivy.Array] = None, out: Optional[ivy.Array] = None, ) -> ivy.Array: """Calculate the minimum value of the input array ``x``. @@ -82,6 +84,11 @@ def min( compatible with the input array (see :ref:`broadcasting`). Otherwise, if ``False``, the reduced axes (dimensions) must not be included in the result. Default: ``False``. + initial + The maximum value of an output element. + Must be present to allow computation on empty slice. + where + Elements to compare for minimum out optional output array, for writing the result to. @@ -139,7 +146,9 @@ def min( b: ivy.array(2) } """ - return current_backend(x).min(x, axis=axis, keepdims=keepdims, out=out) + return current_backend(x).min( + x, axis=axis, keepdims=keepdims, initial=initial, where=where, out=out + ) @handle_exceptions @@ -1090,9 +1099,7 @@ def cumprod( >>> print(y) ivy.array([1, 2, 6]) - >>> x = ivy.array([[2, 3], - [5, 7], - [11, 13]]) + >>> x = ivy.array([[2, 3],[5, 7],[11, 13]]) >>> y = ivy.zeros((3, 2)) >>> ivy.cumprod(x, axis=1, exclusive=True, out=y) >>> print(y) @@ -1110,7 +1117,7 @@ def cumprod( >>> x = ivy.array([[2, 3],[5, 7],[11, 13]]) >>> y = ivy.zeros((3, 2)) >>> x.cumprod(axis=0, exclusive=True, out=y) - >>> print(x) + >>> print(y) ivy.array([[1., 1.], [2., 3.], [10., 21.]]) @@ -1133,12 +1140,7 @@ def cumprod( b: ivy.array([1, 3, 12]) } - >>> x = ivy.Container(a=ivy.array([[2, 3], - [5, 7], - [11, 13]]), - b=ivy.array([[3, 4], - [4, 5], - [5, 6]])) + >>> x = ivy.Container(a=ivy.array([[2, 3],[5, 7],[11, 13]]), b=ivy.array([[3, 4],[4, 5],[5, 6]])) >>> y = ivy.Container(a = ivy.zeros((3, 2)), b = ivy.zeros((3, 2))) >>> ivy.cumprod(x, axis=1, exclusive=True, out=y) >>> print(y) @@ -1151,12 +1153,7 @@ def cumprod( [1, 5]]) } - >>> x = ivy.Container(a=ivy.array([[2, 3], - [5, 7], - [11, 13]]), - b=ivy.array([[3, 4], - [4, 5], - [5, 6]])) + >>> x = ivy.Container(a=ivy.array([[2, 3],[5, 7],[11, 13]]), b=ivy.array([[3, 4],[4, 5],[5, 6]])) >>> x.cumprod(axis=0, exclusive=True, out=x) >>> print(x) { @@ -1165,9 +1162,9 @@ def cumprod( [10, 21]]), b: ivy.array([[1, 1], [3, 4], - [15, 42]]) + [12, 20]]) } - """ + """ # noqa: E501 return current_backend(x).cumprod( x, axis=axis, exclusive=exclusive, reverse=reverse, dtype=dtype, out=out ) diff --git a/ivy/stateful/converters.py b/ivy/stateful/converters.py index 834096133f581..541829bc3d18b 100644 --- a/ivy/stateful/converters.py +++ b/ivy/stateful/converters.py @@ -507,7 +507,7 @@ def __update_param(ivy_module, x, kc): module = module.__getattribute__(key) if hasattr(module, "_update_v"): module._update_v({keys[-1]: self._parameters[kc]}) - return self._parameters[kc] + return getattr(module, keys[-1]) self._ivy_module.v = self._ivy_module.v.cont_map( functools.partial(__update_param, self._ivy_module), diff --git a/ivy/stateful/helpers.py b/ivy/stateful/helpers.py index 202acfde78d37..c62ea0bea79f1 100644 --- a/ivy/stateful/helpers.py +++ b/ivy/stateful/helpers.py @@ -89,9 +89,10 @@ def _find_variables( return vs def _find_buffers(self): - for obj in self.__dict__.keys(): - if isinstance(getattr(self, obj), ivy.Module): - self._buffers.update({obj: getattr(self, obj).buffers}) + if hasattr(self, "_module_dict"): + for key, sub_module in self._module_dict.items(): + if len(sub_module._buffers) > 0: + self._buffers[key] = sub_module._buffers def _build_and_return_v(self, *args, **kwargs): self.build(*args, **kwargs) @@ -128,7 +129,7 @@ def _extract_v(v, keychain_mappings: dict, orig_key_chain, /): # Check if `v` contains `new_kc` before replacing in `ret_cont` if v.cont_has_key_chain(new_kc): ret_cont = ret_cont.cont_set_at_key_chain( - "/".join(new_kc.split("/")[1:]), v.cont_at_key_chain(new_kc) + "/".join(old_kc.split("/")[1:]), v.cont_at_key_chain(new_kc) ) else: continue diff --git a/ivy/stateful/layers.py b/ivy/stateful/layers.py index e2cad240cccf8..6dd606c1c6529 100644 --- a/ivy/stateful/layers.py +++ b/ivy/stateful/layers.py @@ -664,7 +664,7 @@ def __init__( self._filter_size = filter_size self._strides = strides self._padding = padding - self._w_shape = (filter_size, input_channels, output_channels) + self._w_shape = (filter_size, output_channels, input_channels) self._b_shape = ( (1, 1, output_channels) if data_format == "NWC" else (1, output_channels, 1) ) @@ -957,7 +957,7 @@ def __init__( self._filter_shape = filter_shape self._strides = strides self._padding = padding - self._w_shape = filter_shape + [input_channels, output_channels] + self._w_shape = filter_shape + [output_channels, input_channels] self._b_shape = ( (1, 1, 1, output_channels) if data_format == "NHWC" @@ -1393,7 +1393,7 @@ def __init__( self._filter_shape = filter_shape self._strides = strides self._padding = padding - self._w_shape = filter_shape + [input_channels, output_channels] + self._w_shape = filter_shape + [output_channels, input_channels] self._b_shape = ( (1, 1, 1, 1, output_channels) if data_format == "NDHWC" diff --git a/ivy/stateful/module.py b/ivy/stateful/module.py index 195ea30ea1f1f..d8ad7d80455d1 100644 --- a/ivy/stateful/module.py +++ b/ivy/stateful/module.py @@ -288,12 +288,12 @@ def build( # ToDo: verify variables in self.v are released once this method exits self._v = ivy.Container() - # once all variables built, find and assign buffers - self._find_buffers() - # compute the module dict self._compute_module_dict() + # once all variables built, find and assign buffers + self._find_buffers() + return v_ret if bool(v_ret) or isinstance(built, bool) else built def trace_graph( @@ -345,7 +345,10 @@ def register_buffer(self, name, value): value Value of the buffer """ - self._buffers.update({name: value}) + if value is not None: + self._buffers.update({name: value}) + else: + super().__setattr__(name, value) def register_parameter(self, name, value): """Register a parameter. @@ -353,9 +356,9 @@ def register_parameter(self, name, value): Parameters ---------- name - Name of the buffer + Name of the parameter value - Value of the buffer + Value of the parameter """ self._v.update({name: value}) @@ -800,10 +803,12 @@ def _create_variables(self, device=None, dtype=None): def _build(self, *args, **kwargs): self._native_params = ivy.Container( OrderedDict( - sorted([ - (k.replace(".", "/"), v) - for k, v in dict(self._native_module.named_parameters()).items() - ]) + sorted( + [ + (k.replace(".", "/"), v) + for k, v in dict(self._native_module.named_parameters()).items() + ] + ) ), dynamic_backend=False, ) @@ -831,10 +836,12 @@ def _create_variables(self, device=None, dtype=None): def _build(self, *args, **kwargs): self._native_params = ivy.Container( OrderedDict( - sorted([ - (k.replace(".", "/"), v) - for k, v in dict(self._native_module.named_parameters()).items() - ]) + sorted( + [ + (k.replace(".", "/"), v) + for k, v in dict(self._native_module.named_parameters()).items() + ] + ) ), dynamic_backend=False, ) diff --git a/ivy/stateful/sequential.py b/ivy/stateful/sequential.py index 08bf1a1f56465..684f698a0dee1 100644 --- a/ivy/stateful/sequential.py +++ b/ivy/stateful/sequential.py @@ -34,13 +34,13 @@ def __init__( for i, submod in enumerate(sub_modules): try: submod.v = v["submodules"][f"v{str(i)}"] - except KeyError: + except KeyError as e: if submod.v: raise ivy.utils.exceptions.IvyException( "variables v passed to Sequential class must have key " "chains in the form of " '"submodules/v{}", where {} is an idx' - ) + ) from e self._submodules = list(sub_modules) Module.__init__(self, device=device, v=v, dtype=dtype) @@ -64,13 +64,13 @@ def _forward(self, inputs): for i, submod in enumerate(self._submodules): try: x = submod(x, v=self.v.submodules[f"v{str(i)}"]) - except KeyError: + except KeyError as e: if submod.v: raise ivy.utils.exceptions.IvyException( "variables v passed to Sequential class must have key chains " "in the form of " '"submodules/v{}", where {} is an idx' - ) + ) from e x = submod(x) return x diff --git a/ivy/utils/_importlib.py b/ivy/utils/_importlib.py index 13503024aff14..01247a3bd719f 100644 --- a/ivy/utils/_importlib.py +++ b/ivy/utils/_importlib.py @@ -12,7 +12,7 @@ # expected. Import these modules along with Ivy initialization, as the import logic # assumes they exist in sys.modules. -MODULES_TO_SKIP = ["ivy.compiler", "ivy.engines"] +MODULES_TO_SKIP = ["ivy.compiler", "ivy.engines", "ivy.wrappers"] IS_COMPILING_WITH_BACKEND = False diff --git a/ivy/utils/assertions.py b/ivy/utils/assertions.py index 2d5e5a87960cd..952d2be8f8303 100644 --- a/ivy/utils/assertions.py +++ b/ivy/utils/assertions.py @@ -22,13 +22,19 @@ def _broadcast_inputs(x1, x2): def check_less(x1, x2, allow_equal=False, message="", as_array=True): - comp_fn = lambda x1, x2: (ivy.any(x1 > x2), ivy.any(x1 >= x2)) + def comp_fn(x1, x2): + return ivy.any(x1 > x2), ivy.any(x1 >= x2) + if not as_array: - iter_comp_fn = lambda x1_, x2_: ( - any(x1 > x2 for x1, x2 in zip(x1_, x2_)), - any(x1 >= x2 for x1, x2 in zip(x1_, x2_)), - ) - comp_fn = lambda x1, x2: iter_comp_fn(*_broadcast_inputs(x1, x2)) + + def iter_comp_fn(x1_, x2_): + return any(x1 > x2 for x1, x2 in zip(x1_, x2_)), any( + x1 >= x2 for x1, x2 in zip(x1_, x2_) + ) + + def comp_fn(x1, x2): # noqa F811 + return iter_comp_fn(*_broadcast_inputs(x1, x2)) + gt, gt_eq = comp_fn(x1, x2) # less_equal if allow_equal and gt: @@ -42,13 +48,19 @@ def check_less(x1, x2, allow_equal=False, message="", as_array=True): def check_greater(x1, x2, allow_equal=False, message="", as_array=True): - comp_fn = lambda x1, x2: (ivy.any(x1 < x2), ivy.any(x1 <= x2)) + def comp_fn(x1, x2): + return ivy.any(x1 < x2), ivy.any(x1 <= x2) + if not as_array: - iter_comp_fn = lambda x1_, x2_: ( - any(x1 < x2 for x1, x2 in zip(x1_, x2_)), - any(x1 <= x2 for x1, x2 in zip(x1_, x2_)), - ) - comp_fn = lambda x1, x2: iter_comp_fn(*_broadcast_inputs(x1, x2)) + + def iter_comp_fn(x1_, x2_): + return any(x1 < x2 for x1, x2 in zip(x1_, x2_)), any( + x1 <= x2 for x1, x2 in zip(x1_, x2_) + ) + + def comp_fn(x1, x2): # noqa F811 + return iter_comp_fn(*_broadcast_inputs(x1, x2)) + lt, lt_eq = comp_fn(x1, x2) # greater_equal if allow_equal and lt: @@ -63,11 +75,20 @@ def check_greater(x1, x2, allow_equal=False, message="", as_array=True): def check_equal(x1, x2, inverse=False, message="", as_array=True): # not_equal - eq_fn = lambda x1, x2: (x1 == x2 if inverse else x1 != x2) - comp_fn = lambda x1, x2: ivy.any(eq_fn(x1, x2)) + def eq_fn(x1, x2): + return x1 == x2 if inverse else x1 != x2 + + def comp_fn(x1, x2): + return ivy.any(eq_fn(x1, x2)) + if not as_array: - iter_comp_fn = lambda x1_, x2_: any(eq_fn(x1, x2) for x1, x2 in zip(x1_, x2_)) - comp_fn = lambda x1, x2: iter_comp_fn(*_broadcast_inputs(x1, x2)) + + def iter_comp_fn(x1_, x2_): + return any(eq_fn(x1, x2) for x1, x2 in zip(x1_, x2_)) + + def comp_fn(x1, x2): # noqa F811 + return iter_comp_fn(*_broadcast_inputs(x1, x2)) + eq = comp_fn(x1, x2) if inverse and eq: raise ivy.utils.exceptions.IvyException( diff --git a/ivy/utils/backend/handler.py b/ivy/utils/backend/handler.py index 702766db6cb79..04974f0557488 100644 --- a/ivy/utils/backend/handler.py +++ b/ivy/utils/backend/handler.py @@ -96,7 +96,7 @@ def _determine_backend_from_args(args): >>> x = jnp.array([1]) >>> print(_determine_backend_from_args(x)) # noqa - """ + """ # noqa: E501 arg_type = type(args) if isinstance(args, ivy.Array): args = args.data @@ -175,7 +175,7 @@ def current_backend(*args, **kwargs): >>> x = np.array([2.0]) >>> print(ivy.current_backend(x)) # noqa - """ + """ # noqa: E501 global implicit_backend # if a global backend has been set with # set_backend then this will be returned @@ -358,7 +358,6 @@ def set_backend(backend: str, dynamic: bool = False): global ivy_original_dict if not backend_stack: ivy_original_dict = ivy.__dict__.copy() - _clear_current_sub_backends() if isinstance(backend, str): temp_stack = [] diff --git a/ivy/utils/binaries.py b/ivy/utils/binaries.py index 5f050892f2044..dc7175831457b 100644 --- a/ivy/utils/binaries.py +++ b/ivy/utils/binaries.py @@ -9,8 +9,9 @@ def _get_paths_from_binaries(binaries, root_dir=""): """Get all the paths from the binaries.json into a list.""" paths = [] + ext = "pyd" if os.name == "nt" else "so" if isinstance(binaries, str): - return [os.path.join(root_dir, binaries)] + return [os.path.join(root_dir, binaries + "." + ext)] elif isinstance(binaries, dict): for k, v in binaries.items(): paths += _get_paths_from_binaries(v, os.path.join(root_dir, k)) @@ -33,10 +34,12 @@ def check_for_binaries(): for path in binaries_paths: if not os.path.exists(path): if initial: - config_str = "\n".join([ - f"{module} : {', '.join(configs)}" - for module, configs in available_configs.items() - ]) + config_str = "\n".join( + [ + f"{module} : {', '.join(configs)}" + for module, configs in available_configs.items() + ] + ) logging.warning( "\tSome binaries seem to be missing in your system. This could " "be either because we don't have compatible binaries for your " @@ -94,7 +97,8 @@ def cleanup_and_fetch_binaries(clean=True): continue folders = path.split(os.sep) _, file_path = os.sep.join(folders[:-1]), folders[-1] - file_name = f"{file_path[:-3]}_{tag}.so" + ext = "pyd" if os.name == "nt" else "so" + file_name = f"{file_path[:-(len(ext)+1)]}_{tag}.{ext}" search_path = f"{module}/{file_name}" try: response = request.urlopen( diff --git a/ivy/utils/einsum_parser.py b/ivy/utils/einsum_parser.py index 697e47d39494b..46705dd798b60 100644 --- a/ivy/utils/einsum_parser.py +++ b/ivy/utils/einsum_parser.py @@ -178,7 +178,7 @@ def convert_subscripts(old_sub: List[Any], symbol_map: Dict[Any, Any]) -> str: def convert_interleaved_input( - operands: Union[List[Any], Tuple[Any]] + operands: Union[List[Any], Tuple[Any]], ) -> Tuple[str, List[Any]]: """Convert 'interleaved' input to standard einsum input.""" tmp_operands = list(operands) diff --git a/ivy/utils/profiler.py b/ivy/utils/profiler.py index 05b7d016a3a16..7558dce70d32a 100644 --- a/ivy/utils/profiler.py +++ b/ivy/utils/profiler.py @@ -53,3 +53,162 @@ def __exit__(self, *exc): if self.print_stats: stats.print_stats() + + +def tensorflow_profile_start( + logdir: str, + host_tracer_level: int = 2, + python_tracer_level: int = 0, + device_tracer_level: int = 1, + delay_ms: int = None, +): + """Initialize and start the profiler. + + Parameters + ---------- + logdir: str + Directory where the profile data will be saved to. + host_tracer_level: int + Adjust CPU tracing level. Values are: 1 - critical info only, 2 - info, 3 - verbose. [default value is 2] + python_tracer_level: int + Toggle tracing of Python function calls. Values are: 1 - enabled, 0 - disabled [default value is 0] + device_tracer_level: int + Adjust device (TPU/GPU) tracing level. Values are: 1 - enabled, 0 - disabled [default value is 1] + delay_ms: int + Requests for all hosts to start profiling at a timestamp that is delay_ms away from the current time. delay_ms is in milliseconds. If zero, each host will start profiling immediately upon receiving the request. Default value is None, allowing the profiler guess the best value. + Save the weights on the Module. + + Returns + ------- + None + """ # noqa: E501 + from tensorflow.profiler.experimental import ProfilerOptions, start + + options = ProfilerOptions( + host_tracer_level=host_tracer_level, + python_tracer_level=python_tracer_level, + device_tracer_level=device_tracer_level, + delay_ms=delay_ms, + ) + start(logdir, options=options) + + +def tensorflow_profile_stop(): + """Stop the profiler.""" + from tensorflow.profiler.experimental import stop + + stop() + + +def torch_profiler_init( + logdir=None, + activities=None, + schedule=None, + on_trace_ready=None, + record_shapes=False, + profile_memory=False, + with_stack=False, + with_flops=False, + with_modules=False, + experimental_config=None, +): + """Initialize and returns a Torch profiler instance. + + Parameters + ---------- + logdir : str + Directory where the profile data will be saved to. + + activities : iterable + list of activity groups (CPU, CUDA) to use in profiling, supported values: + ``torch.profiler.ProfilerActivity.CPU``, ``torch.profiler.ProfilerActivity.CUDA``. + Default value: ProfilerActivity.CPU and (when available) ProfilerActivity.CUDA. + + schedule : Callable + callable that takes step (int) as a single parameter and returns + ``ProfilerAction`` value that specifies the profiler action to perform at each step. + + on_trace_ready : Callable + callable that is called at each step when ``schedule`` + returns ``ProfilerAction.RECORD_AND_SAVE`` during the profiling. + + record_shapes : bool + save information about operator's input shapes. + + profile_memory : bool + track tensor memory allocation/deallocation. + + with_stack : bool + record source information (file and line number) for the ops. + + with_flops : bool + use formula to estimate the FLOPs (floating point operations) of specific operators + (matrix multiplication and 2D convolution). + + with_modules : bool + record module hierarchy (including function names) + corresponding to the callstack of the op. e.g. If module A's forward call's + module B's forward which contains an aten::add op, then aten::add's module hierarchy is A.B + Note that this support exist, at the moment, only for TorchScript models + and not eager mode models. + + experimental_config _ExperimentalConfig : _ExperimentalConfig + A set of experimental options + used for Kineto library features. Note, backward compatibility is not guaranteed. + + Returns + ------- + Torch profiler instance. + """ # noqa: E501 + from torch.profiler import profile, tensorboard_trace_handler + + profiler = profile( + activities=activities, + schedule=schedule, + on_trace_ready=( + tensorboard_trace_handler(logdir) + if on_trace_ready is None and logdir is not None + else on_trace_ready + ), + record_shapes=record_shapes, + profile_memory=profile_memory, + with_stack=with_stack, + with_flops=with_flops, + with_modules=with_modules, + experimental_config=experimental_config, + ) + return profiler + + +def torch_profiler_start(profiler): + """Start the profiler. + + Parameters + ---------- + profiler : torch.profiler.profile + Torch profiler instance. + + Returns + ------- + None + """ + profiler.start() + + +def torch_profiler_stop(profiler): + """Start the profiler. + + Parameters + ---------- + profiler : torch.profiler.profile + Torch profiler instance. + + Returns + ------- + None + """ + from torch.autograd.profiler import KinetoStepTracker + from torch.profiler.profiler import PROFILER_STEP_NAME + + profiler.stop() + KinetoStepTracker.erase_step_count(PROFILER_STEP_NAME) diff --git a/ivy/utils/profiler_example.ipynb b/ivy/utils/profiler_example.ipynb new file mode 100644 index 0000000000000..a49999df0bd8d --- /dev/null +++ b/ivy/utils/profiler_example.ipynb @@ -0,0 +1,143 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "from torch import nn\n", + "import tensorflow as tf\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class TFModel(tf.keras.Model):\n", + " def __init__(self):\n", + " super().__init__()\n", + " self.lin = tf.keras.layers.Dense(10, activation=tf.nn.relu)\n", + " \n", + " def call(self, inputs, training=False):\n", + " return self.lin(inputs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class TorchModel(nn.Module):\n", + " def __init__(self):\n", + " super().__init__()\n", + " self.lin = nn.Linear(10, 10)\n", + " \n", + " def forward(self, x):\n", + " return self.lin(x)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tf_model = tf.function(TFModel()) \n", + "inp = np.random.random((10, 10))\n", + "x = tf.convert_to_tensor(inp, dtype=tf.float32)\n", + "tf_model(x)\n", + "\n", + "tf_model.summary()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "torch_model = torch.compile(TorchModel())\n", + "inp2 = np.random.random((10, 10)).astype(np.float32)\n", + "x2 = torch.from_numpy(inp2)\n", + "torch_model, torch_model(x2).shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creating the Profiler Logs TensorFlow" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "logs = 'logs/' + \"tensorflow\"\n", + "\n", + "from ivy.utils.profiler import tensorflow_profile_start, tensorflow_profile_stop\n", + "tensorflow_profile_start(logs, \n", + " host_tracer_level = 3,\n", + " python_tracer_level = 1,\n", + " device_tracer_level = 1)\n", + "tf_model(x)\n", + "tensorflow_profile_stop()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Launch TensorBoard and navigate to the Profile tab to view performance profile \n", + "!tensorboard --logdir='logs/'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creating the Profiler Logs Torch" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from ivy.utils.profiler import torch_profiler_init, torch_profiler_start, torch_profiler_stop\n", + "profiler = torch_profiler_init(activities=[torch.profiler.ProfilerActivity.CPU, torch.profiler.ProfilerActivity.CUDA ],\n", + " on_trace_ready=torch.profiler.tensorboard_trace_handler('./logs/torch'),\n", + " record_shapes=True,\n", + " profile_memory=True,\n", + " with_stack=True)\n", + "torch_profiler_start(profiler)\n", + "torch_model(x2)\n", + "torch_profiler_stop(profiler)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "multienv", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.10.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/ivy/wrappers/__init__.py b/ivy/wrappers/__init__.py new file mode 100644 index 0000000000000..880046091c527 --- /dev/null +++ b/ivy/wrappers/__init__.py @@ -0,0 +1,29 @@ +import os +import sys +import glob +import importlib + +dir_path = os.path.dirname(os.path.realpath(__file__)) +so_files = glob.glob(dir_path + "/*.so") +sys.path.append(dir_path) + +__all__ = [] + +for so_file in so_files: + # if os.path.basename(so_file) != "add.so": + # continue + module_name = os.path.splitext(os.path.basename(so_file))[0] + + locals()[module_name] = importlib.import_module(module_name) + + if module_name + "_wrapper" in locals()[module_name].__dict__.keys(): + locals()[module_name + "_wrapper"] = getattr( + locals()[module_name], module_name + "_wrapper" + ) + __all__.append(module_name + "_wrapper") + +del dir_path +del so_files + +import utils +from utils import * diff --git a/ivy/wrappers/utils.py b/ivy/wrappers/utils.py new file mode 100644 index 0000000000000..7702f70f4456e --- /dev/null +++ b/ivy/wrappers/utils.py @@ -0,0 +1,55 @@ +import os +import logging +import json +from urllib import request +import importlib +import ivy + +folder_path = os.sep.join(__file__.split(os.sep)[:-3]) +wrappers_path = os.path.join(folder_path, "wrappers.json") +if os.path.exists(wrappers_path): + wrappers = json.loads(open(wrappers_path).read()) +wrapers_dir = os.path.join(folder_path, "ivy/wrappers") + + +def download_cython_wrapper(func_name: str): + """Get the wrapper for the given function name.""" + if func_name + ".so" not in wrappers["ivy"]["functional"]: + logging.warning(f"Wrapper for {func_name} not found.") + return False + try: + response = request.urlopen( + "https://raw.githubusercontent.com/unifyai" + + "/binaries/cython_wrappers/wrappers/" + + func_name + + ".so" + ) + os.makedirs(wrapers_dir, exist_ok=True) + with open(os.path.join(wrapers_dir, func_name + ".so"), "wb") as f: + f.write(response.read()) + print("Downloaded wrapper for " + func_name) + return True + except request.HTTPError: + logging.warning(f"Unable to download wrapper for {func_name}.") + return False + + +def wrapper_exists(func_name: str): + """Check if the wrapper for the given function name exists.""" + return func_name + ".so" in wrappers["ivy"]["functional"] + + +def load_one_wrapper(func_name: str): + """Load the wrapper for the given function name.""" + module_name = func_name + dir_path = os.path.dirname(os.path.realpath(__file__)) + # check if file exists + if os.path.isfile(os.path.join(dir_path, module_name + ".so")): + ivy.wrappers.__dict__[module_name] = importlib.import_module(module_name) + ivy.wrappers.__dict__[module_name + "_wrapper"] = getattr( + ivy.wrappers.__dict__[module_name], module_name + "_wrapper" + ) + ivy.wrappers.__all__.append(module_name + "_wrapper") + return True + else: + return False diff --git a/ivy_tests/test_docstrings.py b/ivy_tests/test_docstrings.py index 0f582920243ef..0cc34ffed62ff 100644 --- a/ivy_tests/test_docstrings.py +++ b/ivy_tests/test_docstrings.py @@ -6,6 +6,7 @@ import numpy as np import sys + warnings.filterwarnings("ignore", category=DeprecationWarning) import pytest @@ -115,93 +116,38 @@ def check_docstring_examples_run( # the temp skip list consists of functions # which have an issue with their implementation skip_list_temp = [ - "outer", - "argmax", - "split", - "det", - "cumprod", - "sinc", - "grad", - "try_else_none", - # all examples are wrong including functional/ivy - "einops_reduce", - "max_unpool1d", - "pool", - "put_along_axis", - "result_type", - # works only if no backend set - "rfftn", - # examples works but exec throws error or generate diff results - "scaled_dot_product_attention", - "searchsorted", - # generates different results in different backends - "eigh_tridiagonal", - "log_poisson_loss", + "outer", # Failing only torch backend as inputs must be 1-D. + "pool", # Maximum recursion depth exceeded ivy.pool + "put_along_axis", # Depends on scatter_nd for numpy. + "result_type", # Different ouput coming for diff backends in 1st example. + "scaled_dot_product_attention", # Different backends giving different answers. + "eigh_tridiagonal", # Failing only for TF backend "dct", - "idct", - "set_item", - "l1_normalize", - "histogram", - "native_array", - "function_supported_devices", - "acosh", - "bitwise_invert", - "cosh", - "exp", - "sinh", - "reciprocal", - "deg2rad", - "value_and_grad", - "vector_norm", - "set_nest_at_index", - "set_nest_at_indices", - "layer_norm", - "where", - "trace", - "eigvalsh", - "conv2d_transpose", - # fails due to different backend and their view types - "sequence_length", - "max_pool1d", - "vmap", - "inner", - "slogdet", - "svdvals", - "nested_map", - "dill", - "hardtanh", - "hardshrink", - "rfft", - "general_inner_product", - "l1_loss", - "smooth_l1_loss", - "poisson_nll_loss", - "choose", - "cummax", - "one_hot", - "tpu_is_available", - "log2", - "maximum", - "minimum", - "get_referrers_recursive", - "clip_vector_norm", - "set_min_base", - "scatter_flat", - "scatter_nd", + "choose", # Maximum recurion depth exceeded (No backend choose fn). + "idct", # Function already failing for all 5 backends. + "set_item", # Different errors for diff backends (jax, torch) + "l1_normalize", # Function already failing for all 5 backends. + "histogram", # Failing for TF, Torch backends (TODO's left) + "value_and_grad", # Failing only for Torch backend. (Requires_grad=True) + "layer_norm", # Failing only for Torch backend. + "eigvalsh", # Failing only Jax Backend + only for Native Array Example. + "conv2d_transpose", # Function already failing for all 5 backends. + "solve", + "one_hot", # One small example failing for all backends except torch. + "scatter_flat", # Function Already failing for 3 backends + "scatter_nd", # + "execute_with_gradients", # Function Already failing for 4 backends. "gather", "multiprocessing", - "execute_with_gradients", - "solve", - "tensordot", - "cross_entropy", - "binary_cross_entropy", - "sparse_cross_entropy", - "reptile_step", - "insert_into_nest_at_index", "if_else", + "trace_graph", # SystemExit: Please sign up for free pilot access. + "dill", + "smooth_l1_loss", # Function already failing for all 5 backends. + "cummax", # Function already failing for all 5 backends. + "insert_into_nest_at_index", "while_loop", - "trace_graph", - "set_tmp_dir", + "argmax", + "native_array", ] # skip list for array and container docstrings diff --git a/ivy_tests/test_ivy/conftest.py b/ivy_tests/test_ivy/conftest.py index 06b4054ff086f..3776351090e77 100644 --- a/ivy_tests/test_ivy/conftest.py +++ b/ivy_tests/test_ivy/conftest.py @@ -198,12 +198,14 @@ def pytest_configure(config): continue for trace_graph in trace_modes: for implicit in implicit_modes: - TEST_PARAMS_CONFIG.append(( - device, - backend_str, - trace_graph, - implicit, - )) + TEST_PARAMS_CONFIG.append( + ( + device, + backend_str, + trace_graph, + implicit, + ) + ) process_cl_flags(config) @@ -292,6 +294,10 @@ def process_cl_flags(config) -> Dict[str, bool]: False, getopt("--with-transpile"), ), + "test_cython_wrapper": ( + getopt("--skip-cython-wrapper-testing"), + getopt("--with-cython-wrapper-testing"), + ), } # whether to skip gt testing or not @@ -358,6 +364,8 @@ def pytest_addoption(parser): default=None, help="Print test items in my custom format", ) + parser.addoption("--skip-cython-wrapper-testing", action="store_true") + parser.addoption("--with-cython-wrapper-testing", action="store_true") def pytest_collection_finish(session): diff --git a/ivy_tests/test_ivy/helpers/assertions.py b/ivy_tests/test_ivy/helpers/assertions.py index b2403339f7b5f..a4f7a942a4080 100644 --- a/ivy_tests/test_ivy/helpers/assertions.py +++ b/ivy_tests/test_ivy/helpers/assertions.py @@ -58,6 +58,8 @@ def assert_all_close( f" the results from backend {backend} " f"and ground truth framework {ground_truth_backend} " f"do not match\n {ret_np}!={ret_from_gt_np} \n\n" + "The mismatching elements are at `False` indices:\n\n" + f"{ret_np == ret_from_gt_np} \n\n" ) diff --git a/ivy_tests/test_ivy/helpers/function_testing.py b/ivy_tests/test_ivy/helpers/function_testing.py index c86ac233d22e8..4e0f7126b1dd4 100644 --- a/ivy_tests/test_ivy/helpers/function_testing.py +++ b/ivy_tests/test_ivy/helpers/function_testing.py @@ -38,7 +38,39 @@ def traced_if_required(backend: str, fn, test_trace=False, args=None, kwargs=None): with BackendHandler.update_backend(backend) as ivy_backend: if test_trace: - fn = ivy_backend.trace_graph(fn, args=args, kwargs=kwargs) + try: + if ( + t_globals.CURRENT_RUNNING_TEST.fn_name + in t_globals.CURRENT_TRACED_DATA + and backend + not in t_globals.CURRENT_TRACED_DATA[ + t_globals.CURRENT_RUNNING_TEST.fn_name + ] + ): + t_globals.CURRENT_TRACED_DATA[ + t_globals.CURRENT_RUNNING_TEST.fn_name + ][backend] = ivy_backend.trace_graph( + fn, args=args, kwargs=kwargs, backend_compile=True + ) + elif ( + t_globals.CURRENT_RUNNING_TEST.fn_name + not in t_globals.CURRENT_TRACED_DATA + ): + t_globals.CURRENT_TRACED_DATA[ + t_globals.CURRENT_RUNNING_TEST.fn_name + ] = {} + t_globals.CURRENT_TRACED_DATA[ + t_globals.CURRENT_RUNNING_TEST.fn_name + ][backend] = ivy_backend.trace_graph( + fn, args=args, kwargs=kwargs, backend_compile=True + ) + fn = t_globals.CURRENT_TRACED_DATA[ + t_globals.CURRENT_RUNNING_TEST.fn_name + ][backend] + except Exception: + import logging + + logging.warning("API key is invalid, test_trace is skipped.") return fn @@ -126,6 +158,11 @@ def test_function_backend_computation( test_flags.container[0] for _ in range(total_num_arrays) ] + if test_flags.test_cython_wrapper: + ivy.set_cython_wrappers_mode(True) + else: + ivy.set_cython_wrappers_mode(False) + with BackendHandler.update_backend(fw) as ivy_backend: # Update variable flags to be compatible with float dtype and with_out args test_flags.as_variable = [ @@ -209,6 +246,7 @@ def target_fn(instance, *args, **kwargs): target_fn, *copy_args, test_trace=test_flags.test_trace, + precision_mode=test_flags.precision_mode, **copy_kwargs, ) @@ -232,14 +270,24 @@ def target_fn(instance, *args, **kwargs): ret_from_target, ret_np_flat_from_target, ) = get_ret_and_flattened_np_array( - fw, instance.__getattribute__(fn_name), *args, **kwargs, out=out + fw, + instance.__getattribute__(fn_name), + *args, + **kwargs, + out=out, + precision_mode=test_flags.precision_mode, ) else: ( ret_from_target, ret_np_flat_from_target, ) = get_ret_and_flattened_np_array( - fw, ivy_backend.__dict__[fn_name], *args, **kwargs, out=out + fw, + ivy_backend.__dict__[fn_name], + *args, + **kwargs, + out=out, + precision_mode=test_flags.precision_mode, ) test_ret = ( ret_from_target[getattr(ivy_backend.__dict__[fn_name], "out_index")] @@ -281,6 +329,8 @@ def target_fn(instance, *args, **kwargs): precision_mode=test_flags.precision_mode, **kwargs, ) + first_array = ivy_backend.stop_gradient(first_array).to_numpy() + ret_ = ivy_backend.stop_gradient(ret_).to_numpy() assert not np.may_share_memory(first_array, ret_) ret_device = None @@ -479,15 +529,17 @@ def test_function( if mod_backend[backend_to_test]: # multiprocessing proc, input_queue, output_queue = mod_backend[backend_to_test] - input_queue.put(( - "function_backend_computation", - backend_to_test, - test_flags, - all_as_kwargs_np, - input_dtypes, - on_device, - fn_name, - )) + input_queue.put( + ( + "function_backend_computation", + backend_to_test, + test_flags, + all_as_kwargs_np, + input_dtypes, + on_device, + fn_name, + ) + ) ( ret_from_target, ret_np_flat_from_target, @@ -526,20 +578,22 @@ def test_function( # compute the return with a Ground Truth backend if mod_backend[ground_truth_backend]: proc, input_queue, output_queue = mod_backend[ground_truth_backend] - input_queue.put(( - "function_ground_truth_computation", - ground_truth_backend, - on_device, - args_np, - arg_np_arrays, - arrays_args_indices, - kwargs_np, - arrays_kwargs_indices, - kwarg_np_arrays, - input_dtypes, - test_flags, - fn_name, - )) + input_queue.put( + ( + "function_ground_truth_computation", + ground_truth_backend, + on_device, + args_np, + arg_np_arrays, + arrays_args_indices, + kwargs_np, + arrays_kwargs_indices, + kwarg_np_arrays, + input_dtypes, + test_flags, + fn_name, + ) + ) ( ret_from_gt, ret_np_from_gt_flat, @@ -571,13 +625,15 @@ def test_function( if test_flags.transpile: if mod_backend[backend_to_test]: proc, input_queue, output_queue = mod_backend[backend_to_test] - input_queue.put(( - "transpile_if_required_backend", - backend_to_test, - fn_name, - args_np, - kwargs_np, - )) + input_queue.put( + ( + "transpile_if_required_backend", + backend_to_test, + fn_name, + args_np, + kwargs_np, + ) + ) else: _transpile_if_required_backend( backend_to_test, fn_name, args=args_np, kwargs=kwargs_np @@ -637,9 +693,13 @@ def test_function( backend=backend_to_test, ground_truth_backend=test_flags.ground_truth_backend, ) - assert_same_type( - ret_from_target, ret_from_gt, backend_to_test, test_flags.ground_truth_backend - ) + if not test_flags.test_trace: + assert_same_type( + ret_from_target, + ret_from_gt, + backend_to_test, + test_flags.ground_truth_backend, + ) assert ret_device == ret_from_gt_device, ( f"ground truth backend ({test_flags.ground_truth_backend}) returned array on" @@ -932,7 +992,12 @@ def test_frontend_function( first_array = first_array.data ret_ = ret_.data if hasattr(first_array, "requires_grad"): - first_array.requires_grad = False + first_array = first_array.detach() + if hasattr(ret_, "requires_grad"): + ret_ = ret_.detach() + if backend_to_test == "tensorflow": + first_array = first_array.numpy() + ret_ = ret_.numpy() assert not np.may_share_memory(first_array, ret_) elif test_flags.inplace: assert _is_frontend_array(ret) @@ -1215,23 +1280,25 @@ def gradient_test( if mod_backend[backend_to_test]: # do this using multiprocessing proc, input_queue, output_queue = mod_backend[backend_to_test] - input_queue.put(( - "gradient_backend_computation", - backend_to_test, - args_np, - arg_np_vals, - args_idxs, - kwargs_np, - kwarg_np_vals, - kwargs_idxs, - input_dtypes, - test_flags, - on_device, - fn, - test_trace, - xs_grad_idxs, - ret_grad_idxs, - )) + input_queue.put( + ( + "gradient_backend_computation", + backend_to_test, + args_np, + arg_np_vals, + args_idxs, + kwargs_np, + kwarg_np_vals, + kwargs_idxs, + input_dtypes, + test_flags, + on_device, + fn, + test_trace, + xs_grad_idxs, + ret_grad_idxs, + ) + ) grads_np_flat = output_queue.get() else: @@ -1255,24 +1322,26 @@ def gradient_test( if mod_backend[ground_truth_backend]: # do this using multiprocessing proc, input_queue, output_queue = mod_backend[ground_truth_backend] - input_queue.put(( - "gradient_ground_truth_computation", - ground_truth_backend, - on_device, - fn, - input_dtypes, - all_as_kwargs_np, - args_np, - arg_np_vals, - args_idxs, - kwargs_np, - kwarg_np_vals, - test_flags, - kwargs_idxs, - test_trace, - xs_grad_idxs, - ret_grad_idxs, - )) + input_queue.put( + ( + "gradient_ground_truth_computation", + ground_truth_backend, + on_device, + fn, + input_dtypes, + all_as_kwargs_np, + args_np, + arg_np_vals, + args_idxs, + kwargs_np, + kwarg_np_vals, + test_flags, + kwargs_idxs, + test_trace, + xs_grad_idxs, + ret_grad_idxs, + ) + ) grads_np_from_gt_flat = output_queue.get() else: grads_np_from_gt_flat = test_gradient_ground_truth_computation( @@ -1680,22 +1749,24 @@ def test_method( if mod_backend[backend_to_test]: # yep, multiprocessing proc, input_queue, output_queue = mod_backend[backend_to_test] - input_queue.put(( - "method_backend_computation", - init_input_dtypes, - init_flags, - backend_to_test, - init_all_as_kwargs_np, - on_device, - method_input_dtypes, - method_flags, - method_all_as_kwargs_np, - class_name, - method_name, - init_with_v, - test_trace, - method_with_v, - )) + input_queue.put( + ( + "method_backend_computation", + init_input_dtypes, + init_flags, + backend_to_test, + init_all_as_kwargs_np, + on_device, + method_input_dtypes, + method_flags, + method_all_as_kwargs_np, + class_name, + method_name, + init_with_v, + test_trace, + method_with_v, + ) + ) ( ret, ret_np_flat, @@ -1744,24 +1815,26 @@ def test_method( if mod_backend[ground_truth_backend]: # yep, multiprocessing proc, input_queue, output_queue = mod_backend[ground_truth_backend] - input_queue.put(( - "method_ground_truth_computation", - ground_truth_backend, - on_device, - org_con_data, - args_np_method, - met_arg_np_vals, - met_args_idxs, - kwargs_np_method, - met_kwarg_np_vals, - met_kwargs_idxs, - method_input_dtypes, - method_flags, - class_name, - method_name, - test_trace, - v_np, - )) + input_queue.put( + ( + "method_ground_truth_computation", + ground_truth_backend, + on_device, + org_con_data, + args_np_method, + met_arg_np_vals, + met_args_idxs, + kwargs_np_method, + met_kwarg_np_vals, + met_kwargs_idxs, + method_input_dtypes, + method_flags, + class_name, + method_name, + test_trace, + v_np, + ) + ) ( ret_from_gt, ret_np_from_gt_flat, diff --git a/ivy_tests/test_ivy/helpers/globals.py b/ivy_tests/test_ivy/helpers/globals.py index 02d2f16d2b122..d1a4fb6e83791 100644 --- a/ivy_tests/test_ivy/helpers/globals.py +++ b/ivy_tests/test_ivy/helpers/globals.py @@ -46,6 +46,7 @@ CURRENT_DEVICE = _Notsetval CURRENT_DEVICE_STRIPPED = _Notsetval CURRENT_FRONTEND_STR = None +CURRENT_TRACED_DATA = {} @dataclass(frozen=True) # ToDo use kw_only=True when version is updated diff --git a/ivy_tests/test_ivy/helpers/hypothesis_helpers/array_helpers.py b/ivy_tests/test_ivy/helpers/hypothesis_helpers/array_helpers.py index a0d522617220d..28330daec930d 100644 --- a/ivy_tests/test_ivy/helpers/hypothesis_helpers/array_helpers.py +++ b/ivy_tests/test_ivy/helpers/hypothesis_helpers/array_helpers.py @@ -802,6 +802,12 @@ def array_indices_axis( *, array_dtypes, indices_dtypes=get_dtypes("valid"), + abs_smallest_val=None, + min_value=None, + max_value=None, + large_abs_safety_factor=1.1, + small_abs_safety_factor=1.1, + safety_factor_scale="linear", disable_random_axis=False, axis_zero=False, allow_inf=False, @@ -826,6 +832,37 @@ def array_indices_axis( list of data type to draw the array dtype from. indices_dtypes list of data type to draw the indices dtype from. + abs_smallest_val + sets the absolute smallest value to be generated for float data types, + this has no effect on integer data types. If none, the default data type + absolute smallest value is used. + min_value + minimum value of elements in the array. + max_value + maximum value of elements in the array. + large_abs_safety_factor + A safety factor of 1 means that all values are included without limitation, + + when a "linear" safety factor scaler is used, a safety factor of 2 means + that only 50% of the range is included, a safety factor of 3 means that + only 33% of the range is included etc. + + when a "log" safety factor scaler is used, a data type with maximum + value of 2^32 and a safety factor of 2 transforms the maximum to 2^16. + small_abs_safety_factor + A safety factor of 1 means that all values are included without limitation, + this has no effect on integer data types. + + when a "linear" safety factor scaler is used, a data type with minimum + representable number of 0.0001 and a safety factor of 2 transforms the + minimum to 0.0002, a safety factor of 3 transforms the minimum to 0.0003 etc. + + when a "log" safety factor scaler is used, a data type with minimum + representable number of 0.5 * 2^-16 and a safety factor of 2 transforms the + minimum to 0.5 * 2^-8, a safety factor of 3 transforms the minimum to 0.5 * 2^-4 + safety_factor_scale + The operation to use for the safety factor scaling. Can be "linear" or "log". + Default value = "linear". disable_random_axis axis is randomly generated with hypothesis if False. If True, axis is set to 0 if axis_zero is True, -1 otherwise. @@ -961,6 +998,12 @@ def array_indices_axis( max_num_dims=max_num_dims, min_dim_size=min_dim_size, max_dim_size=max_dim_size, + abs_smallest_val=abs_smallest_val, + min_value=min_value, + max_value=max_value, + large_abs_safety_factor=large_abs_safety_factor, + small_abs_safety_factor=small_abs_safety_factor, + safety_factor_scale=safety_factor_scale, ) ) x_dtype = x_dtype[0] @@ -1871,6 +1914,7 @@ def dtype_array_query( shape=shape, large_abs_safety_factor=2, small_abs_safety_factor=2, + safety_factor_scale="log", ) ) if allow_mask and draw(st.booleans()): @@ -1892,6 +1936,7 @@ def dtype_array_query( ) index_types = [v if shape[i] > 0 else "slice" for i, v in enumerate(index_types)] index = [] + empty_array = prod(shape) == 0 for s, index_type in zip(shape, index_types): if index_type == "int": new_index = draw(st.integers(min_value=-s + 1, max_value=s - 1)) @@ -1899,8 +1944,8 @@ def dtype_array_query( new_index = draw( st.lists( st.integers(min_value=-s + 1, max_value=s - 1), - min_size=1, - max_size=20, + min_size=1 if not empty_array else 0, + max_size=20 if not empty_array else 0, ) ) elif index_type == "array": @@ -1910,6 +1955,8 @@ def dtype_array_query( max_value=s - 1, dtype=["int64"], max_num_dims=4, + min_dim_size=1 if not empty_array else 0, + max_dim_size=10 if not empty_array else 0, ) ) new_index = new_index[0] @@ -1989,6 +2036,7 @@ def dtype_array_query_val( shape=val_shape, large_abs_safety_factor=2, small_abs_safety_factor=2, + safety_factor_scale="log", ) ) val_dtype = draw( diff --git a/ivy_tests/test_ivy/helpers/hypothesis_helpers/general_helpers.py b/ivy_tests/test_ivy/helpers/hypothesis_helpers/general_helpers.py index 13369be1461dd..a6f86024384b2 100644 --- a/ivy_tests/test_ivy/helpers/hypothesis_helpers/general_helpers.py +++ b/ivy_tests/test_ivy/helpers/hypothesis_helpers/general_helpers.py @@ -648,3 +648,54 @@ def embedding_helper(draw, mixed_fn_compos=True): ) padding_idx = draw(st.integers(min_value=0, max_value=num_embeddings - 1)) return dtype_indices + dtype_weight, indices[0], weight[0], padding_idx + + +def sizes_(shape, axis): + def factorization(n): + factors = [1] + + def get_factor(n): + x_fixed = 2 + cycle_size = 2 + x = 2 + factor = 1 if n % 2 else 2 + while factor == 1: + for count in range(cycle_size): + if factor > 1: + break + x = (x * x + 1) % n + factor = math.gcd(x - x_fixed, n) + + cycle_size *= 2 + x_fixed = x + + return factor + + while n > 1: + next = get_factor(n) + factors.append(next) + n //= next + if len(factors) > 1: + factors.remove(1) + return factors + + shape_ = ( + tuple(factorization(shape[axis])) + if tuple(factorization(shape[axis])) + else shape + ) + return shape_ + + +@st.composite +def dims_and_offset(draw, shape, ensure_dim_unique=False): + shape_actual = draw(shape) + dim1 = draw(get_axis(shape=shape, force_int=True)) + dim2 = draw(get_axis(shape=shape, force_int=True)) + if ensure_dim_unique: + while dim1 == dim2: + dim2 = draw(get_axis(shape=shape, force_int=True)) + offset = draw( + st.integers(min_value=-shape_actual[dim1], max_value=shape_actual[dim1]) + ) + return dim1, dim2, offset diff --git a/ivy_tests/test_ivy/helpers/multiprocessing.py b/ivy_tests/test_ivy/helpers/multiprocessing.py index 86f2d20971336..39234c644de27 100644 --- a/ivy_tests/test_ivy/helpers/multiprocessing.py +++ b/ivy_tests/test_ivy/helpers/multiprocessing.py @@ -101,19 +101,21 @@ def backend_proc(input_queue, output_queue): ) # ret_from_target to be none, because main process has # framework imports blocked - output_queue.put(( - (None), - ret_np_flat_from_target, - ret_device, - args_np, - arg_np_arrays, - arrays_args_indices, - kwargs_np, - arrays_kwargs_indices, - kwarg_np_arrays, - test_flags, - input_dtypes, - )) + output_queue.put( + ( + (None), + ret_np_flat_from_target, + ret_device, + args_np, + arg_np_arrays, + arrays_args_indices, + kwargs_np, + arrays_kwargs_indices, + kwarg_np_arrays, + test_flags, + input_dtypes, + ) + ) elif data[0] == "function_ground_truth_computation": # it's the ground_truth return computation ( @@ -150,13 +152,15 @@ def backend_proc(input_queue, output_queue): fn_name, ) # ret_from gt is none because main process has frameworks is None - output_queue.put(( - (None), - ret_np_from_gt_flat, - ret_from_gt_device, - test_flags, - fw_list, - )) + output_queue.put( + ( + (None), + ret_np_from_gt_flat, + ret_from_gt_device, + test_flags, + fw_list, + ) + ) elif data[0] == "gradient_backend_computation": # gradient testing , part where it uses the backend ( @@ -279,20 +283,22 @@ def backend_proc(input_queue, output_queue): method_with_v, ) # ret is none here, because main process doesn't import framework - output_queue.put(( - (None), - ret_np_flat, - ret_device, - org_con_data, - args_np_method, - met_arg_np_vals, - met_args_idxs, - kwargs_np_method, - met_kwarg_np_vals, - met_kwargs_idxs, - v_np, - fw_list, - )) + output_queue.put( + ( + (None), + ret_np_flat, + ret_device, + org_con_data, + args_np_method, + met_arg_np_vals, + met_args_idxs, + kwargs_np_method, + met_kwarg_np_vals, + met_kwargs_idxs, + v_np, + fw_list, + ) + ) elif data[0] == "method_ground_truth_computation": ( diff --git a/ivy_tests/test_ivy/helpers/pipeline_helper.py b/ivy_tests/test_ivy/helpers/pipeline_helper.py index f704ab4cd171d..361177808f3b9 100644 --- a/ivy_tests/test_ivy/helpers/pipeline_helper.py +++ b/ivy_tests/test_ivy/helpers/pipeline_helper.py @@ -11,11 +11,12 @@ class BackendHandlerMode(Enum): class WithBackendContext: - def __init__(self, backend) -> None: + def __init__(self, backend, cached=True) -> None: self.backend = backend + self.cached = cached def __enter__(self): - return ivy.with_backend(self.backend) + return ivy.with_backend(self.backend, cached=self.cached) def __exit__(self, exc_type, exc_val, exc_tb): return diff --git a/ivy_tests/test_ivy/helpers/test_parameter_flags.py b/ivy_tests/test_ivy/helpers/test_parameter_flags.py index e123f1764db31..d3429718636d6 100644 --- a/ivy_tests/test_ivy/helpers/test_parameter_flags.py +++ b/ivy_tests/test_ivy/helpers/test_parameter_flags.py @@ -48,6 +48,7 @@ def _as_varaible_strategy(draw): BuiltFrontendArrayStrategy = DynamicFlag(st.booleans()) BuiltTranspileStrategy = DynamicFlag(st.just(False)) BuiltPrecisionModeStrategy = DynamicFlag(st.booleans()) +BuiltCythonWrapperStrategy = DynamicFlag(st.just(False)) flags_mapping = { @@ -62,6 +63,7 @@ def _as_varaible_strategy(draw): "test_trace": "BuiltTraceStrategy", "transpile": "BuiltTranspileStrategy", "precision_mode": "BuiltPrecisionModeStrategy", + "test_cython_wrapper": "BuiltCythonWrapperStrategy", } @@ -98,6 +100,7 @@ def __init__( test_trace, transpile, precision_mode, + test_cython_wrapper, ): self.ground_truth_backend = ground_truth_backend self.num_positional_args = num_positional_args @@ -111,6 +114,7 @@ def __init__( self.test_trace = test_trace self.transpile = transpile self.precision_mode = precision_mode + self.test_cython_wrapper = test_cython_wrapper def apply_flags(self, args_to_iterate, input_dtypes, offset, *, backend, on_device): ret = [] @@ -162,6 +166,7 @@ def function_flags( native_arrays, container_flags, precision_mode, + test_cython_wrapper, ): return draw( st.builds( @@ -178,6 +183,7 @@ def function_flags( native_arrays=native_arrays, container=container_flags, precision_mode=precision_mode, + test_cython_wrapper=test_cython_wrapper, ) ) diff --git a/ivy_tests/test_ivy/helpers/testing_helpers.py b/ivy_tests/test_ivy/helpers/testing_helpers.py index 1628eb85cd84d..37f87c76abda5 100644 --- a/ivy_tests/test_ivy/helpers/testing_helpers.py +++ b/ivy_tests/test_ivy/helpers/testing_helpers.py @@ -7,7 +7,7 @@ import functools from typing import List, Optional -from hypothesis import given, strategies as st +from hypothesis import given, strategies as st, example # local import ivy.functional.frontends.numpy as np_frontend @@ -30,6 +30,7 @@ BuiltFrontendArrayStrategy, BuiltTranspileStrategy, BuiltPrecisionModeStrategy, + BuiltCythonWrapperStrategy, ) from ivy_tests.test_ivy.helpers.structs import FrontendMethodData from ivy_tests.test_ivy.helpers.available_frameworks import available_frameworks @@ -230,13 +231,15 @@ def _get_method_supported_devices_dtypes( if mod_backend[backend_str]: # we gotta do this using multiprocessing proc, input_queue, output_queue = mod_backend[backend_str] - input_queue.put(( - "method supported dtypes", - method_name, - class_module.__name__, - class_name, - backend_str, - )) + input_queue.put( + ( + "method supported dtypes", + method_name, + class_module.__name__, + class_name, + backend_str, + ) + ) supported_device_dtypes[backend_str] = output_queue.get() else: supported_device_dtypes[backend_str] = ( @@ -337,6 +340,7 @@ def handle_test( as_variable_flags=BuiltAsVariableStrategy, native_array_flags=BuiltNativeArrayStrategy, container_flags=BuiltContainerStrategy, + test_cython_wrapper=BuiltCythonWrapperStrategy, **_given_kwargs, ): """Test wrapper for Ivy functions. @@ -414,6 +418,7 @@ def handle_test( native_arrays=_get_runtime_flag_value(native_array_flags), container_flags=_get_runtime_flag_value(container_flags), precision_mode=_get_runtime_flag_value(precision_mode), + test_cython_wrapper=_get_runtime_flag_value(test_cython_wrapper), ) def test_wrapper(test_fn): @@ -934,3 +939,114 @@ def _create_transpile_report( json_object = json.dumps(data, indent=6) with open(file_name, "w") as outfile: outfile.write(json_object) + + +def handle_example( + *, + test_example: bool = False, + test_frontend_example: bool = False, + test_method_example: bool = False, + test_frontend_method_example: bool = False, + **given_kwargs, +): + if test_example: + test_flags = given_kwargs.get("test_flags", {}) + flags = pf.FunctionTestFlags( + ground_truth_backend=test_flags.get("ground_truth_backend", "numpy"), + num_positional_args=test_flags.get("num_positional_args", 0), + instance_method=test_flags.get("instance_method", False), + with_out=test_flags.get("with_out", False), + with_copy=test_flags.get("with_copy", False), + test_gradients=test_flags.get("test_gradients", False), + test_trace=test_flags.get("test_trace", False), + transpile=test_flags.get("transpile", False), + as_variable=test_flags.get("as_variable", [False]), + native_arrays=test_flags.get("native_arrays", [False]), + container=test_flags.get("container", [False]), + precision_mode=test_flags.get("precision_mode", False), + test_cython_wrapper=test_flags.get("test_cython_wrapper", False), + ) + + given_kwargs["test_flags"] = flags + + elif test_frontend_example: + test_flags = given_kwargs.get("test_flags", {}) + flags = pf.FrontendFunctionTestFlags( + num_positional_args=test_flags.get("num_positional_args", 0), + with_out=test_flags.get("with_out", False), + with_copy=test_flags.get("with_copy", False), + inplace=test_flags.get("inplace", False), + as_variable=test_flags.get("as_variable", [False]), + native_arrays=test_flags.get("native_arrays", [False]), + test_trace=test_flags.get("test_trace", False), + generate_frontend_arrays=test_flags.get("generate_frontend_arrays", False), + transpile=test_flags.get("transpile", False), + precision_mode=test_flags.get("precision_mode", False), + ) + + given_kwargs["test_flags"] = flags + + elif test_method_example: + method_flags = given_kwargs.get("method_flags", {}) + init_flags = given_kwargs.get("init_flags", {}) + flags_1 = pf.MethodTestFlags( + num_positional_args=method_flags.get("num_positional_args", 0), + as_variable=method_flags.get("as_variable", [False]), + native_arrays=method_flags.get("native_arrays", [False]), + container_flags=method_flags.get("container", [False]), + precision_mode=method_flags.get("precision_mode", False), + ) + + flags_2 = pf.InitMethodTestFlags( + num_positional_args=init_flags.get("num_positional_args", 0), + as_variable=init_flags.get("as_variable", [False]), + native_arrays=init_flags.get("native_arrays", [False]), + precision_mode=init_flags.get("precision_mode", False), + ) + + given_kwargs["method_flags"] = flags_1 + given_kwargs["init_flags"] = flags_2 + + elif test_frontend_method_example: + method_flags = given_kwargs.get("method_flags", {}) + init_flags = given_kwargs.get("init_flags", {}) + flags_1 = pf.FrontendMethodTestFlags( + num_positional_args=method_flags.get("num_positional_args", 0), + as_variable=method_flags.get("as_variable", [False]), + native_arrays=method_flags.get("native_arrays", [False]), + precision_mode=method_flags.get("precision_mode", False), + inplace=method_flags.get("inplace", False), + test_trace=method_flags.get("test_trace", False), + generate_frontend_arrays=method_flags.get( + "generate_frontend_arrays", False + ), + ) + + flags_2 = pf.FrontendInitTestFlags( + num_positional_args=init_flags.get("num_positional_args", 0), + as_variable=init_flags.get("as_variable", [False]), + native_arrays=init_flags.get("native_arrays", [False]), + ) + + given_kwargs["method_flags"] = flags_1 + given_kwargs["init_flags"] = flags_2 + + def test_wrapper(test_fn): + + hypothesis_test_fn = example(**given_kwargs)(test_fn) + + @functools.wraps(hypothesis_test_fn) + def wrapped_test(*args, **kwargs): + try: + hypothesis_test_fn(*args, **kwargs) + except Exception as e: + # A string matching is used instead of actual exception due to + # exception object in with_backend is different from global Ivy + if e.__class__.__qualname__ == "IvyNotImplementedException": + pytest.skip("Function not implemented in backend.") + else: + raise e + + return wrapped_test + + return test_wrapper diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_array.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_array.py index 8fa019823c2c0..546387bf6b111 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_array.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_array.py @@ -208,15 +208,13 @@ def dtype_x_axis(draw): @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__add__", - dtype_x=helpers.dtype_and_values( + method_name="__abs__", + dtype_and_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, - num_arrays=2, ), ) -def test_jax___add__( - dtype_x, +def test_jax___abs__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -224,7 +222,7 @@ def test_jax___add__( backend_fw, on_device, ): - input_dtype, x = dtype_x + input_dtype, x = dtype_and_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -232,7 +230,7 @@ def test_jax___add__( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -244,14 +242,14 @@ def test_jax___add__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__div__", + method_name="__add__", dtype_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("numeric"), shared_dtype=True, num_arrays=2, ), ) -def test_jax___div__( +def test_jax___add__( dtype_x, frontend, frontend_method_data, @@ -261,7 +259,6 @@ def test_jax___div__( on_device, ): input_dtype, x = dtype_x - assume(not np.any(np.isclose(x[1], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -278,17 +275,18 @@ def test_jax___div__( ) -# __getitem__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__getitem__", - dtype_x_index=helpers.dtype_array_query( - available_dtypes=helpers.get_dtypes("valid"), - ).filter(lambda x: not (isinstance(x[-1], np.ndarray) and x[-1].dtype == np.bool_)), + method_name="__and__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), + num_arrays=2, + shared_dtype=True, + ), ) -def test_jax___getitem__( - dtype_x_index, +def test_jax___and__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -296,13 +294,15 @@ def test_jax___getitem__( backend_fw, on_device, ): - input_dtype, x, index = dtype_x_index + input_dtype, x = dtype_and_x helpers.test_frontend_method( - init_input_dtypes=[input_dtype[0]], + init_input_dtypes=input_dtype, backend_to_test=backend_fw, - init_all_as_kwargs_np={"object": x}, - method_input_dtypes=[*input_dtype[1:]], - method_all_as_kwargs_np={"idx": index}, + init_all_as_kwargs_np={ + "object": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -314,13 +314,15 @@ def test_jax___getitem__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__invert__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), + method_name="__div__", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + shared_dtype=True, + num_arrays=2, ), ) -def test_jax___invert__( - dtype_and_x, +def test_jax___div__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -328,7 +330,8 @@ def test_jax___invert__( backend_fw, on_device, ): - input_dtype, x = dtype_and_x + input_dtype, x = dtype_x + assume(not np.any(np.isclose(x[1], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -336,7 +339,7 @@ def test_jax___invert__( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={}, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -348,11 +351,14 @@ def test_jax___invert__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__lshift__", - dtype_x_shift=_get_dtype_x_and_int_shift(dtype="signed_integer"), + method_name="__eq__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + num_arrays=2, + ), ) -def test_jax___lshift__( - dtype_x_shift, +def test_jax___eq__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -360,15 +366,18 @@ def test_jax___lshift__( backend_fw, on_device, ): - input_dtype, x, shift = dtype_x_shift + input_dtype, x = dtype_and_x + assume("bfloat16" not in input_dtype) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "object": x, + "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": shift}, + method_all_as_kwargs_np={ + "other": x[1], + }, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -380,11 +389,14 @@ def test_jax___lshift__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__matmul__", - dtype_x=_get_dtype_input_and_vectors(), + method_name="__ge__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float_and_integer"), + num_arrays=2, + ), ) -def test_jax___matmul__( - dtype_x, +def test_jax___ge__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -392,7 +404,8 @@ def test_jax___matmul__( backend_fw, on_device, ): - input_dtype, x = dtype_x + input_dtype, x = dtype_and_x + assume("bfloat16" not in input_dtype) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -400,7 +413,9 @@ def test_jax___matmul__( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={ + "other": x[1], + }, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -409,18 +424,17 @@ def test_jax___matmul__( ) +# __getitem__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__mod__", - dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, - num_arrays=2, - ), + method_name="__getitem__", + dtype_x_index=helpers.dtype_array_query( + available_dtypes=helpers.get_dtypes("valid"), + ).filter(lambda x: not (isinstance(x[-1], np.ndarray) and x[-1].dtype == np.bool_)), ) -def test_jax___mod__( - dtype_x, +def test_jax___getitem__( + dtype_x_index, frontend, frontend_method_data, init_flags, @@ -428,16 +442,13 @@ def test_jax___mod__( backend_fw, on_device, ): - input_dtype, x = dtype_x - assume(not np.any(np.isclose(x[1], 0))) + input_dtype, x, index = dtype_x_index helpers.test_frontend_method( - init_input_dtypes=input_dtype, + init_input_dtypes=[input_dtype[0]], backend_to_test=backend_fw, - init_all_as_kwargs_np={ - "object": x[0], - }, - method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + init_all_as_kwargs_np={"object": x}, + method_input_dtypes=[*input_dtype[1:]], + method_all_as_kwargs_np={"idx": index}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -449,15 +460,14 @@ def test_jax___mod__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__mul__", - dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, + method_name="__gt__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float_and_integer"), num_arrays=2, ), ) -def test_jax___mul__( - dtype_x, +def test_jax___gt__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -465,7 +475,8 @@ def test_jax___mul__( backend_fw, on_device, ): - input_dtype, x = dtype_x + input_dtype, x = dtype_and_x + assume("bfloat16" not in input_dtype) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -473,7 +484,9 @@ def test_jax___mul__( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={ + "other": x[1], + }, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -485,15 +498,13 @@ def test_jax___mul__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__radd__", - dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, - num_arrays=2, + method_name="__invert__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), ), ) -def test_jax___radd__( - dtype_x, +def test_jax___invert__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -501,7 +512,7 @@ def test_jax___radd__( backend_fw, on_device, ): - input_dtype, x = dtype_x + input_dtype, x = dtype_and_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -509,7 +520,7 @@ def test_jax___radd__( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -521,15 +532,14 @@ def test_jax___radd__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rdiv__", - dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, + method_name="__le__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float_and_integer"), num_arrays=2, ), ) -def test_jax___rdiv__( - dtype_x, +def test_jax___le__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -537,8 +547,8 @@ def test_jax___rdiv__( backend_fw, on_device, ): - input_dtype, x = dtype_x - assume(not np.any(np.isclose(x[0], 0))) + input_dtype, x = dtype_and_x + assume("bfloat16" not in input_dtype) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -546,7 +556,9 @@ def test_jax___rdiv__( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={ + "other": x[1], + }, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -558,10 +570,10 @@ def test_jax___rdiv__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rlshift__", + method_name="__lshift__", dtype_x_shift=_get_dtype_x_and_int_shift(dtype="signed_integer"), ) -def test_jax___rlshift__( +def test_jax___lshift__( dtype_x_shift, frontend, frontend_method_data, @@ -575,10 +587,10 @@ def test_jax___rlshift__( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "object": shift, + "object": x, }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x}, + method_all_as_kwargs_np={"other": shift}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -590,11 +602,15 @@ def test_jax___rlshift__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rmatmul__", - dtype_x=_get_dtype_input_and_vectors(), + method_name="__lt__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float_and_integer"), + num_arrays=2, + shared_dtype=True, + ), ) -def test_jax___rmatmul__( - dtype_x, +def test_jax___lt__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -602,7 +618,7 @@ def test_jax___rmatmul__( backend_fw, on_device, ): - input_dtype, x = dtype_x + input_dtype, x = dtype_and_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -610,7 +626,9 @@ def test_jax___rmatmul__( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={ + "other": x[1], + }, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -622,14 +640,10 @@ def test_jax___rmatmul__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rmod__", - dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, - num_arrays=2, - ), + method_name="__matmul__", + dtype_x=_get_dtype_input_and_vectors(), ) -def test_jax___rmod__( +def test_jax___matmul__( dtype_x, frontend, frontend_method_data, @@ -639,7 +653,6 @@ def test_jax___rmod__( on_device, ): input_dtype, x = dtype_x - assume(not np.any(np.isclose(x[0], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -659,14 +672,14 @@ def test_jax___rmod__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rmul__", + method_name="__mod__", dtype_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("numeric"), shared_dtype=True, num_arrays=2, ), ) -def test_jax___rmul__( +def test_jax___mod__( dtype_x, frontend, frontend_method_data, @@ -676,6 +689,7 @@ def test_jax___rmul__( on_device, ): input_dtype, x = dtype_x + assume(not np.any(np.isclose(x[1], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -695,11 +709,15 @@ def test_jax___rmul__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rrshift__", - dtype_x_shift=_get_dtype_x_and_int_shift(dtype="signed_integer"), + method_name="__mul__", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + shared_dtype=True, + num_arrays=2, + ), ) -def test_jax___rrshift__( - dtype_x_shift, +def test_jax___mul__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -707,15 +725,15 @@ def test_jax___rrshift__( backend_fw, on_device, ): - input_dtype, x, shift = dtype_x_shift + input_dtype, x = dtype_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "object": shift, + "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x}, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -727,11 +745,14 @@ def test_jax___rrshift__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rshift__", - dtype_x_shift=_get_dtype_x_and_int_shift(dtype="signed_integer"), + method_name="__ne__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + num_arrays=2, + ), ) -def test_jax___rshift__( - dtype_x_shift, +def test_jax___ne__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -739,15 +760,18 @@ def test_jax___rshift__( backend_fw, on_device, ): - input_dtype, x, shift = dtype_x_shift + input_dtype, x = dtype_and_x + assume("bfloat16" not in input_dtype) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "object": x, + "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": shift}, + method_all_as_kwargs_np={ + "other": x[1], + }, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -759,15 +783,13 @@ def test_jax___rshift__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rsub__", - dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, - num_arrays=2, + method_name="__neg__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("signed_integer"), ), ) -def test_jax___rsub__( - dtype_x, +def test_jax___neg__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -775,7 +797,7 @@ def test_jax___rsub__( backend_fw, on_device, ): - input_dtype, x = dtype_x + input_dtype, x = dtype_and_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -783,7 +805,7 @@ def test_jax___rsub__( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -795,15 +817,15 @@ def test_jax___rsub__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rtruediv__", - dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, + method_name="__or__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), num_arrays=2, + shared_dtype=True, ), ) -def test_jax___rtruediv__( - dtype_x, +def test_jax___or__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -811,8 +833,7 @@ def test_jax___rtruediv__( backend_fw, on_device, ): - input_dtype, x = dtype_x - assume(not np.any(np.isclose(x[0], 0))) + input_dtype, x = dtype_and_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -832,15 +853,13 @@ def test_jax___rtruediv__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__sub__", - dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, - num_arrays=2, + method_name="__pos__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), ), ) -def test_jax___sub__( - dtype_x, +def test_jax___pos__( + dtype_and_x, frontend, frontend_method_data, init_flags, @@ -848,38 +867,35 @@ def test_jax___sub__( backend_fw, on_device, ): - input_dtype, x = dtype_x + input_dtype, x = dtype_and_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, + on_device=on_device, init_all_as_kwargs_np={ "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, - on_device=on_device, ) @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__truediv__", - dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - shared_dtype=True, + method_name="__pow__", + dtype_x_pow=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), num_arrays=2, - large_abs_safety_factor=2, - small_abs_safety_factor=2, - safety_factor_scale="log", + shared_dtype=True, ), ) -def test_jax___truediv__( - dtype_x, +def test_jax___pow__( + dtype_x_pow, frontend, frontend_method_data, init_flags, @@ -887,8 +903,7 @@ def test_jax___truediv__( backend_fw, on_device, ): - input_dtype, x = dtype_x - assume(not np.any(np.isclose(x[1], 0))) + input_dtype, x = dtype_x_pow helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -896,7 +911,9 @@ def test_jax___truediv__( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={ + "other": x[1], + }, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -908,13 +925,15 @@ def test_jax___truediv__( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__abs__", - dtype_and_x=helpers.dtype_and_values( + method_name="__radd__", + dtype_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("numeric"), + shared_dtype=True, + num_arrays=2, ), ) -def test_jax__abs_( - dtype_and_x, +def test_jax___radd__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -922,7 +941,7 @@ def test_jax__abs_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x + input_dtype, x = dtype_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -930,7 +949,7 @@ def test_jax__abs_( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={}, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -942,14 +961,14 @@ def test_jax__abs_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__and__", + method_name="__rand__", dtype_and_x=helpers.dtype_and_values( available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), num_arrays=2, shared_dtype=True, ), ) -def test_jax__and_( +def test_jax___rand__( dtype_and_x, frontend, frontend_method_data, @@ -978,14 +997,15 @@ def test_jax__and_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__eq__", - dtype_and_x=helpers.dtype_and_values( + method_name="__rdiv__", + dtype_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("numeric"), + shared_dtype=True, num_arrays=2, ), ) -def test_jax__eq_( - dtype_and_x, +def test_jax___rdiv__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -993,8 +1013,8 @@ def test_jax__eq_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x - assume("bfloat16" not in input_dtype) + input_dtype, x = dtype_x + assume(not np.any(np.isclose(x[0], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -1002,9 +1022,7 @@ def test_jax__eq_( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "other": x[1], - }, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1016,14 +1034,11 @@ def test_jax__eq_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__ge__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float_and_integer"), - num_arrays=2, - ), + method_name="__rlshift__", + dtype_x_shift=_get_dtype_x_and_int_shift(dtype="signed_integer"), ) -def test_jax__ge_( - dtype_and_x, +def test_jax___rlshift__( + dtype_x_shift, frontend, frontend_method_data, init_flags, @@ -1031,18 +1046,15 @@ def test_jax__ge_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x - assume("bfloat16" not in input_dtype) + input_dtype, x, shift = dtype_x_shift helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "object": x[0], + "object": shift, }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "other": x[1], - }, + method_all_as_kwargs_np={"other": x}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1054,14 +1066,11 @@ def test_jax__ge_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__gt__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float_and_integer"), - num_arrays=2, - ), + method_name="__rmatmul__", + dtype_x=_get_dtype_input_and_vectors(), ) -def test_jax__gt_( - dtype_and_x, +def test_jax___rmatmul__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -1069,8 +1078,7 @@ def test_jax__gt_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x - assume("bfloat16" not in input_dtype) + input_dtype, x = dtype_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -1078,9 +1086,7 @@ def test_jax__gt_( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "other": x[1], - }, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1092,14 +1098,15 @@ def test_jax__gt_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__le__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float_and_integer"), + method_name="__rmod__", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + shared_dtype=True, num_arrays=2, ), ) -def test_jax__le_( - dtype_and_x, +def test_jax___rmod__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -1107,8 +1114,8 @@ def test_jax__le_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x - assume("bfloat16" not in input_dtype) + input_dtype, x = dtype_x + assume(not np.any(np.isclose(x[0], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -1116,9 +1123,7 @@ def test_jax__le_( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "other": x[1], - }, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1130,15 +1135,15 @@ def test_jax__le_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__lt__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float_and_integer"), - num_arrays=2, + method_name="__rmul__", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), shared_dtype=True, + num_arrays=2, ), ) -def test_jax__lt_( - dtype_and_x, +def test_jax___rmul__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -1146,7 +1151,7 @@ def test_jax__lt_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x + input_dtype, x = dtype_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -1154,9 +1159,7 @@ def test_jax__lt_( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "other": x[1], - }, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1168,13 +1171,14 @@ def test_jax__lt_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__ne__", + method_name="__ror__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), num_arrays=2, + shared_dtype=True, ), ) -def test_jax__ne_( +def test_jax___ror__( dtype_and_x, frontend, frontend_method_data, @@ -1184,7 +1188,6 @@ def test_jax__ne_( on_device, ): input_dtype, x = dtype_and_x - assume("bfloat16" not in input_dtype) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -1192,9 +1195,7 @@ def test_jax__ne_( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "other": x[1], - }, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1206,13 +1207,11 @@ def test_jax__ne_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__neg__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("signed_integer"), - ), + method_name="__rpow__", + dtype_x_pow=_get_dtype_x_and_int(), ) -def test_jax__neg_( - dtype_and_x, +def test_jax___rpow__( + dtype_x_pow, frontend, frontend_method_data, init_flags, @@ -1220,15 +1219,17 @@ def test_jax__neg_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x + input_dtype, x, pow = dtype_x_pow helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "object": x[0], + "object": pow[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={}, + method_all_as_kwargs_np={ + "other": x[0], + }, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1240,15 +1241,11 @@ def test_jax__neg_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__or__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), - num_arrays=2, - shared_dtype=True, - ), + method_name="__rrshift__", + dtype_x_shift=_get_dtype_x_and_int_shift(dtype="signed_integer"), ) -def test_jax__or_( - dtype_and_x, +def test_jax___rrshift__( + dtype_x_shift, frontend, frontend_method_data, init_flags, @@ -1256,15 +1253,15 @@ def test_jax__or_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x + input_dtype, x, shift = dtype_x_shift helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "object": x[0], + "object": shift, }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={"other": x[1]}, + method_all_as_kwargs_np={"other": x}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1276,13 +1273,11 @@ def test_jax__or_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__pos__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("valid"), - ), + method_name="__rshift__", + dtype_x_shift=_get_dtype_x_and_int_shift(dtype="signed_integer"), ) -def test_jax__pos_( - dtype_and_x, +def test_jax___rshift__( + dtype_x_shift, frontend, frontend_method_data, init_flags, @@ -1290,35 +1285,35 @@ def test_jax__pos_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x + input_dtype, x, shift = dtype_x_shift helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, - on_device=on_device, init_all_as_kwargs_np={ - "object": x[0], + "object": x, }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={}, + method_all_as_kwargs_np={"other": shift}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, + on_device=on_device, ) @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__pow__", - dtype_x_pow=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), - num_arrays=2, + method_name="__rsub__", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), shared_dtype=True, + num_arrays=2, ), ) -def test_jax__pow_( - dtype_x_pow, +def test_jax___rsub__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -1326,7 +1321,7 @@ def test_jax__pow_( backend_fw, on_device, ): - input_dtype, x = dtype_x_pow + input_dtype, x = dtype_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -1334,9 +1329,7 @@ def test_jax__pow_( "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "other": x[1], - }, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1348,15 +1341,15 @@ def test_jax__pow_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rand__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), - num_arrays=2, + method_name="__rtruediv__", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), shared_dtype=True, + num_arrays=2, ), ) -def test_jax__rand_( - dtype_and_x, +def test_jax___rtruediv__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -1364,7 +1357,8 @@ def test_jax__rand_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x + input_dtype, x = dtype_x + assume(not np.any(np.isclose(x[0], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -1384,14 +1378,14 @@ def test_jax__rand_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__ror__", + method_name="__rxor__", dtype_and_x=helpers.dtype_and_values( available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), num_arrays=2, shared_dtype=True, ), ) -def test_jax__ror_( +def test_jax___rxor__( dtype_and_x, frontend, frontend_method_data, @@ -1420,11 +1414,15 @@ def test_jax__ror_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rpow__", - dtype_x_pow=_get_dtype_x_and_int(), + method_name="__sub__", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + shared_dtype=True, + num_arrays=2, + ), ) -def test_jax__rpow_( - dtype_x_pow, +def test_jax___sub__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -1432,17 +1430,15 @@ def test_jax__rpow_( backend_fw, on_device, ): - input_dtype, x, pow = dtype_x_pow + input_dtype, x = dtype_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "object": pow[0], + "object": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "other": x[0], - }, + method_all_as_kwargs_np={"other": x[1]}, frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, @@ -1454,15 +1450,18 @@ def test_jax__rpow_( @handle_frontend_method( class_tree=CLASS_TREE, init_tree="jax.numpy.array", - method_name="__rxor__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), - num_arrays=2, + method_name="__truediv__", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), shared_dtype=True, + num_arrays=2, + large_abs_safety_factor=2, + small_abs_safety_factor=2, + safety_factor_scale="log", ), ) -def test_jax__rxor_( - dtype_and_x, +def test_jax___truediv__( + dtype_x, frontend, frontend_method_data, init_flags, @@ -1470,7 +1469,8 @@ def test_jax__rxor_( backend_fw, on_device, ): - input_dtype, x = dtype_and_x + input_dtype, x = dtype_x + assume(not np.any(np.isclose(x[1], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -1497,7 +1497,7 @@ def test_jax__rxor_( shared_dtype=True, ), ) -def test_jax__xor_( +def test_jax___xor__( dtype_and_x, frontend, frontend_method_data, diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_indexing.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_indexing.py index 4d76bfcc9a139..5065fbd54c3a5 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_indexing.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_indexing.py @@ -53,18 +53,6 @@ def _get_dtype_square_x(draw): return dtype_x -# diagonal -@st.composite -def dims_and_offset(draw, shape): - shape_actual = draw(shape) - dim1 = draw(helpers.get_axis(shape=shape, force_int=True)) - dim2 = draw(helpers.get_axis(shape=shape, force_int=True)) - offset = draw( - st.integers(min_value=-shape_actual[dim1], max_value=shape_actual[dim1]) - ) - return dim1, dim2, offset - - # unravel_index @st.composite def max_value_as_shape_prod(draw): @@ -217,7 +205,7 @@ def test_jax_diag_indices_from( available_dtypes=helpers.get_dtypes("float"), shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape"), ), - dims_and_offset=dims_and_offset( + dims_and_offset=helpers.dims_and_offset( shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape") ), ) diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_mathematical_functions.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_mathematical_functions.py index 7ff6a267a5b4b..402c3a7f6a3be 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_mathematical_functions.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_mathematical_functions.py @@ -1103,9 +1103,9 @@ def test_jax_einsum_path( **kw, optimize=optimize, ) - len(ret[0]) == len(ret_gt[0]) - all(x == y for x, y in zip(ret[0], ret_gt[0])) - ret[1] == str(ret_gt[1]) + assert len(ret[0]) == len(ret_gt[0]) + assert all(x == y for x, y in zip(ret[0], ret_gt[0])) + assert ret[1] == str(ret_gt[1]) # exp diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_statistics/test_correlating.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_statistics/test_correlating.py index ee73f44e8a3d6..055ec7ace5b72 100644 --- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_statistics/test_correlating.py +++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_statistics/test_correlating.py @@ -83,7 +83,8 @@ def test_numpy_correlate( test_flags=test_flags, fn_tree=fn_tree, on_device=on_device, - rtol=1e-2, + rtol=1e-3, + atol=1e-3, a=xs[0], v=xs[1], mode=mode, diff --git a/ivy_tests/test_ivy/test_frontends/test_paddle/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_paddle/test_linalg.py index 26547bb45a8f6..a5aa23037461d 100644 --- a/ivy_tests/test_ivy/test_frontends/test_paddle/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_paddle/test_linalg.py @@ -171,17 +171,6 @@ def _transpose_helper(draw): return dtype, x, perm -@st.composite -def dims_and_offset(draw, shape): - shape_actual = draw(shape) - dim1 = draw(helpers.get_axis(shape=shape, force_int=True)) - dim2 = draw(helpers.get_axis(shape=shape, force_int=True)) - offset = draw( - st.integers(min_value=-shape_actual[dim1], max_value=shape_actual[dim1]) - ) - return dim1, dim2, offset - - # Helpers # # ------ # @@ -569,7 +558,7 @@ def test_paddle_eig( ret = [ivy.to_numpy(x).astype("float64") for x in ret] frontend_ret = [np.asarray(x, dtype=np.float64) for x in frontend_ret] - l, v = ret + l, v = ret # noqa: E741 front_l, front_v = frontend_ret assert_all_close( @@ -619,7 +608,7 @@ def test_paddle_eigh( ret = [ivy.to_numpy(x).astype("float64") for x in ret] frontend_ret = [np.asarray(x, dtype=np.float64) for x in frontend_ret] - l, v = ret + l, v = ret # noqa: E741 front_l, front_v = frontend_ret assert_all_close( @@ -706,7 +695,7 @@ def test_paddle_eigvalsh( available_dtypes=helpers.get_dtypes("valid"), shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape"), ), - axis_and_offset=dims_and_offset( + axis_and_offset=helpers.dims_and_offset( shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape") ), ) diff --git a/ivy_tests/test_ivy/test_frontends/test_paddle/test_manipulation.py b/ivy_tests/test_ivy/test_frontends/test_paddle/test_manipulation.py index 413f799ef4d9d..c3515fd426518 100644 --- a/ivy_tests/test_ivy/test_frontends/test_paddle/test_manipulation.py +++ b/ivy_tests/test_ivy/test_frontends/test_paddle/test_manipulation.py @@ -48,6 +48,62 @@ def _arrays_axis_n_dtypes(draw): return xs, input_dtypes, axis +@st.composite +def _arrays_dim_idx_n_dtypes(draw): + num_dims = draw(st.shared(helpers.ints(min_value=1, max_value=4), key="num_dims")) + num_arrays = 2 + common_shape = draw( + helpers.lists( + x=helpers.ints(min_value=2, max_value=3), + min_size=num_dims - 1, + max_size=num_dims - 1, + ) + ) + _dim = draw(helpers.ints(min_value=0, max_value=num_dims - 1)) + unique_dims = draw( + helpers.lists( + x=helpers.ints(min_value=2, max_value=3), + min_size=num_arrays, + max_size=num_arrays, + ) + ) + + min_dim = min(unique_dims) + max_dim = max(unique_dims) + _idx = draw( + helpers.array_values( + shape=min_dim, + dtype="int64", + min_value=0, + max_value=max_dim, + exclude_min=False, + ) + ) + + xs = [] + # available_input_types = draw(helpers.get_dtypes("integer")) + available_input_types = ["int32", "int64", "float16", "float32", "float64"] + input_dtypes = draw( + helpers.array_dtypes( + available_dtypes=available_input_types, + num_arrays=num_arrays, + shared_dtype=True, + ) + ) + for ud, dt in zip(unique_dims, input_dtypes): + x = draw( + helpers.array_values( + shape=common_shape[:_dim] + [ud] + common_shape[_dim:], + dtype=dt, + large_abs_safety_factor=2.5, + small_abs_safety_factor=2.5, + safety_factor_scale="log", + ) + ) + xs.append(x) + return xs, input_dtypes, _dim, _idx + + # concat @st.composite def _arrays_idx_n_dtypes(draw): @@ -471,6 +527,38 @@ def test_paddle_gather_nd( ) +@handle_frontend_test( + fn_tree="paddle.index_add", + xs_dtypes_dim_idx=_arrays_dim_idx_n_dtypes(), +) +def test_paddle_index_add( + *, + xs_dtypes_dim_idx, + on_device, + fn_tree, + frontend, + test_flags, + backend_fw, +): + xs, input_dtypes, axis, indices = xs_dtypes_dim_idx + if xs[0].shape[axis] < xs[1].shape[axis]: + source, input = xs + else: + input, source = xs + helpers.test_frontend_function( + input_dtypes=input_dtypes, + backend_to_test=backend_fw, + test_flags=test_flags, + fn_tree=fn_tree, + frontend=frontend, + on_device=on_device, + x=input, + index=indices, + axis=axis, + value=source, + ) + + # repeat_interleave @handle_frontend_test( fn_tree="paddle.repeat_interleave", diff --git a/ivy_tests/test_ivy/test_frontends/test_paddle/test_math.py b/ivy_tests/test_ivy/test_frontends/test_paddle/test_math.py index 3aa1a088b7e79..a7e20943574a5 100644 --- a/ivy_tests/test_ivy/test_frontends/test_paddle/test_math.py +++ b/ivy_tests/test_ivy/test_frontends/test_paddle/test_math.py @@ -1137,7 +1137,7 @@ def test_paddle_floor_mod( @handle_frontend_test( fn_tree="paddle.fmax", dtypes_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), num_arrays=2, shared_dtype=True + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True ), ) def test_paddle_fmax( @@ -1165,7 +1165,7 @@ def test_paddle_fmax( @handle_frontend_test( fn_tree="paddle.fmin", dtypes_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), num_arrays=2, shared_dtype=True + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True ), ) def test_paddle_fmin( @@ -1720,6 +1720,39 @@ def test_paddle_logit( ) +# logsumexp +@handle_frontend_test( + fn_tree="paddle.tensor.math.logsumexp", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + max_num_dims=4, + num_arrays=2, + allow_inf=False, + shared_dtype=True, + ), +) +def test_paddle_logsumexp( + *, + dtype_and_x, + on_device, + fn_tree, + backend_fw, + frontend, + test_flags, +): + input_dtypes, xs = dtype_and_x + helpers.test_frontend_function( + input_dtypes=input_dtypes, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + x=xs[0], + axis=None, + ) + + # max @handle_frontend_test( fn_tree="paddle.max", diff --git a/ivy_tests/test_ivy/test_frontends/test_paddle/test_stat.py b/ivy_tests/test_ivy/test_frontends/test_paddle/test_stat.py index f8ccfc5b7ac2c..9d37a3532b9de 100644 --- a/ivy_tests/test_ivy/test_frontends/test_paddle/test_stat.py +++ b/ivy_tests/test_ivy/test_frontends/test_paddle/test_stat.py @@ -26,7 +26,7 @@ def test_paddle_mean( backend_fw, test_flags, ): - input_dtype, x, axis = dtype_and_x + input_dtype, x, axis = dtype_and_x[:3] test_flags.num_positional_args = len(dtype_and_x) - 2 helpers.test_frontend_function( input_dtypes=input_dtype, @@ -35,6 +35,8 @@ def test_paddle_mean( test_flags=test_flags, fn_tree=fn_tree, on_device=on_device, + rtol=1e-2, + atol=1e-2, input=x[0], axis=axis, keepdim=keepdim, diff --git a/ivy_tests/test_ivy/test_frontends/test_paddle/test_tensor/test_manipulation.py b/ivy_tests/test_ivy/test_frontends/test_paddle/test_tensor/test_manipulation.py index c1265c500864e..d2f8f5bde0fea 100644 --- a/ivy_tests/test_ivy/test_frontends/test_paddle/test_tensor/test_manipulation.py +++ b/ivy_tests/test_ivy/test_frontends/test_paddle/test_tensor/test_manipulation.py @@ -13,6 +13,63 @@ # --------------- # +@st.composite +def _arrays_dim_idx_n_dtypes(draw): + num_dims = draw(st.shared(helpers.ints(min_value=1, max_value=4), key="num_dims")) + num_arrays = 2 + common_shape = draw( + helpers.lists( + x=helpers.ints(min_value=2, max_value=3), + min_size=num_dims - 1, + max_size=num_dims - 1, + ) + ) + _dim = draw(helpers.ints(min_value=0, max_value=num_dims - 1)) + unique_dims = draw( + helpers.lists( + x=helpers.ints(min_value=2, max_value=3), + min_size=num_arrays, + max_size=num_arrays, + ) + ) + + min_dim = min(unique_dims) + max_dim = max(unique_dims) + _idx = draw( + helpers.array_values( + shape=min_dim, + dtype="int64", + min_value=0, + max_value=max_dim, + exclude_min=False, + ) + ) + + xs = [] + # available_input_types = draw(helpers.get_dtypes("integer")) + # available_input_types = ["int32", "int64", "float16", "float32", "float64"] + available_input_types = ["int32", "int64"] + input_dtypes = draw( + helpers.array_dtypes( + available_dtypes=available_input_types, + num_arrays=num_arrays, + shared_dtype=True, + ) + ) + for ud, dt in zip(unique_dims, input_dtypes): + x = draw( + helpers.array_values( + shape=common_shape[:_dim] + [ud] + common_shape[_dim:], + dtype=dt, + large_abs_safety_factor=2.5, + small_abs_safety_factor=2.5, + safety_factor_scale="log", + ) + ) + xs.append(x) + return xs, input_dtypes, _dim, _idx + + @st.composite def dtypes_x_reshape_(draw): shape = draw(helpers.get_shape(min_num_dims=1)) @@ -25,6 +82,42 @@ def dtypes_x_reshape_(draw): return dtypes, x, shape +# --- Main --- # +# ------------ # + + +@handle_frontend_test( + fn_tree="paddle.tensor.manipulation.index_add_", + xs_dtypes_dim_idx=_arrays_dim_idx_n_dtypes(), +) +def test_paddle_index_add_( + *, + xs_dtypes_dim_idx, + on_device, + fn_tree, + frontend, + test_flags, + backend_fw, +): + xs, input_dtypes, axis, indices = xs_dtypes_dim_idx + if xs[0].shape[axis] < xs[1].shape[axis]: + source, input = xs + else: + input, source = xs + helpers.test_frontend_function( + input_dtypes=input_dtypes, + backend_to_test=backend_fw, + test_flags=test_flags, + fn_tree=fn_tree, + frontend=frontend, + on_device=on_device, + x=input, + index=indices, + axis=axis, + value=source, + ) + + # reshape_ @handle_frontend_test( fn_tree="paddle.tensor.manipulation.reshape_", diff --git a/ivy_tests/test_ivy/test_frontends/test_paddle/test_tensor/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_paddle/test_tensor/test_tensor.py index 87a9e59d7889b..fe5e3dda8add5 100644 --- a/ivy_tests/test_ivy/test_frontends/test_paddle/test_tensor/test_tensor.py +++ b/ivy_tests/test_ivy/test_frontends/test_paddle/test_tensor/test_tensor.py @@ -160,6 +160,39 @@ def _get_clip_inputs_(draw): return x_dtype, x, min, max +@st.composite +def _get_dtype_and_3dbatch_matrices_for_matmul(draw): + dim_size1 = draw(helpers.ints(min_value=2, max_value=5)) + dim_size2 = draw(helpers.ints(min_value=2, max_value=5)) + shared_size = draw(helpers.ints(min_value=2, max_value=5)) + dtype = draw(helpers.get_dtypes("float", full=True)) + dtype = [ + draw(st.sampled_from(tuple(set(dtype).difference({"bfloat16", "float16"})))) + ] + batch_size = draw(helpers.ints(min_value=2, max_value=4)) + transpose_x = draw(st.booleans()) + transpose_y = draw(st.booleans()) + + mat1_shape = ( + (batch_size, dim_size1, shared_size) + if not transpose_x + else (batch_size, shared_size, dim_size1) + ) + mat2_shape = ( + (batch_size, shared_size, dim_size2) + if not transpose_y + else (batch_size, dim_size2, shared_size) + ) + + mat1 = draw( + helpers.array_values(dtype=dtype[0], shape=mat1_shape, min_value=2, max_value=5) + ) + mat2 = draw( + helpers.array_values(dtype=dtype[0], shape=mat2_shape, min_value=2, max_value=5) + ) + return dtype, mat1, mat2, transpose_x, transpose_y + + # cond @st.composite def _get_dtype_and_matrix_non_singular(draw, dtypes): @@ -186,6 +219,16 @@ def _get_dtype_and_matrix_non_singular(draw, dtypes): return matrix[0], matrix[1] +@st.composite +def _get_dtype_and_multiplicative_matrices(draw): + return draw( + st.one_of( + _get_dtype_input_and_matrices_for_matmul(), + _get_dtype_and_3dbatch_matrices_for_matmul(), + ) + ) + + @st.composite def _get_dtype_and_square_matrix(draw): dim_size = draw(helpers.ints(min_value=2, max_value=5)) @@ -245,6 +288,118 @@ def _get_dtype_and_values_for_lerp(draw): return input_dtype, x[0], x[1], weight +@st.composite +def _get_dtype_input_and_matrices_for_matmul(draw): + dim_size1 = draw(helpers.ints(min_value=2, max_value=5)) + dim_size2 = draw(helpers.ints(min_value=2, max_value=5)) + shared_size = draw(helpers.ints(min_value=2, max_value=5)) + dtype = draw(helpers.get_dtypes("float", full=True)) + dtype = [ + draw(st.sampled_from(tuple(set(dtype).difference({"bfloat16", "float16"})))) + ] + transpose_x = draw(st.booleans()) + transpose_y = draw(st.booleans()) + + mat1_shape = (shared_size, dim_size1) if transpose_x else (dim_size1, shared_size) + mat2_shape = (dim_size2, shared_size) if transpose_y else (shared_size, dim_size2) + + mat1 = draw( + helpers.array_values(dtype=dtype[0], shape=mat1_shape, min_value=2, max_value=5) + ) + mat2 = draw( + helpers.array_values(dtype=dtype[0], shape=mat2_shape, min_value=2, max_value=5) + ) + return dtype, mat1, mat2, transpose_x, transpose_y + + +@st.composite +def _get_dtype_value1_value2_cov( + draw, + available_dtypes, + min_num_dims, + max_num_dims, + min_dim_size, + max_dim_size, + abs_smallest_val=None, + min_value=None, + max_value=None, + allow_inf=False, + exclude_min=False, + exclude_max=False, + large_abs_safety_factor=4, + small_abs_safety_factor=4, + safety_factor_scale="log", +): + shape = draw( + helpers.get_shape( + allow_none=False, + min_num_dims=min_num_dims, + max_num_dims=max_num_dims, + min_dim_size=min_dim_size, + max_dim_size=max_dim_size, + ) + ) + + dtype = draw(st.sampled_from(draw(available_dtypes))) + + values = [] + for i in range(1): + values.append( + draw( + helpers.array_values( + dtype=dtype, + shape=shape, + abs_smallest_val=abs_smallest_val, + min_value=min_value, + max_value=max_value, + allow_inf=allow_inf, + exclude_min=exclude_min, + exclude_max=exclude_max, + large_abs_safety_factor=large_abs_safety_factor, + small_abs_safety_factor=small_abs_safety_factor, + safety_factor_scale=safety_factor_scale, + ) + ) + ) + + value = values[0] + + # modifiers: rowVar, bias, ddof + rowVar = draw(st.booleans()) + ddof = draw(st.booleans()) + + numVals = None + if rowVar is False: + numVals = -1 if numVals == 0 else 0 + else: + numVals = 0 if len(shape) == 1 else -1 + + fweights = draw( + helpers.array_values( + dtype="int64", + shape=shape[numVals], + abs_smallest_val=1, + min_value=1, + max_value=10, + allow_inf=False, + ) + ) + + aweights = draw( + helpers.array_values( + dtype="float64", + shape=shape[numVals], + abs_smallest_val=1, + min_value=1, + max_value=10, + allow_inf=False, + small_abs_safety_factor=1, + ) + ) + + return [dtype], value, rowVar, ddof, fweights, aweights + + @st.composite def _reshape_helper(draw): # generate a shape s.t len(shape) > 0 @@ -269,18 +424,6 @@ def _reshape_helper(draw): return dtypes, x, reshape_shape -# diagonal -@st.composite -def dims_and_offset(draw, shape): - shape_actual = draw(shape) - dim1 = draw(helpers.get_axis(shape=shape, force_int=True)) - dim2 = draw(helpers.get_axis(shape=shape, force_int=True)) - offset = draw( - st.integers(min_value=-shape_actual[dim1], max_value=shape_actual[dim1]) - ) - return dim1, dim2, offset - - # expand helper function @st.composite def dtypes_x_shape(draw): @@ -351,53 +494,56 @@ def test_paddle___add__( ) -# __ge__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__ge__", + method_name="__float__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2, shared_dtype=True + available_dtypes=helpers.get_dtypes("numeric"), + max_num_dims=0, ), ) -def test_paddle___ge__( +def test_paddle___float__( dtype_and_x, frontend_method_data, init_flags, method_flags, + backend_fw, frontend, on_device, - backend_fw, ): - input_dtype, x = dtype_and_x + input_dtypes, xs = dtype_and_x + # Numpy doesn't support complex to float conversion + assume(not np.issubdtype(input_dtypes[0], np.complexfloating)) helpers.test_frontend_method( - init_input_dtypes=input_dtype, + init_input_dtypes=input_dtypes, backend_to_test=backend_fw, + method_input_dtypes=input_dtypes, init_all_as_kwargs_np={ - "data": x[0], - }, - method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "y": x[1], + "object": xs[0], }, + method_all_as_kwargs_np={}, + frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, - frontend=frontend, on_device=on_device, ) -# __gt__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__gt__", + method_name="__floordiv__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2, shared_dtype=True + available_dtypes=helpers.get_dtypes("float"), + num_arrays=2, + large_abs_safety_factor=2.5, + small_abs_safety_factor=2.5, + safety_factor_scale="log", ), ) -def test_paddle___gt__( +def test_paddle___floordiv__( dtype_and_x, frontend_method_data, init_flags, @@ -407,6 +553,7 @@ def test_paddle___gt__( backend_fw, ): input_dtype, x = dtype_and_x + assume(not np.any(np.isclose(x[1], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -415,26 +562,27 @@ def test_paddle___gt__( }, method_input_dtypes=input_dtype, method_all_as_kwargs_np={ - "y": x[1], + "other": x[1], }, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, frontend=frontend, on_device=on_device, + atol_=1, ) -# __le__ +# __ge__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__le__", + method_name="__ge__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True + available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2, shared_dtype=True ), ) -def test_paddle___le__( +def test_paddle___ge__( dtype_and_x, frontend_method_data, init_flags, @@ -462,17 +610,18 @@ def test_paddle___le__( ) -# __lt__ +# __getitem__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__lt__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2, shared_dtype=True - ), + method_name="__getitem__", + dtype_x_index=helpers.dtype_array_query( + available_dtypes=helpers.get_dtypes("valid"), + allow_neg_step=False, + ).filter(lambda x: x[0][0] == x[0][-1] and _filter_query(x[-2])), ) -def test_paddle___lt__( - dtype_and_x, +def test_paddle___getitem__( + dtype_x_index, frontend_method_data, init_flags, method_flags, @@ -480,17 +629,13 @@ def test_paddle___lt__( on_device, backend_fw, ): - input_dtype, x = dtype_and_x + input_dtype, x, index = dtype_x_index helpers.test_frontend_method( - init_input_dtypes=input_dtype, + init_input_dtypes=[input_dtype[0]], backend_to_test=backend_fw, - init_all_as_kwargs_np={ - "data": x[0], - }, - method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "y": x[1], - }, + init_all_as_kwargs_np={"data": x}, + method_input_dtypes=[*input_dtype[1:]], + method_all_as_kwargs_np={"item": index}, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, @@ -499,16 +644,16 @@ def test_paddle___lt__( ) -# __mul__ +# __gt__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__mul__", + method_name="__gt__", dtype_and_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2, shared_dtype=True ), ) -def test_paddle___mul__( +def test_paddle___gt__( dtype_and_x, frontend_method_data, init_flags, @@ -536,91 +681,92 @@ def test_paddle___mul__( ) -# __or__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__or__", + method_name="__int__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("integer"), num_arrays=2, shared_dtype=True + available_dtypes=helpers.get_dtypes("integer"), + max_num_dims=0, + min_value=-1e15, + max_value=1e15, ), ) -def test_paddle___or__( +def test_paddle___int__( dtype_and_x, frontend_method_data, init_flags, method_flags, + backend_fw, frontend, on_device, - backend_fw, ): - input_dtype, x = dtype_and_x + input_dtypes, xs = dtype_and_x + # Numpy doesn't support complex to int conversion + assume(not np.issubdtype(input_dtypes[0], np.complexfloating)) helpers.test_frontend_method( - init_input_dtypes=input_dtype, + init_input_dtypes=input_dtypes, backend_to_test=backend_fw, + method_input_dtypes=input_dtypes, init_all_as_kwargs_np={ - "data": x[0], - }, - method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "y": x[1], + "object": xs[0], }, + method_all_as_kwargs_np={}, + frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, - frontend=frontend, on_device=on_device, ) -# __radd__ +# invert @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__radd__", + method_name="__invert__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True + available_dtypes=helpers.get_dtypes("numeric"), + max_num_dims=0, ), ) -def test_paddle___radd__( +def test_paddle___invert__( dtype_and_x, frontend_method_data, init_flags, method_flags, + backend_fw, frontend, on_device, - backend_fw, ): - input_dtype, x = dtype_and_x + input_dtypes, xs = dtype_and_x helpers.test_frontend_method( - init_input_dtypes=input_dtype, + init_input_dtypes=input_dtypes, backend_to_test=backend_fw, + method_input_dtypes=input_dtypes, init_all_as_kwargs_np={ - "data": x[0], - }, - method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "x": x[1], + "object": xs[0], }, + method_all_as_kwargs_np={}, + frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, - frontend=frontend, on_device=on_device, ) -# __setitem__ +# __le__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__setitem__", - dtypes_x_index_val=helpers.dtype_array_query_val( - available_dtypes=helpers.get_dtypes("valid"), - ).filter(lambda x: x[0][0] == x[0][-1] and _filter_query(x[-2])), + method_name="__le__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True + ), ) -def test_paddle___setitem__( - dtypes_x_index_val, +def test_paddle___le__( + dtype_and_x, frontend_method_data, init_flags, method_flags, @@ -628,13 +774,17 @@ def test_paddle___setitem__( on_device, backend_fw, ): - input_dtype, x, index, val = dtypes_x_index_val + input_dtype, x = dtype_and_x helpers.test_frontend_method( - init_input_dtypes=[input_dtype[0]], + init_input_dtypes=input_dtype, backend_to_test=backend_fw, - init_all_as_kwargs_np={"data": x}, - method_input_dtypes=[*input_dtype[1:]], - method_all_as_kwargs_np={"item": index, "value": val}, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "y": x[1], + }, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, @@ -643,53 +793,55 @@ def test_paddle___setitem__( ) -# __sub__ +# __len__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__sub__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True + method_name="__len__", + dtype_and_x=_array_and_shape( + min_num_dims=1, + max_num_dims=5, ), ) -def test_paddle___sub__( +def test_paddle___len__( dtype_and_x, + frontend, frontend_method_data, init_flags, method_flags, - frontend, - on_device, backend_fw, + on_device, ): input_dtype, x = dtype_and_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "data": x[0], + "value": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "y": x[1], - }, + method_all_as_kwargs_np={}, + frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, - frontend=frontend, on_device=on_device, ) +# long @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__float__", + method_name="__long__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("integer"), max_num_dims=0, + min_value=-1e15, + max_value=1e15, ), ) -def test_paddle__float__( +def test_paddle___long__( dtype_and_x, frontend_method_data, init_flags, @@ -699,7 +851,7 @@ def test_paddle__float__( on_device, ): input_dtypes, xs = dtype_and_x - # Numpy doesn't support complex to float conversion + # Numpy doesn't support complex to int conversion assume(not np.issubdtype(input_dtypes[0], np.complexfloating)) helpers.test_frontend_method( init_input_dtypes=input_dtypes, @@ -717,19 +869,16 @@ def test_paddle__float__( ) +# __lt__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__floordiv__", + method_name="__lt__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), - num_arrays=2, - large_abs_safety_factor=2.5, - small_abs_safety_factor=2.5, - safety_factor_scale="log", + available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2, shared_dtype=True ), ) -def test_paddle__floordiv__( +def test_paddle___lt__( dtype_and_x, frontend_method_data, init_flags, @@ -739,7 +888,6 @@ def test_paddle__floordiv__( backend_fw, ): input_dtype, x = dtype_and_x - assume(not np.any(np.isclose(x[1], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -748,29 +896,27 @@ def test_paddle__floordiv__( }, method_input_dtypes=input_dtype, method_all_as_kwargs_np={ - "other": x[1], + "y": x[1], }, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, frontend=frontend, on_device=on_device, - atol_=1, ) -# __getitem__ +# __mul__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__getitem__", - dtype_x_index=helpers.dtype_array_query( - available_dtypes=helpers.get_dtypes("valid"), - allow_neg_step=False, - ).filter(lambda x: x[0][0] == x[0][-1] and _filter_query(x[-2])), + method_name="__mul__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2, shared_dtype=True + ), ) -def test_paddle__getitem__( - dtype_x_index, +def test_paddle___mul__( + dtype_and_x, frontend_method_data, init_flags, method_flags, @@ -778,13 +924,17 @@ def test_paddle__getitem__( on_device, backend_fw, ): - input_dtype, x, index = dtype_x_index + input_dtype, x = dtype_and_x helpers.test_frontend_method( - init_input_dtypes=[input_dtype[0]], + init_input_dtypes=input_dtype, backend_to_test=backend_fw, - init_all_as_kwargs_np={"data": x}, - method_input_dtypes=[*input_dtype[1:]], - method_all_as_kwargs_np={"item": index}, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "y": x[1], + }, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, @@ -793,211 +943,216 @@ def test_paddle__getitem__( ) +# __ne__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__int__", + method_name="__ne__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("integer"), - max_num_dims=0, - min_value=-1e15, - max_value=1e15, + available_dtypes=helpers.get_dtypes("float"), + num_arrays=2, + min_value=-1e04, + max_value=1e04, + allow_inf=False, ), ) -def test_paddle__int__( +def test_paddle___ne__( dtype_and_x, frontend_method_data, init_flags, method_flags, - backend_fw, frontend, on_device, + backend_fw, ): - input_dtypes, xs = dtype_and_x - # Numpy doesn't support complex to int conversion - assume(not np.issubdtype(input_dtypes[0], np.complexfloating)) + input_dtype, x = dtype_and_x helpers.test_frontend_method( - init_input_dtypes=input_dtypes, + init_input_dtypes=input_dtype, backend_to_test=backend_fw, - method_input_dtypes=input_dtypes, init_all_as_kwargs_np={ - "object": xs[0], + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "other": x[1], }, - method_all_as_kwargs_np={}, - frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, + frontend=frontend, on_device=on_device, ) -# invert +# __neg__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__invert__", + method_name="__neg__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - max_num_dims=0, + available_dtypes=helpers.get_dtypes("float"), + min_value=-1e04, + max_value=1e04, + allow_inf=False, ), ) -def test_paddle__invert__( +def test_paddle___neg__( dtype_and_x, frontend_method_data, init_flags, method_flags, - backend_fw, frontend, on_device, + backend_fw, ): - input_dtypes, xs = dtype_and_x + input_dtype, x = dtype_and_x helpers.test_frontend_method( - init_input_dtypes=input_dtypes, + init_input_dtypes=input_dtype, backend_to_test=backend_fw, - method_input_dtypes=input_dtypes, init_all_as_kwargs_np={ - "object": xs[0], + "data": x[0], }, + method_input_dtypes=input_dtype, method_all_as_kwargs_np={}, - frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, + frontend=frontend, on_device=on_device, ) -# __len__ +# __or__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__len__", - dtype_and_x=_array_and_shape( - min_num_dims=1, - max_num_dims=5, + method_name="__or__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("integer"), num_arrays=2, shared_dtype=True ), ) -def test_paddle__len__( +def test_paddle___or__( dtype_and_x, - frontend, frontend_method_data, init_flags, method_flags, - backend_fw, + frontend, on_device, + backend_fw, ): input_dtype, x = dtype_and_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "value": x[0], + "data": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={}, - frontend=frontend, + method_all_as_kwargs_np={ + "y": x[1], + }, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, + frontend=frontend, on_device=on_device, ) -# long +# __radd__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__long__", + method_name="__radd__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("integer"), - max_num_dims=0, - min_value=-1e15, - max_value=1e15, + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True ), ) -def test_paddle__long__( +def test_paddle___radd__( dtype_and_x, frontend_method_data, init_flags, method_flags, - backend_fw, frontend, on_device, + backend_fw, ): - input_dtypes, xs = dtype_and_x - # Numpy doesn't support complex to int conversion - assume(not np.issubdtype(input_dtypes[0], np.complexfloating)) + input_dtype, x = dtype_and_x helpers.test_frontend_method( - init_input_dtypes=input_dtypes, + init_input_dtypes=input_dtype, backend_to_test=backend_fw, - method_input_dtypes=input_dtypes, init_all_as_kwargs_np={ - "object": xs[0], + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "x": x[1], }, - method_all_as_kwargs_np={}, - frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, + frontend=frontend, on_device=on_device, ) -# __ne__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__ne__", + method_name="__rdiv__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2, - min_value=-1e04, - max_value=1e04, - allow_inf=False, + shared_dtype=True, + large_abs_safety_factor=10, + small_abs_safety_factor=10, + safety_factor_scale="log", ), ) -def test_paddle__ne__( +def test_paddle___rdiv__( dtype_and_x, + frontend, frontend_method_data, init_flags, method_flags, - frontend, on_device, backend_fw, ): input_dtype, x = dtype_and_x + assume(not np.any(np.isclose(x[0], 0))) + assume(not np.any(np.isclose(x[1], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "data": x[0], + "value": x[0], }, method_input_dtypes=input_dtype, method_all_as_kwargs_np={ - "other": x[1], + "y": x[1], }, + frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, - frontend=frontend, on_device=on_device, ) -# __neg__ +# __rmul__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__neg__", + method_name="__rmul__", dtype_and_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("float"), + num_arrays=2, min_value=-1e04, max_value=1e04, allow_inf=False, ), ) -def test_paddle__neg__( +def test_paddle___rmul__( dtype_and_x, frontend_method_data, init_flags, @@ -1014,7 +1169,9 @@ def test_paddle__neg__( "data": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np={}, + method_all_as_kwargs_np={ + "other": x[1], + }, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, @@ -1023,31 +1180,27 @@ def test_paddle__neg__( ) +# __rsub__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__rdiv__", + method_name="__rsub__", dtype_and_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2, shared_dtype=True, - large_abs_safety_factor=10, - small_abs_safety_factor=10, - safety_factor_scale="log", ), ) -def test_paddle__rdiv__( +def test_paddle___rsub__( dtype_and_x, frontend, frontend_method_data, init_flags, method_flags, - on_device, backend_fw, + on_device, ): input_dtype, x = dtype_and_x - assume(not np.any(np.isclose(x[0], 0))) - assume(not np.any(np.isclose(x[1], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -1056,7 +1209,7 @@ def test_paddle__rdiv__( }, method_input_dtypes=input_dtype, method_all_as_kwargs_np={ - "y": x[1], + "x": x[1], }, frontend=frontend, frontend_method_data=frontend_method_data, @@ -1066,58 +1219,60 @@ def test_paddle__rdiv__( ) -# reshape @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="reshape", - dtype_x_shape=_reshape_helper(), + method_name="__rtruediv__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + num_arrays=2, + shared_dtype=True, + large_abs_safety_factor=10, + small_abs_safety_factor=10, + safety_factor_scale="log", + ), ) -def test_paddle__reshape( - dtype_x_shape, +def test_paddle___rtruediv__( + dtype_and_x, + frontend, frontend_method_data, init_flags, method_flags, - frontend, on_device, backend_fw, ): - input_dtype, x, shape = dtype_x_shape - assume(len(shape) != 0) - shape = { - "shape": shape, - } + input_dtype, x = dtype_and_x + assume(not np.any(np.isclose(x[0], 0))) + assume(not np.any(np.isclose(x[1], 0))) helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "data": x[0], + "value": x[0], }, method_input_dtypes=input_dtype, - method_all_as_kwargs_np=shape, + method_all_as_kwargs_np={ + "y": x[1], + }, + frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, - frontend=frontend, on_device=on_device, ) -# __rmul__ +# __setitem__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__rmul__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), - num_arrays=2, - min_value=-1e04, - max_value=1e04, - allow_inf=False, - ), + method_name="__setitem__", + dtypes_x_index_val=helpers.dtype_array_query_val( + available_dtypes=helpers.get_dtypes("valid"), + ).filter(lambda x: x[0][0] == x[0][-1] and _filter_query(x[-2])), ) -def test_paddle__rmul__( - dtype_and_x, +def test_paddle___setitem__( + dtypes_x_index_val, frontend_method_data, init_flags, method_flags, @@ -1125,17 +1280,13 @@ def test_paddle__rmul__( on_device, backend_fw, ): - input_dtype, x = dtype_and_x + input_dtype, x, index, val = dtypes_x_index_val helpers.test_frontend_method( - init_input_dtypes=input_dtype, + init_input_dtypes=[input_dtype[0]], backend_to_test=backend_fw, - init_all_as_kwargs_np={ - "data": x[0], - }, - method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "other": x[1], - }, + init_all_as_kwargs_np={"data": x}, + method_input_dtypes=[*input_dtype[1:]], + method_all_as_kwargs_np={"item": index, "value": val}, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, @@ -1144,41 +1295,39 @@ def test_paddle__rmul__( ) -# __rsub__ +# __sub__ @handle_frontend_method( class_tree=CLASS_TREE, init_tree="paddle.to_tensor", - method_name="__rsub__", + method_name="__sub__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - num_arrays=2, - shared_dtype=True, + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True ), ) -def test_paddle__rsub__( +def test_paddle___sub__( dtype_and_x, - frontend, frontend_method_data, init_flags, method_flags, - backend_fw, + frontend, on_device, + backend_fw, ): input_dtype, x = dtype_and_x helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, init_all_as_kwargs_np={ - "value": x[0], + "data": x[0], }, method_input_dtypes=input_dtype, method_all_as_kwargs_np={ - "x": x[1], + "y": x[1], }, - frontend=frontend, frontend_method_data=frontend_method_data, init_flags=init_flags, method_flags=method_flags, + frontend=frontend, on_device=on_device, ) @@ -1194,7 +1343,7 @@ def test_paddle__rsub__( shared_dtype=True, ), ) -def test_paddle__xor__( +def test_paddle___xor__( dtype_and_x, frontend, frontend_method_data, @@ -2594,7 +2743,7 @@ def test_paddle_device( available_dtypes=helpers.get_dtypes("valid"), shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape"), ), - dims_and_offset=dims_and_offset( + dims_and_offset=helpers.dims_and_offset( shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape") ), ) @@ -4671,6 +4820,80 @@ def test_paddle_remainder_( ) +# reshape +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="paddle.to_tensor", + method_name="reshape", + dtype_x_shape=_reshape_helper(), +) +def test_paddle_reshape( + dtype_x_shape, + frontend_method_data, + init_flags, + method_flags, + frontend, + on_device, + backend_fw, +): + input_dtype, x, shape = dtype_x_shape + assume(len(shape) != 0) + shape = { + "shape": shape, + } + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np=shape, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + +# reshape_ +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="paddle.to_tensor", + method_name="reshape_", + dtype_x_shape=_reshape_helper(), +) +def test_paddle_reshape_( + dtype_x_shape, + frontend_method_data, + init_flags, + method_flags, + frontend, + on_device, + backend_fw, +): + input_dtype, x, shape = dtype_x_shape + assume(len(shape) != 0) + shape = { + "shape": shape, + } + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np=shape, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # rot90 @handle_frontend_method( class_tree=CLASS_TREE, @@ -5539,6 +5762,57 @@ def test_paddle_tensor_chunk( ) +# cov +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="paddle.to_tensor", + method_name="cov", + dtype_x1_corr_cov=_get_dtype_value1_value2_cov( + available_dtypes=helpers.get_dtypes("float"), + min_num_dims=2, + max_num_dims=2, + min_dim_size=2, + max_dim_size=5, + min_value=1, + max_value=1e10, + abs_smallest_val=0.01, + large_abs_safety_factor=2, + safety_factor_scale="log", + ), +) +def test_paddle_tensor_cov( + dtype_x1_corr_cov, + frontend_method_data, + init_flags, + method_flags, + frontend, + backend_fw, + on_device, +): + dtype, x, rowvar, ddof, fweights, aweights = dtype_x1_corr_cov + helpers.test_frontend_method( + init_input_dtypes=["float64", "int64", "float64"], + init_all_as_kwargs_np={ + "data": x, + }, + method_input_dtypes=["int64", "float64"], + backend_to_test=backend_fw, + method_all_as_kwargs_np={ + "rowvar": rowvar, + "ddof": ddof, + "fweights": fweights, + "aweights": aweights, + }, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + rtol_=1e-3, + atol_=1e-3, + frontend=frontend, + on_device=on_device, + ) + + # expand @handle_frontend_method( class_tree=CLASS_TREE, @@ -5574,6 +5848,53 @@ def test_paddle_tensor_expand( ) +# flatten +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="paddle.to_tensor", + method_name="flatten", + dtype_value=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + shape=st.shared(helpers.get_shape(), key="shape"), + ), + axes=helpers.get_axis( + shape=st.shared(helpers.get_shape(), key="shape"), + min_size=2, + max_size=2, + unique=False, + force_tuple=True, + ), +) +def test_paddle_tensor_flatten( + dtype_value, + axes, + frontend_method_data, + init_flags, + method_flags, + frontend, + on_device, + backend_fw, +): + input_dtype, x = dtype_value + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "start_axis": axes[0], + "stop_axis": axes[1], + }, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # floor_mod @handle_frontend_method( class_tree=CLASS_TREE, @@ -5652,6 +5973,88 @@ def test_paddle_tensor_heaviside( ) +# matmul +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="paddle.to_tensor", + method_name="matmul", + dtype_tensor1_tensor2=_get_dtype_and_multiplicative_matrices(), +) +def test_paddle_tensor_matmul( + dtype_tensor1_tensor2, + frontend_method_data, + init_flags, + method_flags, + frontend, + on_device, + backend_fw, +): + dtype, tensor1, tensor2, transpose_x, transpose_y = dtype_tensor1_tensor2 + + helpers.test_frontend_method( + init_input_dtypes=dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": tensor1, + }, + method_input_dtypes=dtype, + method_all_as_kwargs_np={ + "y": tensor2, + "transpose_x": transpose_x, + "transpose_y": transpose_y, + }, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + +# squeeze +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="paddle.to_tensor", + method_name="squeeze", + dtype_value=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + shape=st.shared(helpers.get_shape(), key="shape"), + ), + axis=helpers.get_axis( + shape=st.shared(helpers.get_shape(), key="shape"), + allow_neg=True, + force_int=True, + ), +) +def test_paddle_tensor_squeeze( + dtype_value, + axis, + frontend_method_data, + init_flags, + method_flags, + frontend, + on_device, + backend_fw, +): + input_dtype, x = dtype_value + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "axis": axis, + }, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # tile @handle_frontend_method( class_tree=CLASS_TREE, diff --git a/ivy_tests/test_ivy/test_frontends/test_sklearn/test_tree/test_tree.py b/ivy_tests/test_ivy/test_frontends/test_sklearn/test_tree/test_tree.py new file mode 100644 index 0000000000000..350d6d208e671 --- /dev/null +++ b/ivy_tests/test_ivy/test_frontends/test_sklearn/test_tree/test_tree.py @@ -0,0 +1,44 @@ +from ivy.functional.frontends.sklearn.tree import DecisionTreeClassifier as ivy_DTC +import ivy +from hypothesis import given +import ivy_tests.test_ivy.helpers as helpers + + +# --- Helpers --- # +# --------------- # + + +# helper functions +def _get_sklearn_predict(X, y, max_depth, DecisionTreeClassifier): + clf = DecisionTreeClassifier(max_depth=max_depth, random_state=0) + clf.fit(X, y) + return clf.predict + + +# --- Main --- # +# ------------ # + + +# todo: integrate with already existing strats and generalize +@given( + X=helpers.array_values( + shape=(5, 2), + dtype=helpers.get_dtypes("float", prune_function=False), + safety_factor_scale="log", + ), + y=helpers.array_values( + shape=(5,), + dtype=helpers.get_dtypes("signed_integer", prune_function=False), + safety_factor_scale="log", + ), + max_depth=helpers.ints(max_value=5, min_value=1), +) +def test_sklearn_tree_predict(X, y, max_depth): + try: + from sklearn.tree import DecisionTreeClassifier as sklearn_DTC + except ImportError: + print("sklearn not installed, skipping test_sklearn_tree_predict") + return + sklearn_pred = _get_sklearn_predict(X, y, max_depth, sklearn_DTC)(X) + ivy_pred = _get_sklearn_predict(ivy.array(X), ivy.array(y), max_depth, ivy_DTC)(X) + helpers.assert_same_type_and_shape([sklearn_pred, ivy_pred]) diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test___operators__.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test___operators__.py new file mode 100644 index 0000000000000..c5728e0085ee3 --- /dev/null +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test___operators__.py @@ -0,0 +1,38 @@ +# global +from hypothesis import strategies as st + +# local +import ivy_tests.test_ivy.helpers as helpers +from ivy_tests.test_ivy.helpers.testing_helpers import handle_frontend_test + + +# add +@handle_frontend_test( + fn_tree="tensorflow.__operators__.add", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + num_arrays=2, + shared_dtype=True, + ), + test_with_out=st.just(False), +) +def test_tensorflow___operators___add( + *, + dtype_and_x, + frontend, + test_flags, + fn_tree, + backend_fw, + on_device, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + x=x[0], + y=x[1], + ) diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_keras/test_backend.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_keras/test_backend.py new file mode 100644 index 0000000000000..21ba947042729 --- /dev/null +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_keras/test_backend.py @@ -0,0 +1,374 @@ +# global +from hypothesis import assume, strategies as st +from ivy.func_wrapper import output_to_native_arrays + +# local +import ivy_tests.test_ivy.helpers as helpers +from ivy_tests.test_ivy.helpers import handle_frontend_test +from ivy_tests.test_ivy.test_functional.test_experimental.test_core.test_linalg import ( + _generate_dot_dtype_and_arrays, +) +from ivy_tests.test_ivy.test_frontends.test_tensorflow.test_nn import ( + _generate_bias_data, +) +from ivy_tests.test_ivy.test_functional.test_experimental.test_nn.test_layers import ( + _lstm_helper, +) +import ivy +from ivy.functional.frontends.tensorflow.func_wrapper import ( + inputs_to_ivy_arrays, + outputs_to_frontend_arrays, +) +import ivy.functional.frontends.tensorflow as tf_frontend + + +# --- Helpers --- # +# --------------- # + + +@st.composite +def _x_and_filters( + draw, + dtypes, + data_format, + padding=None, + stride_min=1, + stride_max=4, + dilation_min=1, + dilation_max=4, + type: str = "depthwise", +): + data_format = draw(data_format) + dtype = draw(dtypes) + dim = 2 if type in ["depthwise", "separable"] else 4 + if padding is None: + padding = (st.sampled_from(["same", "valid"]),) + padding = draw(padding) + dilations = draw( + st.one_of( + st.integers(dilation_min, dilation_max), + st.lists( + st.integers(dilation_min, dilation_max), min_size=dim, max_size=dim + ), + ) + ) + fdilations = [dilations] * dim if isinstance(dilations, int) else dilations + if type in ["depthwise", "separable"]: + # if any value in dilations is greater than 1, tensorflow implements + # depthwise_covn2d as an atrous depthwise convolution, in which case all values + # in strides must be equal to 1. + if any(x > 1 for x in fdilations): + stride = 1 + else: + stride = draw(st.integers(stride_min, stride_max)) + else: + stride = draw( + st.one_of( + st.integers(stride_min, stride_max), + st.lists( + st.integers(stride_min, stride_max), min_size=dim, max_size=dim + ), + ) + ) + if dim == 2: + min_x_height = 1 + min_x_width = 1 + filter_shape = draw( + st.tuples( + helpers.ints(min_value=3, max_value=5), + helpers.ints(min_value=3, max_value=5), + helpers.ints(min_value=1, max_value=3), + helpers.ints(min_value=1, max_value=3), + ) + ) + min_x_height = filter_shape[0] + (filter_shape[0] - 1) * (fdilations[0] - 1) + min_x_width = filter_shape[1] + (filter_shape[1] - 1) * (fdilations[1] - 1) + d_in = filter_shape[2] + if data_format == "channels_last": + x_shape = draw( + st.tuples( + helpers.ints(min_value=1, max_value=5), + helpers.ints(min_value=min_x_height, max_value=100), + helpers.ints(min_value=min_x_width, max_value=100), + helpers.ints(min_value=d_in, max_value=d_in), + ) + ) + else: + x_shape = draw( + st.tuples( + helpers.ints(min_value=1, max_value=5), + helpers.ints(min_value=d_in, max_value=d_in), + helpers.ints(min_value=min_x_height, max_value=100), + helpers.ints(min_value=min_x_width, max_value=100), + ) + ) + x = draw( + helpers.array_values(dtype=dtype[0], shape=x_shape, min_value=0, max_value=1) + ) + filters = draw( + helpers.array_values( + dtype=dtype[0], shape=filter_shape, min_value=0, max_value=1 + ) + ) + if type in ["depthwise", "separable"]: + stride = (stride, stride) + if isinstance(dilations, int): + dilations = (dilations,) * dim + return dtype, x, filters, dilations, data_format, stride, padding + + +# --- Main --- # +# ------------ # + + +@handle_frontend_test( + fn_tree="tensorflow.keras.backend.dot", + data=_generate_dot_dtype_and_arrays(min_num_dims=2), +) +def test_tensorflow_dot(*, data, on_device, fn_tree, frontend, test_flags, backend_fw): + (input_dtypes, x) = data + return helpers.test_frontend_function( + input_dtypes=input_dtypes, + test_flags=test_flags, + backend_to_test=backend_fw, + on_device=on_device, + frontend=frontend, + fn_tree=fn_tree, + rtol=0.5, + atol=0.5, + x=x[0], + y=x[1], + ) + + +@handle_frontend_test( + fn_tree="tensorflow.keras.backend.bias_add", + data=_generate_bias_data(keras_backend_fn=True), + test_with_out=st.just(False), +) +def test_tensorflow_keras_backend_bias_add( + *, + data, + frontend, + test_flags, + fn_tree, + backend_fw, + on_device, +): + data_format, dtype, x, bias = data + helpers.test_frontend_function( + input_dtypes=dtype * 2, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + x=x[0], + bias=bias, + data_format=data_format, + ) + + +@handle_frontend_test( + fn_tree="tensorflow.keras.backend.depthwise_conv2d", + x_f_d_df=_x_and_filters( + dtypes=helpers.get_dtypes("float", full=False), + data_format=st.sampled_from(["channels_last"]), + padding=st.sampled_from(["valid", "same"]), + type="depthwise", + ), + test_with_out=st.just(False), +) +def test_tensorflow_keras_backend_depthwise_conv2d( + *, + x_f_d_df, + frontend, + test_flags, + fn_tree, + backend_fw, + on_device, +): + input_dtype, x, filters, dilation, data_format, stride, padding = x_f_d_df + helpers.test_frontend_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + x=x, + depthwise_kernel=filters, + strides=stride, + padding=padding, + data_format=data_format, + dilation_rate=dilation, + ) + + +# mean +@handle_frontend_test( + fn_tree="tensorflow.keras.backend.mean", + dtype_x_axis=helpers.dtype_values_axis( + available_dtypes=helpers.get_dtypes("float"), + force_int_axis=True, + valid_axis=True, + min_num_dims=1, + large_abs_safety_factor=24, + small_abs_safety_factor=24, + safety_factor_scale="log", + ), + keepdims=st.booleans(), + test_with_out=st.just(False), +) +def test_tensorflow_keras_backend_mean( + *, + dtype_x_axis, + keepdims, + frontend, + test_flags, + fn_tree, + backend_fw, + on_device, +): + input_dtype, x, axis = dtype_x_axis + helpers.test_frontend_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + atol=1e-1, + rtol=1e-1, + on_device=on_device, + x=x[0], + axis=axis, + keepdims=keepdims, + ) + + +@handle_frontend_test( + fn_tree="tensorflow.keras.backend.rnn", + rnn_args=_lstm_helper(), + test_with_out=st.just(False), +) +def test_tensorflow_keras_backend_rnn( + *, + rnn_args, + frontend, + test_flags, + fn_tree, + backend_fw, + on_device, +): + ( + input_dtypes, + inputs, + kernel_orig, + recurrent_kernel_orig, + bias_orig, + recurrent_bias_orig, + initial_states, + go_backwards, + mask, + unroll, + input_length, + time_major, + zero_output_for_mask, + return_all_outputs, + ) = rnn_args + + # unsupported dtype of float16 is in our _lstm_step function + # so can't be inferred through ivy.function_unsupported_devices_and_dtypes + assume(not (backend_fw == "torch" and input_dtypes[0] == "float16")) + + def _lstm_step(cell_inputs, cell_states): + nonlocal kernel_orig, recurrent_kernel_orig, bias_orig, recurrent_bias_orig + kernel = ivy.array(kernel_orig) + recurrent_kernel = ivy.array(recurrent_kernel_orig) + bias = ivy.array(bias_orig) + recurrent_bias = ivy.array(recurrent_bias_orig) + + h_tm1 = cell_states[0] # previous memory state + c_tm1 = cell_states[1] # previous carry state + + z = ivy.dot(cell_inputs, kernel) + bias + z += ivy.dot(h_tm1, recurrent_kernel) + recurrent_bias + + z0, z1, z2, z3 = ivy.split(z, num_or_size_splits=4, axis=-1) + + i = ivy.sigmoid(z0) # input + f = ivy.sigmoid(z1) # forget + c = f * c_tm1 + i * ivy.tanh(z2) + o = ivy.sigmoid(z3) # output + + h = o * ivy.tanh(c) + return h, [h, c] + + np_vals = [inputs, *initial_states, mask] + + if mask is None: + np_vals.pop(-1) + + with ivy.utils.backend.ContextManager(backend_fw): + _lstm_step_backend = outputs_to_frontend_arrays( + inputs_to_ivy_arrays(_lstm_step) + ) + vals = [ivy.array(val) for val in np_vals] + if len(vals) > 3: + inputs, init_h, init_c, mask = vals + else: + inputs, init_h, init_c = vals + initial_states = [init_h, init_c] + + args = (_lstm_step_backend, inputs, initial_states) + kwargs = { + "go_backwards": go_backwards, + "mask": mask, + "constants": None, + "unroll": unroll, + "input_length": input_length, + "time_major": time_major, + "zero_output_for_mask": zero_output_for_mask, + "return_all_outputs": return_all_outputs, + } + ret = tf_frontend.keras.backend.rnn(*args, **kwargs) + ivy_ret = ivy.nested_map(lambda x: x.ivy_array, ret, shallow=False) + ivy_idxs = ivy.nested_argwhere(ivy_ret, ivy.is_ivy_array) + ivy_vals = ivy.multi_index_nest(ivy_ret, ivy_idxs) + ret_np_flat = [x.to_numpy() for x in ivy_vals] + + with ivy.utils.backend.ContextManager(frontend): + _lstm_step_gt = output_to_native_arrays(inputs_to_ivy_arrays(_lstm_step)) + import tensorflow as tf + + vals = [ivy.array(val).data for val in np_vals] + if len(vals) > 3: + inputs, init_h, init_c, mask = vals + else: + inputs, init_h, init_c = vals + initial_states = [init_h, init_c] + + args = (_lstm_step_gt, inputs, initial_states) + kwargs = { + "go_backwards": go_backwards, + "mask": mask, + "constants": None, + "unroll": unroll, + "input_length": input_length, + "time_major": time_major, + "zero_output_for_mask": zero_output_for_mask, + "return_all_outputs": return_all_outputs, + } + ret = tf.keras.backend.rnn(*args, **kwargs) + native_idxs = ivy.nested_argwhere(ret, lambda x: isinstance(x, ivy.NativeArray)) + native_vals = ivy.multi_index_nest(ret, native_idxs) + frontend_ret_np_flat = [x.numpy() for x in native_vals] + + helpers.value_test( + ret_np_flat=ret_np_flat, + ret_np_from_gt_flat=frontend_ret_np_flat, + rtol=1e-1, + atol=1e-1, + backend=backend_fw, + ground_truth_backend=frontend, + ) diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py index 716f149551848..24e4d61344997 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py @@ -414,6 +414,7 @@ def test_tensorflow_eigvals( rtol=1e-06, atol=1e-06, ground_truth_backend=frontend, + backend=backend_fw, ) @@ -969,6 +970,7 @@ def test_tensorflow_qr( rtol=1e-2, atol=1e-2, ground_truth_backend=frontend, + backend=backend_fw, ) @@ -1120,6 +1122,7 @@ def test_tensorflow_svd( rtol=1e-2, atol=1e-2, ground_truth_backend=frontend, + backend=backend_fw, ) diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_math.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_math.py index 1ad9f4d2e1987..aec91a0c64eab 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_math.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_math.py @@ -238,7 +238,7 @@ def test_tensorflow_angle( @handle_frontend_test( fn_tree="tensorflow.math.argmax", dtype_and_x=_statistical_dtype_values(function="argmax"), - output_type=st.sampled_from(["int16", "uint16", "int32", "int64"]), + output_type=st.sampled_from(["int32", "int64"]), test_with_out=st.just(False), ) def test_tensorflow_argmax( @@ -251,9 +251,7 @@ def test_tensorflow_argmax( on_device, output_type, ): - if backend_fw in ("torch", "paddle"): - assume(output_type != "uint16") - input_dtype, x, axis = dtype_and_x + input_dtype, x, axis, *_ = dtype_and_x if isinstance(axis, tuple): axis = axis[0] helpers.test_frontend_function( @@ -286,7 +284,7 @@ def test_tensorflow_argmin( on_device, output_type, ): - input_dtype, x, axis = dtype_and_x + input_dtype, x, axis, *_ = dtype_and_x if isinstance(axis, tuple): axis = axis[0] helpers.test_frontend_function( @@ -449,6 +447,41 @@ def test_tensorflow_atanh( ) +# bessel_i1 +@handle_frontend_test( + fn_tree="tensorflow.math.bessel_i1", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + num_arrays=1, + min_value=-10, + max_value=10, + min_num_dims=1, + max_num_dims=4, + shared_dtype=True, + ), + test_with_out=st.just(False), +) +def test_tensorflow_bessel_i1( + *, + dtype_and_x, + frontend, + test_flags, + fn_tree, + backend_fw, + on_device, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + x=x[0], + ) + + # bincount @handle_frontend_test( fn_tree="tensorflow.math.bincount", diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_nn.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_nn.py index 9c26b4a068eb4..ce528f775d260 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_nn.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_nn.py @@ -136,9 +136,13 @@ def _dropout_helper(draw): @st.composite -def _generate_bias_data(draw): +def _generate_bias_data(draw, keras_backend_fn=False): data_format = draw(st.sampled_from(["NC...", "N...C", None])) channel_dim = 1 if data_format == "NC..." else -1 + if keras_backend_fn: + data_format = {"NC...": "channels_first", "N...C": "channels_last", None: None}[ + data_format + ] dtype, value, shape = draw( helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("numeric"), diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py index 44be3315bf271..ad9b5ee4f3114 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py @@ -265,6 +265,40 @@ def _reshape_helper(draw): return x, dtype, reshape_shape +@st.composite +def _segment_ops_helper(draw): + shape_x = draw(st.integers(min_value=3, max_value=100)) + shape_y = draw(st.integers(min_value=3, max_value=100)) + max_val = draw(st.integers(min_value=3, max_value=9)) + s_dtype = draw( + st.sampled_from( + [ + "int32", + "int64", + ] + ) + ) + data_dtype, data = draw( + helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + num_arrays=1, + shape=(shape_x, shape_y), + min_value=-max_val, + max_value=max_val, + ) + ) + seg_dtype, segment_ids = draw( + helpers.dtype_and_values( + available_dtypes=[s_dtype], + num_arrays=1, + shape=(shape_x,), + min_value=0, + max_value=max_val, + ) + ) + return data_dtype + seg_dtype, data, segment_ids, max_val + + @st.composite def _squeeze_helper(draw): shape = draw(st.shared(helpers.get_shape(), key="value_shape")) @@ -2098,6 +2132,44 @@ def test_tensorflow_Gather( # NOQA ) +# GatherNd +@handle_frontend_test( + fn_tree="tensorflow.raw_ops.GatherNd", + params_indices_axis_batch_dims=helpers.array_indices_axis( + array_dtypes=helpers.get_dtypes("valid"), + indices_dtypes=["int32", "int64"], + min_num_dims=3, + max_num_dims=3, + min_dim_size=3, + max_dim_size=3, + axis_zero=True, + disable_random_axis=True, + indices_same_dims=True, + ), + test_with_out=st.just(False), +) +def test_tensorflow_GatherNd( + *, + params_indices_axis_batch_dims, + frontend, + test_flags, + fn_tree, + backend_fw, + on_device, +): + input_dtypes, params, indices = params_indices_axis_batch_dims + helpers.test_frontend_function( + input_dtypes=input_dtypes, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + params=params, + indices=indices, + ) + + # Greater @handle_frontend_test( fn_tree="tensorflow.raw_ops.Greater", @@ -4245,6 +4317,7 @@ def test_tensorflow_Svd( rtol=1e-2, atol=1e-2, ground_truth_backend=frontend, + backend=backend_fw, ) @@ -4427,6 +4500,34 @@ def test_tensorflow_Unpack( # NOQA ) +@handle_frontend_test( + fn_tree="tensorflow.raw_ops.UnsortedSegmentProd", + params=_segment_ops_helper(), + test_with_out=st.just(False), +) +def test_tensorflow_UnsortedSegmentProd( + *, + params, + frontend, + test_flags, + fn_tree, + backend_fw, + on_device, +): + dtypes, data, segment_ids, max_val = params + helpers.test_frontend_function( + input_dtypes=dtypes, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + data=data[0], + segment_ids=segment_ids[0], + num_segments=max_val + 1, + ) + + @handle_frontend_test( fn_tree="tensorflow.raw_ops.Xdivy", dtype_and_x=helpers.dtype_and_values( diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_tensor.py index 66acd2020de79..153f2089e184b 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_tensor.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_tensor.py @@ -85,7 +85,7 @@ def _check_query(query): shared_dtype=True, ), ) -def test_tensorflow__add__( +def test_tensorflow___add__( dtype_and_x, frontend, frontend_method_data, @@ -113,45 +113,6 @@ def test_tensorflow__add__( ) -# __and__ -@handle_frontend_method( - class_tree=CLASS_TREE, - init_tree="tensorflow.constant", - method_name="__and__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("integer"), - num_arrays=2, - shared_dtype=True, - ), -) -def test_tensorflow__and__( - dtype_and_x, - frontend, - frontend_method_data, - init_flags, - method_flags, - backend_fw, - on_device, -): - input_dtype, x = dtype_and_x - helpers.test_frontend_method( - init_input_dtypes=input_dtype, - backend_to_test=backend_fw, - init_all_as_kwargs_np={ - "value": x[0], - }, - method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "y": x[1], - }, - frontend=frontend, - frontend_method_data=frontend_method_data, - init_flags=init_flags, - method_flags=method_flags, - on_device=on_device, - ) - - # __array__ @handle_frontend_method( class_tree=CLASS_TREE, @@ -160,7 +121,7 @@ def test_tensorflow__and__( dtype_and_x=helpers.dtype_and_values(available_dtypes=helpers.get_dtypes("valid")), dtype=helpers.get_dtypes("valid", full=False), ) -def test_tensorflow__array__( +def test_tensorflow___array__( dtype_and_x, dtype, frontend, @@ -193,7 +154,7 @@ def test_tensorflow__array__( max_dim_size=1, ), ) -def test_tensorflow__bool__( +def test_tensorflow___bool__( dtype_and_x, frontend, frontend_method_data, @@ -232,7 +193,7 @@ def test_tensorflow__bool__( safety_factor_scale="log", ), ) -def test_tensorflow__div__( +def test_tensorflow___div__( dtype_and_x, frontend, frontend_method_data, @@ -271,7 +232,7 @@ def test_tensorflow__div__( num_arrays=2, ), ) -def test_tensorflow__eq__( +def test_tensorflow___eq__( dtype_and_x, frontend, frontend_method_data, @@ -312,7 +273,7 @@ def test_tensorflow__eq__( safety_factor_scale="log", ), ) -def test_tensorflow__floordiv__( +def test_tensorflow___floordiv__( dtype_and_x, frontend, frontend_method_data, @@ -351,7 +312,7 @@ def test_tensorflow__floordiv__( shared_dtype=True, ), ) -def test_tensorflow__ge__( +def test_tensorflow___ge__( dtype_and_x, frontend, frontend_method_data, @@ -394,7 +355,7 @@ def test_tensorflow__ge__( ) ), ) -def test_tensorflow__getitem__( +def test_tensorflow___getitem__( dtype_x_index, frontend, frontend_method_data, @@ -429,7 +390,7 @@ def test_tensorflow__getitem__( shared_dtype=True, ), ) -def test_tensorflow__gt__( +def test_tensorflow___gt__( dtype_and_x, frontend, frontend_method_data, @@ -466,7 +427,7 @@ def test_tensorflow__gt__( available_dtypes=helpers.get_dtypes("integer") ), ) -def test_tensorflow__invert__( +def test_tensorflow___invert__( dtype_and_x, frontend, frontend_method_data, @@ -503,7 +464,7 @@ def test_tensorflow__invert__( shared_dtype=True, ), ) -def test_tensorflow__le__( +def test_tensorflow___le__( dtype_and_x, frontend, frontend_method_data, @@ -541,7 +502,7 @@ def test_tensorflow__le__( max_num_dims=5, ), ) -def test_tensorflow__len__( +def test_tensorflow___len__( dtype_and_x, frontend, frontend_method_data, @@ -578,7 +539,7 @@ def test_tensorflow__len__( shared_dtype=True, ), ) -def test_tensorflow__lt__( +def test_tensorflow___lt__( dtype_and_x, frontend, frontend_method_data, @@ -626,7 +587,7 @@ def test_tensorflow__lt__( safety_factor_scale="log", ), ) -def test_tensorflow__matmul__( +def test_tensorflow___matmul__( dtype_and_x, frontend, frontend_method_data, @@ -665,7 +626,7 @@ def test_tensorflow__matmul__( shared_dtype=True, ), ) -def test_tensorflow__mod__( +def test_tensorflow___mod__( dtype_and_x, frontend, frontend_method_data, @@ -705,7 +666,7 @@ def test_tensorflow__mod__( shared_dtype=True, ), ) -def test_tensorflow__mul__( +def test_tensorflow___mul__( dtype_and_x, frontend, frontend_method_data, @@ -744,7 +705,7 @@ def test_tensorflow__mul__( shared_dtype=True, ), ) -def test_tensorflow__ne__( +def test_tensorflow___ne__( dtype_and_x, frontend, frontend_method_data, @@ -788,7 +749,7 @@ def test_tensorflow__ne__( ], ), ) -def test_tensorflow__neg__( +def test_tensorflow___neg__( dtype_and_x, frontend, frontend_method_data, @@ -824,7 +785,7 @@ def test_tensorflow__neg__( max_dim_size=1, ), ) -def test_tensorflow__nonzero__( +def test_tensorflow___nonzero__( dtype_and_x, frontend, frontend_method_data, @@ -861,7 +822,7 @@ def test_tensorflow__nonzero__( shared_dtype=True, ), ) -def test_tensorflow__or__( +def test_tensorflow___or__( dtype_and_x, frontend, frontend_method_data, @@ -906,7 +867,7 @@ def test_tensorflow__or__( shared_dtype=True, ), ) -def test_tensorflow__pow__( +def test_tensorflow___pow__( dtype_and_x, frontend, frontend_method_data, @@ -952,7 +913,7 @@ def test_tensorflow__pow__( shared_dtype=True, ), ) -def test_tensorflow__radd__( +def test_tensorflow___radd__( dtype_and_x, frontend, frontend_method_data, @@ -991,7 +952,7 @@ def test_tensorflow__radd__( shared_dtype=True, ), ) -def test_tensorflow__rand__( +def test_tensorflow___rand__( dtype_and_x, frontend, frontend_method_data, @@ -1033,7 +994,7 @@ def test_tensorflow__rand__( safety_factor_scale="log", ), ) -def test_tensorflow__rfloordiv__( +def test_tensorflow___rfloordiv__( dtype_and_x, frontend, frontend_method_data, @@ -1081,7 +1042,7 @@ def test_tensorflow__rfloordiv__( safety_factor_scale="log", ), ) -def test_tensorflow__rmatmul__( +def test_tensorflow___rmatmul__( dtype_and_x, frontend, frontend_method_data, @@ -1122,7 +1083,7 @@ def test_tensorflow__rmatmul__( max_value=100, ), ) -def test_tensorflow__rmul__( +def test_tensorflow___rmul__( dtype_and_x, frontend, frontend_method_data, @@ -1161,7 +1122,7 @@ def test_tensorflow__rmul__( shared_dtype=True, ), ) -def test_tensorflow__ror__( +def test_tensorflow___ror__( dtype_and_x, frontend, frontend_method_data, @@ -1196,7 +1157,7 @@ def test_tensorflow__ror__( method_name="__rpow__", dtype_and_x=_pow_helper_shared_dtype(), ) -def test_tensorflow__rpow__( +def test_tensorflow___rpow__( dtype_and_x, frontend, frontend_method_data, @@ -1235,7 +1196,7 @@ def test_tensorflow__rpow__( shared_dtype=True, ), ) -def test_tensorflow__rsub__( +def test_tensorflow___rsub__( dtype_and_x, frontend, frontend_method_data, @@ -1277,7 +1238,7 @@ def test_tensorflow__rsub__( safety_factor_scale="log", ), ) -def test_tensorflow__rtruediv__( +def test_tensorflow___rtruediv__( dtype_and_x, frontend, frontend_method_data, @@ -1316,7 +1277,7 @@ def test_tensorflow__rtruediv__( shared_dtype=True, ), ) -def test_tensorflow__rxor__( +def test_tensorflow___rxor__( dtype_and_x, frontend, frontend_method_data, @@ -1355,7 +1316,7 @@ def test_tensorflow__rxor__( shared_dtype=True, ), ) -def test_tensorflow__sub__( +def test_tensorflow___sub__( dtype_and_x, frontend, frontend_method_data, @@ -1397,7 +1358,7 @@ def test_tensorflow__sub__( safety_factor_scale="log", ), ) -def test_tensorflow__truediv__( +def test_tensorflow___truediv__( dtype_and_x, frontend, frontend_method_data, @@ -1437,7 +1398,46 @@ def test_tensorflow__truediv__( shared_dtype=True, ), ) -def test_tensorflow__xor__( +def test_tensorflow___xor__( + dtype_and_x, + frontend, + frontend_method_data, + init_flags, + method_flags, + backend_fw, + on_device, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "value": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "y": x[1], + }, + frontend=frontend, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + on_device=on_device, + ) + + +# __and__ +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="tensorflow.constant", + method_name="__and__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("integer"), + num_arrays=2, + shared_dtype=True, + ), +) +def test_tensorflow__and__( dtype_and_x, frontend, frontend_method_data, @@ -1552,6 +1552,7 @@ def test_tensorflow_ivy_array( ret_np_flat=ret, ret_np_from_gt_flat=ret_gt, ground_truth_backend="tensorflow", + backend=backend_fw, ) ivy.previous_backend() diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_comparison_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_comparison_ops.py index 9d1a64830280c..0227a3aa47a96 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_comparison_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_comparison_ops.py @@ -368,7 +368,7 @@ def test_torch_isfinite( @handle_frontend_test( fn_tree="torch.isin", dtype_and_inputs=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True, ), @@ -658,7 +658,7 @@ def test_torch_less_equal( @handle_frontend_test( fn_tree="torch.maximum", dtype_and_inputs=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True, ), @@ -688,7 +688,7 @@ def test_torch_maximum( @handle_frontend_test( fn_tree="torch.minimum", dtype_and_inputs=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, shared_dtype=True, ), diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_creation_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_creation_ops.py index 859ddfa5df3cf..136390818d19e 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_creation_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_creation_ops.py @@ -7,6 +7,7 @@ import ivy_tests.test_ivy.helpers as helpers import ivy_tests.test_ivy.helpers.globals as test_globals from ivy_tests.test_ivy.helpers import handle_frontend_test, BackendHandler +from ivy_tests.test_ivy.helpers.testing_helpers import handle_example # --- Helpers --- # @@ -611,6 +612,14 @@ def test_torch_heaviside( num=st.integers(min_value=1, max_value=10), dtype=helpers.get_dtypes("float", full=False), ) +@handle_example( + test_frontend_example=True, + start=np.array(0), + stop=1, + num=2, + dtype=[None], + fn_tree="ivy.functional.frontends.torch.linspace", +) def test_torch_linspace( *, start, @@ -624,7 +633,7 @@ def test_torch_linspace( backend_fw, ): helpers.test_frontend_function( - input_dtypes=[], + input_dtypes=[] if isinstance(start, float) else ["int64"], backend_to_test=backend_fw, frontend=frontend, test_flags=test_flags, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index 4923c2051c28b..f3e37cdf4efed 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -2,7 +2,7 @@ import math import sys import numpy as np -from hypothesis import strategies as st, assume +from hypothesis import strategies as st, assume, settings, HealthCheck # local import ivy @@ -270,6 +270,37 @@ def _vander_helper(draw): # ------------ # +@handle_frontend_test( + fn_tree="torch.linalg.lu_solve", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + shape=helpers.get_shape( + min_num_dims=2, max_num_dims=2, min_dim_size=2, max_dim_size=2 + ), + num_arrays=2, + shared_dtype=True, + ).filter(lambda x: helpers.matrix_is_stable(x[1][0], cond_limit=10)), +) +def test_lu_solve(dtype_x, test_flags, backend_fw, fn_name, on_device): + dtype, arr = dtype_x + A, B = arr[0], arr[1] + ivy.set_backend(backend_fw) + lu_ = ivy.lu_factor(A) + lu, p = lu_.LU, lu_.p + X, X_gt = helpers.test_frontend_function( + input_dtypes=dtype, + test_flags=test_flags, + on_device=on_device, + backend_to_test=backend_fw, + fn_name=fn_name, + lu=lu, + p=p, + b=B, + test_values=False, + ) + assert np.allclose(A @ X, B) + + @handle_frontend_test( fn_tree="torch.linalg.cholesky", aliases=["torch.cholesky"], @@ -424,6 +455,49 @@ def test_torch_det( ) +@handle_frontend_test( + fn_tree="torch.diag_embed", + dtype_and_values=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + shape=st.shared(helpers.get_shape(min_num_dims=1, max_num_dims=2), key="shape"), + ), + dims_and_offsets=helpers.dims_and_offset( + shape=st.shared(helpers.get_shape(min_num_dims=1, max_num_dims=2), key="shape"), + ensure_dim_unique=True, + ), +) +@settings(suppress_health_check=list(HealthCheck)) +def test_torch_diag_embed( + *, + dtype_and_values, + dims_and_offsets, + test_flags, + on_device, + fn_tree, + frontend, + backend_fw, +): + input_dtype, value = dtype_and_values + dim1, dim2, offset = dims_and_offsets + num_of_dims = len(np.shape(value[0])) + if dim1 < 0: + assume(dim1 + num_of_dims != dim2) + if dim2 < 0: + assume(dim1 != dim2 + num_of_dims) + helpers.test_frontend_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + test_flags=test_flags, + frontend=frontend, + fn_tree=fn_tree, + on_device=on_device, + input=value[0], + offset=offset, + dim1=dim1, + dim2=dim2, + ) + + # eig # TODO: Test for all valid dtypes once ivy.eig supports complex data types @handle_frontend_test( @@ -458,7 +532,7 @@ def test_torch_eig( ret = [ivy.to_numpy(x).astype("float64") for x in ret] frontend_ret = [np.asarray(x, dtype=np.float64) for x in frontend_ret] - l, v = ret + l, v = ret # noqa: E741 front_l, front_v = frontend_ret assert_all_close( @@ -467,6 +541,7 @@ def test_torch_eig( rtol=1e-2, atol=1e-2, ground_truth_backend=frontend, + backend=backend_fw, ) @@ -511,6 +586,7 @@ def test_torch_eigh( ret_np=Q @ np.diag(L) @ Q.T, ret_from_gt_np=frontend_Q @ np.diag(frontend_L) @ frontend_Q.T, atol=1e-02, + backend=backend_fw, ) @@ -581,6 +657,7 @@ def test_torch_eigvals( rtol=1e-2, atol=1e-2, ground_truth_backend=frontend, + backend=backend_fw, ) @@ -689,7 +766,43 @@ def test_torch_lu_factor( backend_fw, ): dtype, input = input_dtype_and_input - helpers.test_frontend_function( + ret = helpers.test_frontend_function( + input_dtypes=dtype, + backend_to_test=backend_fw, + test_flags=test_flags, + frontend=frontend, + fn_tree=fn_tree, + on_device=on_device, + rtol=1e-03, + atol=1e-02, + A=input[0], + test_values=False, + ) + ret_f, ret_gt = ret + LU, p = ret_f.LU, ret_f.p + L = np.tril(LU, -1) + np.eye(LU.shape[0]) + U = np.triu(LU) + P = np.eye(LU.shape[0])[p] + assert np.allclose(L @ U, P @ input[0]) + + +@handle_frontend_test( + fn_tree="torch.linalg.lu_factor_ex", + input_dtype_and_input=_get_dtype_and_matrix( + batch=True, square=True, invertible=True + ), +) +def test_torch_lu_factor_ex( + *, + input_dtype_and_input, + on_device, + fn_tree, + frontend, + test_flags, + backend_fw, +): + dtype, input = input_dtype_and_input + ret = helpers.test_frontend_function( input_dtypes=dtype, backend_to_test=backend_fw, test_flags=test_flags, @@ -699,7 +812,23 @@ def test_torch_lu_factor( rtol=1e-03, atol=1e-02, A=input[0], + check_errors=False, + test_values=False, ) + ret_f, ret_gt = ret + ret_f_matrix, ret_f_info = ret_f + if ret_f_info == 0: + ( + LU, + p, + ) = ( + ret_f_matrix.LU, + ret_f_matrix.p, + ) + L = np.tril(LU, -1) + np.eye(LU.shape[0]) + U = np.triu(LU) + P = np.eye(LU.shape[0])[p] + assert np.allclose(L @ U, P @ input[0]) @handle_frontend_test( @@ -770,32 +899,37 @@ def test_torch_matrix_exp( @handle_frontend_test( fn_tree="torch.linalg.matrix_norm", dtype_values_axis=helpers.dtype_values_axis( - available_dtypes=helpers.get_dtypes("valid"), + available_dtypes=helpers.get_dtypes("float_and_complex"), min_num_dims=2, min_axes_size=2, max_axes_size=2, - min_value=-1e04, - max_value=1e04, + max_value=10e4, + min_value=-10e4, + abs_smallest_val=10e-4, valid_axis=True, force_tuple_axis=True, ), ord=st.sampled_from(["fro", "nuc", np.inf, -np.inf, 1, -1, 2, -2]), keepdim=st.booleans(), - dtype=helpers.get_dtypes("valid", none=True, full=False), + dtypes=helpers.get_dtypes("float_and_complex", none=True, full=False), ) def test_torch_matrix_norm( *, dtype_values_axis, ord, keepdim, - dtype, frontend, + dtypes, test_flags, fn_tree, backend_fw, on_device, ): input_dtype, x, axis = dtype_values_axis + if dtypes[0] is not None and "complex128" in input_dtype[0]: + dtypes[0] = input_dtype[0] + if dtypes[0] is not None: + dtypes[0] = input_dtype[0][:-2] + max([input_dtype[0][-2:], dtypes[0][-2:]]) helpers.test_frontend_function( input_dtypes=input_dtype, @@ -810,7 +944,7 @@ def test_torch_matrix_norm( ord=ord, dim=axis, keepdim=keepdim, - dtype=dtype[0], + dtype=dtypes[0], ) @@ -1001,6 +1135,7 @@ def test_torch_qr( rtol=1e-2, atol=1e-2, ground_truth_backend=frontend, + backend=backend_fw, ) ivy.previous_backend() @@ -1150,6 +1285,7 @@ def test_torch_svd( rtol=1e-2, atol=1e-2, ground_truth_backend=frontend, + backend=backend_fw, ) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_miscellaneous_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_miscellaneous_ops.py index 340fe6bed6930..90fb791284ad3 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_miscellaneous_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_miscellaneous_ops.py @@ -8,6 +8,7 @@ # local import ivy import ivy_tests.test_ivy.helpers as helpers +from ivy_tests.test_ivy.helpers.hypothesis_helpers.general_helpers import sizes_ from ivy_tests.test_ivy.helpers import handle_frontend_test from ivy_tests.test_ivy.test_functional.test_core.test_linalg import ( _get_dtype_value1_value2_axis_for_tensordot, @@ -190,17 +191,6 @@ def complex_strategy( return tuple(shape) -@st.composite -def dims_and_offset(draw, shape): - shape_actual = draw(shape) - dim1 = draw(helpers.get_axis(shape=shape, force_int=True)) - dim2 = draw(helpers.get_axis(shape=shape, force_int=True)) - offset = draw( - st.integers(min_value=-shape_actual[dim1], max_value=shape_actual[dim1]) - ) - return dim1, dim2, offset - - # cross @st.composite def dtype_value1_value2_axis( @@ -510,6 +500,50 @@ def test_torch_cartesian_prod( ) +@handle_frontend_test( + fn_tree="torch.cdist", + dtypes_and_x=helpers.dtype_and_values( + shape=st.shared(helpers.get_shape(min_num_dims=2, max_num_dims=3), key="shape"), + shared_dtype=True, + num_arrays=2, + allow_inf=False, + available_dtypes=["float32", "float64"], + ), + p=st.integers(min_value=0, max_value=1000000), + compute_mode=st.sampled_from( + [ + "use_mm_for_euclid_dist_if_necessary", + "use_mm_for_euclid_dist", + "donot_use_mm_for_euclid_dist", + ] + ), +) +def test_torch_cdist( + *, + dtypes_and_x, + p, + compute_mode, + on_device, + fn_tree, + frontend, + test_flags, + backend_fw, +): + input_dtypes, xs = dtypes_and_x + helpers.test_frontend_function( + input_dtypes=input_dtypes, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + x1=xs[0], + x2=xs[1], + p=p, + compute_mode=compute_mode, + ) + + # clone @handle_frontend_test( fn_tree="torch.clone", @@ -543,7 +577,7 @@ def test_torch_clone( @handle_frontend_test( fn_tree="torch.corrcoef", dtypes_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), num_arrays=1, min_num_dims=2, max_num_dims=2, @@ -563,7 +597,7 @@ def test_torch_corrcoef( ): input_dtypes, x = dtypes_and_x helpers.test_frontend_function( - input_dtypes=["float64"], + input_dtypes=input_dtypes, frontend=frontend, fn_tree=fn_tree, test_flags=test_flags, @@ -855,7 +889,7 @@ def test_torch_diagflat( available_dtypes=helpers.get_dtypes("float"), shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape"), ), - dims_and_offset=dims_and_offset( + dims_and_offset=helpers.dims_and_offset( shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape") ), ) @@ -973,6 +1007,38 @@ def test_torch_einsum( ) +# erfinv +@handle_frontend_test( + fn_tree="torch.special.erfinv", + aliases=["torch.erfinv"], + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + min_value=-1, + max_value=1, + abs_smallest_val=1e-05, + ), +) +def test_torch_erfinv( + *, + dtype_and_x, + on_device, + fn_tree, + frontend, + test_flags, + backend_fw, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + input=x[0], + ) + + @handle_frontend_test( fn_tree="torch.flatten", dtype_input_axes=helpers.dtype_values_axis( @@ -1502,10 +1568,10 @@ def test_torch_rot90( max_num_dims=1, num_arrays=2, ), - side=st.sampled_from(["left", "right"]), + side=st.sampled_from(["left", "right", None]), out_int32=st.booleans(), - right=st.just(False), - test_with_out=st.just(False), + right=st.sampled_from([True, False, None]), + test_with_out=st.booleans(), ) def test_torch_searchsorted( dtype_x_v, @@ -1518,6 +1584,13 @@ def test_torch_searchsorted( backend_fw, on_device, ): + potential_kwargs = {} + if side == "left" and right: + right = None # this combo will cause an exception + if side is not None: + potential_kwargs["side"] = side + if right is not None: + potential_kwargs["right"] = right input_dtypes, xs = dtype_x_v use_sorter = st.booleans() if use_sorter: @@ -1535,10 +1608,9 @@ def test_torch_searchsorted( on_device=on_device, sorted_sequence=xs[0], values=xs[1], - side=side, out_int32=out_int32, - right=right, sorter=sorter, + **potential_kwargs, ) @@ -1733,6 +1805,47 @@ def test_torch_triu_indices( ) +# unflatten +@handle_frontend_test( + fn_tree="torch.unflatten", + shape=st.shared(helpers.get_shape(min_num_dims=1), key="shape"), + dtype_and_values=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + min_num_dims=1, + shape_key="shape", + ), + axis=helpers.get_axis( + shape=st.shared(helpers.get_shape(min_num_dims=1), key="shape"), + force_int=True, + ), +) +def test_torch_unflatten( + *, + dtype_and_values, + on_device, + fn_tree, + frontend, + test_flags, + backend_fw, + shape, + axis, +): + dtype, x = dtype_and_values + sizes = sizes_(shape, axis) + helpers.test_frontend_function( + input_dtypes=dtype, + frontend=frontend, + backend_to_test=backend_fw, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + test_values=False, + input=x[0], + dim=axis, + sizes=sizes, + ) + + # vander @handle_frontend_test( fn_tree="torch.vander", diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_layer_functions.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_layer_functions.py index 1395d00bb080b..453026fad8ea9 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_layer_functions.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_layer_functions.py @@ -4,10 +4,7 @@ # local import ivy -from ivy.functional.ivy.layers import _get_embed_dim -from ivy.functional.frontends.torch.nn.functional.layer_functions import ( - _pack_padded_sequence, -) +from ivy.functional.ivy.layers import _get_embed_dim, _pack_padded_sequence from ivy_tests.test_ivy import helpers from ivy_tests.test_ivy.helpers import handle_frontend_test from ivy_tests.test_ivy.test_functional.test_nn.test_layers import _mha_helper @@ -178,7 +175,7 @@ def test_torch_lstm( ): dtypes, kwargs = dtypes_kwargs # Todo: Debug the function to have this case passing as well - assume("batch_sizes" not in kwargs or not kwargs["bidirectional"]) + assume("batch_sizes" not in kwargs) helpers.test_frontend_function( input_dtypes=dtypes, backend_to_test=backend_fw, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_non_linear_activation_functions.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_non_linear_activation_functions.py index 953e6865a11c7..162ef1b2e73b6 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_non_linear_activation_functions.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_non_linear_activation_functions.py @@ -649,7 +649,6 @@ def test_torch_log_softmax( backend_fw, ): input_dtype, x, axis = dtype_x_and_axis - ivy.set_backend(backend_fw) helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -660,9 +659,8 @@ def test_torch_log_softmax( input=x[0], dim=axis, _stacklevel=3, - dtype=ivy.as_ivy_dtype(dtypes[0]), + dtype=dtypes[0], ) - ivy.previous_backend() # logsigmoid diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py index 7abe0b623de58..27091c4ca9bba 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_pooling_functions.py @@ -160,6 +160,49 @@ def test_torch_adaptive_max_pool2d( ) +@handle_frontend_test( + fn_tree="torch.nn.functional.adaptive_max_pool3d", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + min_num_dims=4, + max_num_dims=5, + min_dim_size=2, + max_value=100, + min_value=-100, + ), + output_size=st.one_of( + st.tuples( + helpers.ints(min_value=1, max_value=5), + helpers.ints(min_value=1, max_value=5), + helpers.ints(min_value=1, max_value=5), + ), + helpers.ints(min_value=1, max_value=5), + ), + test_with_out=st.just(False), +) +def test_torch_adaptive_max_pool3d( + *, + dtype_and_x, + output_size, + on_device, + frontend, + test_flags, + fn_tree, + backend_fw, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + input=x[0], + output_size=output_size, + ) + + # avg_pool1d @handle_frontend_test( fn_tree="torch.nn.functional.avg_pool1d", diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_vision_functions.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_vision_functions.py index 912c3e82599be..58c58e87939ac 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_vision_functions.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_nn/test_functional/test_vision_functions.py @@ -106,7 +106,7 @@ def _pad_helper(draw): ) padding = draw(_pad_generator(shape, mode)) if mode == "constant": - value = draw(helpers.ints(min_value=0, max_value=4)) + value = draw(helpers.ints(min_value=0, max_value=4) | st.none()) else: value = 0.0 return dtype, input[0], padding, value, mode diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_pointwise_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_pointwise_ops.py index 0e7744ac41a41..52c15b10bd760 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_pointwise_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_pointwise_ops.py @@ -9,7 +9,6 @@ two_broadcastable_shapes, ) from ivy_tests.test_ivy.helpers import handle_frontend_test -from ivy_tests.test_ivy.test_functional.test_core.test_elementwise import pow_helper # --- Helpers --- # @@ -1182,7 +1181,8 @@ def test_torch_erf( # erfc @handle_frontend_test( - fn_tree="torch.erfc", + fn_tree="torch.special.erfc", + aliases=["torch.erfc"], dtype_and_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("float"), ), @@ -1212,7 +1212,7 @@ def test_torch_erfc( @handle_frontend_test( fn_tree="torch.exp", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), ), ) def test_torch_exp( @@ -2325,7 +2325,13 @@ def test_torch_positive( @handle_frontend_test( fn_tree="torch.pow", - dtype_and_x=pow_helper(), + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + num_arrays=2, + min_value=1, + max_value=7, + shared_dtype=True, + ), ) def test_torch_pow( dtype_and_x, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_random_sampling.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_random_sampling.py index 2b54f57e84078..9c9cd0341e71c 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_random_sampling.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_random_sampling.py @@ -538,7 +538,7 @@ def call(): @handle_frontend_test( fn_tree="torch.set_rng_state", new_state=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("uint8"), + available_dtypes=helpers.get_dtypes("valid"), min_value=0, max_value=10, min_num_dims=1, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_reduction_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_reduction_ops.py index 9d3f52db9a672..55e9ed5fd0eda 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_reduction_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_reduction_ops.py @@ -106,7 +106,7 @@ def test_torch_all( @handle_frontend_test( fn_tree="torch.amax", dtype_input_axis=helpers.dtype_values_axis( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("valid"), min_num_dims=1, min_axis=-1, max_axis=0, @@ -140,7 +140,7 @@ def test_torch_amax( @handle_frontend_test( fn_tree="torch.amin", dtype_input_axis=helpers.dtype_values_axis( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("valid"), min_num_dims=1, min_axis=-1, max_axis=0, @@ -174,7 +174,7 @@ def test_torch_amin( @handle_frontend_test( fn_tree="torch.aminmax", dtype_input_axis=helpers.dtype_values_axis( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("valid"), min_num_dims=1, min_axis=-1, max_axis=0, @@ -209,6 +209,9 @@ def test_torch_aminmax( fn_tree="torch.any", dtype_input_axis=helpers.dtype_values_axis( available_dtypes=helpers.get_dtypes("valid"), + safety_factor_scale="log", + small_abs_safety_factor=8, + large_abs_safety_factor=8, min_axis=-1, max_axis=0, min_num_dims=1, @@ -476,7 +479,7 @@ def test_torch_mean( test_flags, backend_fw, ): - input_dtype, x, axis = dtype_and_x + input_dtype, x, axis, *_ = dtype_and_x helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -495,7 +498,7 @@ def test_torch_mean( @handle_frontend_test( fn_tree="torch.median", dtype_input_axis=helpers.dtype_values_axis( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("valid"), min_num_dims=1, valid_axis=True, force_int_axis=True, @@ -656,7 +659,7 @@ def test_torch_nanmean( test_flags, backend_fw, ): - input_dtype, x, axis = dtype_and_x + input_dtype, x, axis, *_ = dtype_and_x helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -760,14 +763,14 @@ def test_torch_norm( helpers.test_frontend_function( backend_to_test=backend_fw, - input_dtypes=[x_dtype], + input_dtypes=x_dtype, frontend=frontend, test_flags=test_flags, fn_tree=fn_tree, on_device=on_device, rtol=1e-01, atol=1e-08, - input=x, + input=x[0], p=p, dim=axis, keepdim=keepdim, @@ -843,6 +846,8 @@ def test_torch_quantile( input_dtype, x, axis, interpolation, q = dtype_and_x if type(axis) is tuple: axis = axis[0] + if interpolation == "nearest_jax": + interpolation = "nearest" helpers.test_frontend_function( input_dtypes=input_dtype, backend_to_test=backend_fw, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_special_funcs.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_special_funcs.py new file mode 100644 index 0000000000000..56bac4271b7bb --- /dev/null +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_special_funcs.py @@ -0,0 +1,30 @@ +# local +import ivy_tests.test_ivy.helpers as helpers +from ivy_tests.test_ivy.helpers import handle_frontend_test + + +@handle_frontend_test( + fn_tree="torch.special.erfcx", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + ), +) +def test_torch_erfcx( + *, + dtype_and_x, + on_device, + fn_tree, + frontend, + test_flags, + backend_fw, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + input=x[0], + ) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py index e79b86ece43f4..26e8c5ece6238 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py @@ -21,6 +21,7 @@ # local import ivy_tests.test_ivy.helpers as helpers +from ivy_tests.test_ivy.helpers.hypothesis_helpers.general_helpers import sizes_ from ivy_tests.test_ivy.test_frontends.test_torch.test_blas_and_lapack_ops import ( _get_dtype_and_3dbatch_matrices, _get_dtype_input_and_matrices, @@ -351,11 +352,12 @@ def _repeat_helper(draw): @st.composite -def _requires_grad(draw): - dtype = draw(_dtypes())[0] +def _requires_grad_and_dtypes(draw): + dtypes = draw(_dtypes()) + dtype = dtypes[0] if ivy.is_int_dtype(dtype) or ivy.is_uint_dtype(dtype): - return draw(st.just(False)) - return draw(st.booleans()) + return draw(st.just(False)), dtypes + return draw(st.booleans()), dtypes @st.composite @@ -415,18 +417,6 @@ def _unfold_args(draw): return values_dtype, values, axis, size, step -# diagonal -@st.composite -def dims_and_offset(draw, shape): - shape_actual = draw(shape) - dim1 = draw(helpers.get_axis(shape=shape, force_int=True)) - dim2 = draw(helpers.get_axis(shape=shape, force_int=True)) - offset = draw( - st.integers(min_value=-shape_actual[dim1], max_value=shape_actual[dim1]) - ) - return dim1, dim2, offset - - # --- Main --- # # ------------ # @@ -513,6 +503,37 @@ def test_torch___and__( ) +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="torch.tensor", + method_name="__array__", + dtype_and_x=helpers.dtype_and_values(available_dtypes=helpers.get_dtypes("valid")), + dtype=helpers.get_dtypes("valid", full=False), +) +def test_torch___array__( + dtype_and_x, + dtype, + frontend, + backend_fw, +): + input_dtype, x = dtype_and_x + if x[0].dtype == "bfloat16": + return + dtype[0] = np.dtype(dtype[0]) + ret_gt = torch.tensor(x[0]).__array__(dtype[0]) + with BackendHandler.update_backend(backend_fw) as ivy_backend: + local_importer = ivy_backend.utils.dynamic_import + function_module = local_importer.import_module("ivy.functional.frontends.torch") + ret = function_module.tensor(x[0]).__array__(dtype[0]) + + helpers.value_test( + ret_np_flat=ret.ravel(), + ret_np_from_gt_flat=ret_gt.ravel(), + ground_truth_backend="torch", + backend=backend_fw, + ) + + @handle_frontend_method( class_tree=CLASS_TREE, init_tree="torch.tensor", @@ -745,6 +766,47 @@ def test_torch___gt__( raise +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="torch.tensor", + method_name="__iand__", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=st.one_of(st.just(("bool",)), helpers.get_dtypes("integer")), + num_arrays=2, + min_value=-1e04, + max_value=1e04, + allow_inf=False, + ), + test_inplace=st.just(True), +) +def test_torch___iand__( + dtype_and_x, + frontend_method_data, + init_flags, + method_flags, + frontend, + on_device, + backend_fw, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "other": x[1], + }, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # __invert__ @handle_frontend_method( class_tree=CLASS_TREE, @@ -1177,7 +1239,7 @@ def test_torch___radd__( init_tree="torch.tensor", method_name="__rmul__", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2, min_value=-1e04, max_value=1e04, @@ -1409,37 +1471,6 @@ def test_torch___truediv__( ) -@handle_frontend_method( - class_tree=CLASS_TREE, - init_tree="torch.tensor", - method_name="__array__", - dtype_and_x=helpers.dtype_and_values(available_dtypes=helpers.get_dtypes("valid")), - dtype=helpers.get_dtypes("valid", full=False), -) -def test_torch__array__( - dtype_and_x, - dtype, - frontend, - backend_fw, -): - input_dtype, x = dtype_and_x - if x[0].dtype == "bfloat16": - return - dtype[0] = np.dtype(dtype[0]) - ret_gt = torch.tensor(x[0]).__array__(dtype[0]) - with BackendHandler.update_backend(backend_fw) as ivy_backend: - local_importer = ivy_backend.utils.dynamic_import - function_module = local_importer.import_module("ivy.functional.frontends.torch") - ret = function_module.tensor(x[0]).__array__(dtype[0]) - - helpers.value_test( - ret_np_flat=ret.ravel(), - ret_np_from_gt_flat=ret_gt.ravel(), - ground_truth_backend="torch", - backend=backend_fw, - ) - - @given( dtype_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("valid", prune_function=False), @@ -4870,6 +4901,41 @@ def test_torch_clamp_min( ) +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="torch.tensor", + method_name="clamp_min_", + input_and_ranges=_get_clip_min_inputs(), + test_inplace=st.just(True), +) +def test_torch_clamp_min_( + input_and_ranges, + frontend_method_data, + init_flags, + backend_fw, + frontend, + on_device, + method_flags, +): + x_dtype, x, min = input_and_ranges + helpers.test_frontend_method( + init_input_dtypes=x_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=x_dtype, + method_all_as_kwargs_np={ + "min": min, + }, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # clip @handle_frontend_method( class_tree=CLASS_TREE, @@ -5820,7 +5886,7 @@ def test_torch_diag( available_dtypes=helpers.get_dtypes("valid"), shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape"), ), - dims_and_offset=dims_and_offset( + dims_and_offset=helpers.dims_and_offset( shape=st.shared(helpers.get_shape(min_num_dims=2), key="shape") ), ) @@ -6374,6 +6440,83 @@ def test_torch_erf_( ) +# erfinv_ tests +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="torch.tensor", + method_name="erfinv_", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + min_value=-1, + max_value=1, + abs_smallest_val=1e-05, + ), +) +def test_torch_erfinv( + dtype_and_x, + frontend_method_data, + init_flags, + method_flags, + frontend, + on_device, + backend_fw, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={}, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + +# erfinv_ tests +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="torch.tensor", + method_name="erfinv_", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + min_value=-1, + max_value=1, + abs_smallest_val=1e-05, + ), + test_inplace=st.just(True), +) +def test_torch_erfinv_( + dtype_and_x, + frontend_method_data, + init_flags, + method_flags, + frontend, + on_device, + backend_fw, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={}, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # exp @handle_frontend_method( class_tree=CLASS_TREE, @@ -6463,6 +6606,13 @@ def test_torch_expand( backend_fw, ): input_dtype, x, shape = dtype_x_shape + + if backend_fw == "paddle": + assume( + input_dtype[0] in ["int32", "int64", "float32", "float64", "bool"] + and len(shape) < 7 + ) + if unpack_shape: method_flags.num_positional_args = len(shape) + 1 size = {} @@ -8039,6 +8189,44 @@ def test_torch_is_quantized( ivy.previous_backend() +# isfinite +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="torch.tensor", + method_name="isfinite", + dtype_and_input=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + min_value=-np.inf, + max_value=np.inf, + ), +) +def test_torch_isfinite( + *, + dtype_and_input, + on_device, + frontend, + backend_fw, + frontend_method_data, + init_flags, + method_flags, +): + input_dtype, x = dtype_and_input + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={}, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # isinf @handle_frontend_method( class_tree=CLASS_TREE, @@ -8704,6 +8892,51 @@ def test_torch_log_( ) +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="torch.tensor", + method_name="log_softmax", + dtype_x_and_axis=helpers.dtype_values_axis( + available_dtypes=helpers.get_dtypes("float"), + min_num_dims=1, + max_axes_size=1, + force_int_axis=True, + valid_axis=True, + ), + dtypes=helpers.get_dtypes("float", none=False, full=False), +) +def test_torch_log_softmax( + *, + dtype_x_and_axis, + dtypes, + on_device, + frontend, + backend_fw, + frontend_method_data, + init_flags, + method_flags, +): + input_dtype, x, axis = dtype_x_and_axis + + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "dim": axis, + "dtype": dtypes[0], + }, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # logaddexp @handle_frontend_method( class_tree=CLASS_TREE, @@ -10036,6 +10269,39 @@ def test_torch_negative( ) +# new +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="torch.tensor", + method_name="new", + dtype_and_x=helpers.dtype_and_values(), +) +def test_torch_new_( + dtype_and_x, + frontend_method_data, + init_flags, + method_flags, + frontend, + on_device, + backend_fw, +): + input_dtype, x = dtype_and_x + helpers.test_frontend_method( + init_input_dtypes=input_dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={}, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # new_empty (not actually intuitive for testing) @handle_frontend_method( class_tree=CLASS_TREE, @@ -10127,14 +10393,12 @@ def test_torch_new_full( min_dim_size=1, max_dim_size=10, ), - dtypes=_dtypes(), - requires_grad=_requires_grad(), + requires_grad_and_dtypes=_requires_grad_and_dtypes(), ) def test_torch_new_ones( dtype_and_x, size, - dtypes, - requires_grad, + requires_grad_and_dtypes, on_device, frontend_method_data, init_flags, @@ -10143,6 +10407,7 @@ def test_torch_new_ones( backend_fw, ): input_dtype, x = dtype_and_x + requires_grad, dtypes = requires_grad_and_dtypes helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -10216,14 +10481,12 @@ def test_torch_new_tensor( min_dim_size=1, max_dim_size=10, ), - dtypes=_dtypes(), - requires_grad=_requires_grad(), + requires_grad_and_dtypes=_requires_grad_and_dtypes(), ) def test_torch_new_zeros( dtype_and_x, size, - dtypes, - requires_grad, + requires_grad_and_dtypes, on_device, frontend_method_data, init_flags, @@ -10232,6 +10495,7 @@ def test_torch_new_zeros( backend_fw, ): input_dtype, x = dtype_and_x + requires_grad, dtypes = requires_grad_and_dtypes helpers.test_frontend_method( init_input_dtypes=input_dtype, backend_to_test=backend_fw, @@ -10377,8 +10641,8 @@ def call(): return ret_np, ret_from_np = ret - ret_np = helpers.flatten_and_to_np(ret=ret_np) - ret_from_np = helpers.flatten_and_to_np(ret=ret_from_np) + ret_np = helpers.flatten_and_to_np(ret=ret_np, backend=backend_fw) + ret_from_np = helpers.flatten_and_to_np(ret=ret_from_np, backend=backend_fw) for u, v in zip(ret_np, ret_from_np): assert u.dtype == v.dtype assert u.shape == v.shape @@ -10503,9 +10767,10 @@ def test_torch_numpy( ) # manual testing required as function return is numpy frontend helpers.value_test( - ret_np_flat=helpers.flatten_and_to_np(ret=ret), + ret_np_flat=helpers.flatten_and_to_np(ret=ret, backend=backend_fw), ret_np_from_gt_flat=frontend_ret[0], ground_truth_backend="torch", + backend=backend_fw, ) @@ -13715,6 +13980,54 @@ def test_torch_unbind( ) +@handle_frontend_method( + class_tree=CLASS_TREE, + init_tree="torch.tensor", + method_name="unflatten", + shape=st.shared(helpers.get_shape(min_num_dims=1), key="shape"), + dtype_and_values=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + min_num_dims=1, + shape_key="shape", + ), + axis=helpers.get_axis( + shape=st.shared(helpers.get_shape(min_num_dims=1), key="shape"), + force_int=True, + ), +) +def test_torch_unflatten( + *, + dtype_and_values, + on_device, + frontend, + backend_fw, + shape, + axis, + frontend_method_data, + init_flags, + method_flags, +): + dtype, x = dtype_and_values + sizes = sizes_(shape, axis) + helpers.test_frontend_method( + init_input_dtypes=dtype, + backend_to_test=backend_fw, + init_all_as_kwargs_np={ + "data": x[0], + }, + method_input_dtypes=dtype, + method_all_as_kwargs_np={ + "dim": axis, + "sizes": sizes, + }, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, + frontend=frontend, + on_device=on_device, + ) + + # unfold @handle_frontend_method( class_tree=CLASS_TREE, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor_functions.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor_functions.py index 920ffe8a46ce3..9f4632ec3bddc 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor_functions.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor_functions.py @@ -10,6 +10,40 @@ ) +# broadcast_tensors +@handle_frontend_test( + fn_tree="torch.broadcast_tensors", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + min_num_dims=1, + num_arrays=helpers.ints(min_value=2, max_value=5), + ), +) +def test_torch_broadcast_tensors( + *, + dtype_and_x, + on_device, + fn_tree, + frontend, + test_flags, + backend_fw, +): + input_dtype, x = dtype_and_x + kw = {} + for i, array in enumerate(x): + kw[f"x{i}"] = array + test_flags.num_positional_args = len(kw) + helpers.test_frontend_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + on_device=on_device, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + **kw, + ) + + @handle_frontend_test( fn_tree="torch.is_complex", dtype_and_x=helpers.dtype_and_values( diff --git a/ivy_tests/test_ivy/test_frontends/test_torchvision/test_ops.py b/ivy_tests/test_ivy/test_frontends/test_torchvision/test_ops.py index 919c05a30274f..70510ca8f8829 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torchvision/test_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torchvision/test_ops.py @@ -148,6 +148,36 @@ def test_torchvision_box_area( ) +@handle_frontend_test( + fn_tree="torchvision.ops.box_iou", + boxes=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + shape=st.tuples(helpers.ints(min_value=1, max_value=5), st.just(4)), + num_arrays=2, + ), +) +def test_torchvision_box_iou( + *, + boxes, + on_device, + fn_tree, + frontend, + test_flags, + backend_fw, +): + dtype, boxes = boxes + helpers.test_frontend_function( + input_dtypes=dtype, + backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, + on_device=on_device, + boxes1=boxes[0], + boxes2=boxes[1], + ) + + @handle_frontend_test( fn_tree="torchvision.ops.clip_boxes_to_image", boxes=helpers.dtype_and_values( diff --git a/ivy_tests/test_ivy/test_functional/test_core/test_creation.py b/ivy_tests/test_ivy/test_functional/test_core/test_creation.py index 99a105e454651..e13e0836f24eb 100644 --- a/ivy_tests/test_ivy/test_functional/test_core/test_creation.py +++ b/ivy_tests/test_ivy/test_functional/test_core/test_creation.py @@ -848,6 +848,7 @@ def test_zeros(*, shape, dtype, test_flags, backend_fw, fn_name, on_device): min_dim_size=1, max_dim_size=5, ), + test_gradients=st.just(False), ) def test_zeros_like(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): dtype, x = dtype_and_x diff --git a/ivy_tests/test_ivy/test_functional/test_core/test_device.py b/ivy_tests/test_ivy/test_functional/test_core/test_device.py index 8145e909d85ad..05300aa6cd446 100644 --- a/ivy_tests/test_ivy/test_functional/test_core/test_device.py +++ b/ivy_tests/test_ivy/test_functional/test_core/test_device.py @@ -372,7 +372,7 @@ def test_num_cpu_cores(backend_fw): # using multiprocessing module too because ivy uses psutil as basis. p_cpu_cores = psutil.cpu_count() m_cpu_cores = multiprocessing.cpu_count() - assert type(ivy_backend.num_cpu_cores()) == int + assert isinstance(ivy_backend.num_cpu_cores(), int) assert ivy_backend.num_cpu_cores() == p_cpu_cores assert ivy_backend.num_cpu_cores() == m_cpu_cores diff --git a/ivy_tests/test_ivy/test_functional/test_core/test_elementwise.py b/ivy_tests/test_ivy/test_functional/test_core/test_elementwise.py index 89071dec7917e..5e2dc42aa3322 100644 --- a/ivy_tests/test_ivy/test_functional/test_core/test_elementwise.py +++ b/ivy_tests/test_ivy/test_functional/test_core/test_elementwise.py @@ -2,15 +2,17 @@ # global import math + import numpy as np -from hypothesis import assume, strategies as st +from hypothesis import assume +from hypothesis import strategies as st # local import ivy import ivy_tests.test_ivy.helpers as helpers +import ivy_tests.test_ivy.helpers.globals as test_globals from ivy_tests.test_ivy.helpers import handle_test from ivy_tests.test_ivy.helpers.pipeline_helper import BackendHandler -import ivy_tests.test_ivy.helpers.globals as test_globals _one = np.asarray(1, dtype="uint8") _zero = np.asarray(0, dtype="uint8") @@ -67,7 +69,7 @@ def min_max_helper(draw): if use_where: dtype_and_x = draw( helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("numeric", full=False), num_arrays=2, small_abs_safety_factor=6, large_abs_safety_factor=6, @@ -77,10 +79,12 @@ def min_max_helper(draw): else: dtype_and_x = draw( helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("numeric", full=False), num_arrays=2, min_value=-1e5, max_value=1e5, + small_abs_safety_factor=6, + large_abs_safety_factor=6, safety_factor_scale="log", ) ) @@ -180,6 +184,7 @@ def test_abs(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): available_dtypes=helpers.get_dtypes("float_and_complex"), large_abs_safety_factor=4, small_abs_safety_factor=4, + safety_factor_scale="log", ), ) def test_acos(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): @@ -293,6 +298,7 @@ def test_angle( fn_tree="functional.ivy.asin", dtype_and_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("float_and_complex"), + safety_factor_scale="log", large_abs_safety_factor=4, small_abs_safety_factor=4, ), @@ -318,6 +324,7 @@ def test_asin(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): available_dtypes=helpers.get_dtypes("float_and_complex"), large_abs_safety_factor=4, small_abs_safety_factor=4, + safety_factor_scale="log", ), ) def test_asinh(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): @@ -339,8 +346,8 @@ def test_asinh(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): fn_tree="functional.ivy.atan", dtype_and_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("float_and_complex"), - large_abs_safety_factor=2, - small_abs_safety_factor=2, + large_abs_safety_factor=4, + small_abs_safety_factor=4, safety_factor_scale="log", ), ) @@ -390,7 +397,9 @@ def test_atan2(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): @handle_test( fn_tree="functional.ivy.atanh", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float_and_complex") + min_value=1e-30, + max_value=1e30, + available_dtypes=helpers.get_dtypes("float_and_complex"), ), ) def test_atanh(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): @@ -633,7 +642,10 @@ def test_cosh(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): @handle_test( fn_tree="functional.ivy.deg2rad", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric") + available_dtypes=helpers.get_dtypes("valid"), + safety_factor_scale="log", + large_abs_safety_factor=2, + small_abs_safety_factor=2, ), ) def test_deg2rad(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): @@ -644,6 +656,8 @@ def test_deg2rad(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): backend_to_test=backend_fw, fn_name=fn_name, on_device=on_device, + atol_=1e-2, + rtol_=1e-2, x=x[0], ) @@ -651,8 +665,9 @@ def test_deg2rad(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): # divide @handle_test( fn_tree="functional.ivy.divide", + test_gradients=st.just(False), dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("numeric", full=False), num_arrays=2, large_abs_safety_factor=2, small_abs_safety_factor=2, @@ -679,7 +694,7 @@ def test_divide(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): @handle_test( fn_tree="functional.ivy.equal", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("valid", full=True), num_arrays=2 + available_dtypes=helpers.get_dtypes("valid", full=False), num_arrays=2 ), test_gradients=st.just(False), ) @@ -819,6 +834,7 @@ def test_floor(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): safety_factor_scale="linear", shared_dtype=True, ), + test_gradients=st.just(False), ) def test_floor_divide(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): input_dtype, x = dtype_and_x @@ -992,6 +1008,7 @@ def test_greater_equal(*, dtype_and_x, test_flags, backend_fw, fn_name, on_devic allow_nan=False, ), test_gradients=st.just(False), + test_instance_method=st.just(False), ) def test_imag( *, @@ -1167,6 +1184,7 @@ def test_less(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2 ), test_gradients=st.just(False), + ground_truth_backend="jax", ) def test_less_equal(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): input_dtype, x = dtype_and_x @@ -1422,6 +1440,8 @@ def test_logical_xor(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device) @handle_test( fn_tree="functional.ivy.maximum", dtype_and_x_and_use_where=min_max_helper(), + test_gradients=st.just(False), + ground_truth_backend="jax", ) def test_maximum( *, dtype_and_x_and_use_where, test_flags, backend_fw, fn_name, on_device @@ -1445,6 +1465,8 @@ def test_maximum( @handle_test( fn_tree="functional.ivy.minimum", dtype_and_x_and_use_where=min_max_helper(), + test_gradients=st.just(False), + ground_truth_backend="jax", ) def test_minimum( *, dtype_and_x_and_use_where, test_flags, backend_fw, fn_name, on_device @@ -1468,8 +1490,9 @@ def test_minimum( @handle_test( fn_tree="functional.ivy.multiply", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), num_arrays=2 + available_dtypes=helpers.get_dtypes("valid"), num_arrays=2 ), + ground_truth_backend="torch", ) def test_multiply(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): input_dtype, x = dtype_and_x @@ -1624,9 +1647,7 @@ def test_pow(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): @handle_test( fn_tree="functional.ivy.rad2deg", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric") - ), + dtype_and_x=helpers.dtype_and_values(available_dtypes=helpers.get_dtypes("valid")), ) def test_rad2deg(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): input_dtype, x = dtype_and_x @@ -1634,6 +1655,8 @@ def test_rad2deg(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): input_dtypes=input_dtype, test_flags=test_flags, backend_to_test=backend_fw, + rtol_=1e-2, + atol_=1e-2, fn_name=fn_name, on_device=on_device, x=x[0], diff --git a/ivy_tests/test_ivy/test_functional/test_core/test_general.py b/ivy_tests/test_ivy/test_functional/test_core/test_general.py index 951c1d05e804c..ebeecffba73dc 100644 --- a/ivy_tests/test_ivy/test_functional/test_core/test_general.py +++ b/ivy_tests/test_ivy/test_functional/test_core/test_general.py @@ -15,7 +15,11 @@ import ivy import ivy_tests.test_ivy.helpers as helpers -from ivy_tests.test_ivy.helpers import handle_test, BackendHandler +from ivy_tests.test_ivy.helpers import ( + handle_test, + BackendHandler, + handle_example, +) from ivy_tests.test_ivy.helpers.assertions import assert_all_close from ivy_tests.test_ivy.test_functional.test_core.test_elementwise import pow_helper @@ -1289,7 +1293,7 @@ def test_inplace_increment(x_val_and_dtypes, test_flags, on_device, backend_fw): shared_dtype=True, ), keep_x_dtype=st.booleans(), - inplace_mode=st.sampled_from(["lenient", "strict"]), + inplace_mode=st.just("lenient"), ) def test_inplace_update( x_val_and_dtypes, keep_x_dtype, inplace_mode, test_flags, on_device, backend_fw @@ -1643,6 +1647,20 @@ def test_set_inplace_mode(mode): container_flags=st.just([False]), test_with_copy=st.just(True), ) +@handle_example( + test_example=True, + test_flags={ + "num_positional_args": 3, + }, + dtypes_x_query_val=( + ["int32", "int32"], + np.ones((1, 3, 3, 3)), + (slice(None, None, None), slice(None, None, None), slice(None, None, None), 1), + np.zeros((3, 1)), + ), + copy=False, + fn_name="set_item", +) def test_set_item( dtypes_x_query_val, copy, diff --git a/ivy_tests/test_ivy/test_functional/test_core/test_searching.py b/ivy_tests/test_ivy/test_functional/test_core/test_searching.py index 425c78805d9bb..1edb5f5a6f60c 100644 --- a/ivy_tests/test_ivy/test_functional/test_core/test_searching.py +++ b/ivy_tests/test_ivy/test_functional/test_core/test_searching.py @@ -64,8 +64,9 @@ def _dtype_x_limited_axis(draw, *, allow_none=False): fn_tree="functional.ivy.argmax", dtype_x_axis=_dtype_x_limited_axis(allow_none=True), keepdims=st.booleans(), - dtype=helpers.get_dtypes("valid", full=False, none=True), + dtype=helpers.get_dtypes("numeric", full=False, none=True), select_last_index=st.booleans(), + test_gradients=st.just(False), ) def test_argmax( *, diff --git a/ivy_tests/test_ivy/test_functional/test_core/test_statistical.py b/ivy_tests/test_ivy/test_functional/test_core/test_statistical.py index 87b230fdf9649..7c6cd30e28a00 100644 --- a/ivy_tests/test_ivy/test_functional/test_core/test_statistical.py +++ b/ivy_tests/test_ivy/test_functional/test_core/test_statistical.py @@ -82,7 +82,20 @@ def _statistical_dtype_values(draw, *, function, min_value=None, max_value=None) | helpers.floats(min_value=0, max_value=max_correction - 1) ) return dtype, values, axis, correction - return dtype, values, axis + + if isinstance(axis, tuple): + axis = axis[0] + + where_shape = draw( + helpers.mutually_broadcastable_shapes( + num_shapes=1, base_shape=shape, min_dims=0, max_dims=axis + ) + ) + dtype3, where = draw( + helpers.dtype_and_values(available_dtypes=["bool"], shape=where_shape[0]) + ) + + return dtype, values, axis, dtype3, where # --- Main --- # @@ -95,6 +108,7 @@ def _statistical_dtype_values(draw, *, function, min_value=None, max_value=None) dtype_x_axis_castable=_get_castable_dtype(), exclusive=st.booleans(), reverse=st.booleans(), + test_gradients=st.just(False), ) def test_cumprod( *, @@ -140,6 +154,7 @@ def test_cumprod( dtype_x_axis_castable=_get_castable_dtype(), exclusive=st.booleans(), reverse=st.booleans(), + test_gradients=st.just(False), ) def test_cumsum( *, @@ -152,6 +167,7 @@ def test_cumsum( on_device, ): input_dtype, x, axis, castable_dtype = dtype_x_axis_castable + assume("bool" not in input_dtype) # ToDo: set as_variable_flags as the parameter generated by test_cumsum once # this issue is marked as completed https://github.com/pytorch/pytorch/issues/75733 if "torch" in backend_fw: @@ -218,7 +234,7 @@ def test_einsum( keep_dims=st.booleans(), ) def test_max(*, dtype_and_x, keep_dims, test_flags, backend_fw, fn_name, on_device): - input_dtype, x, axis = dtype_and_x + input_dtype, x, axis, *_ = dtype_and_x helpers.test_function( input_dtypes=input_dtype, test_flags=test_flags, @@ -238,7 +254,7 @@ def test_max(*, dtype_and_x, keep_dims, test_flags, backend_fw, fn_name, on_devi keep_dims=st.booleans(), ) def test_mean(*, dtype_and_x, keep_dims, test_flags, backend_fw, fn_name, on_device): - input_dtype, x, axis = dtype_and_x + input_dtype, x, axis, dtype3, where = dtype_and_x helpers.test_function( input_dtypes=input_dtype, test_flags=test_flags, @@ -259,11 +275,15 @@ def test_mean(*, dtype_and_x, keep_dims, test_flags, backend_fw, fn_name, on_dev fn_tree="functional.ivy.min", dtype_and_x=_statistical_dtype_values(function="min"), keep_dims=st.booleans(), + test_gradients=st.just(False), + initial=st.integers(min_value=-5, max_value=5), ) -def test_min(*, dtype_and_x, keep_dims, test_flags, backend_fw, fn_name, on_device): - input_dtype, x, axis = dtype_and_x +def test_min( + *, dtype_and_x, keep_dims, initial, test_flags, backend_fw, fn_name, on_device +): + input_dtype, x, axis, dtype3, where = dtype_and_x helpers.test_function( - input_dtypes=input_dtype, + input_dtypes=[input_dtype[0], dtype3[0]], test_flags=test_flags, backend_to_test=backend_fw, fn_name=fn_name, @@ -271,6 +291,8 @@ def test_min(*, dtype_and_x, keep_dims, test_flags, backend_fw, fn_name, on_devi x=x[0], axis=axis, keepdims=keep_dims, + initial=initial, + where=where[0], ) diff --git a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_elementwise.py b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_elementwise.py index 24517040cf225..3e4b7cf584661 100644 --- a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_elementwise.py +++ b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_elementwise.py @@ -1,5 +1,5 @@ # global -from hypothesis import strategies as st +from hypothesis import assume, strategies as st # local import ivy @@ -217,6 +217,7 @@ def test_allclose( dtype_and_x, rtol, atol, equal_nan, test_flags, backend_fw, fn_name, on_device ): input_dtype, x = dtype_and_x + assume("bfloat16" not in input_dtype) helpers.test_function( input_dtypes=input_dtype, test_flags=test_flags, @@ -510,6 +511,42 @@ def test_erfc( ) +# erfinv +@handle_test( + fn_tree="functional.ivy.experimental.erfinv", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + min_value=-1, + max_value=1, + abs_smallest_val=1e-05, + ), +) +def test_erfinv( + *, + dtype_and_x, + backend_fw, + test_flags, + fn_name, + on_device, +): + input_dtype, x = dtype_and_x + if on_device == "cpu": + assume("float16" not in input_dtype and "bfloat16" not in input_dtype) + test_values = True + if backend_fw == "numpy": + # the numpy backend requires an approximation which doesn't pass the value tests + test_values = False + helpers.test_function( + input_dtypes=input_dtype, + backend_to_test=backend_fw, + test_flags=test_flags, + fn_name=fn_name, + on_device=on_device, + test_values=test_values, + x=x[0], + ) + + # fix @handle_test( fn_tree="functional.ivy.experimental.fix", @@ -796,7 +833,7 @@ def test_lgamma( @handle_test( fn_tree="functional.ivy.experimental.modf", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("valid"), num_arrays=1, min_value=0, exclude_min=True, diff --git a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_linalg.py b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_linalg.py index fe2f805d4759b..1e15bdc2ff1fb 100644 --- a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_linalg.py +++ b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_linalg.py @@ -5,6 +5,7 @@ import numpy as np import pytest import itertools +import sys # local import ivy_tests.test_ivy.helpers as helpers @@ -162,15 +163,15 @@ def _generate_diag_args(draw): # dot @st.composite -def _generate_dot_dtype_and_arrays(draw): +def _generate_dot_dtype_and_arrays(draw, min_num_dims=0): shape_a = draw( helpers.get_shape( - min_dim_size=2, max_dim_size=5, min_num_dims=0, max_num_dims=5 + min_dim_size=2, max_dim_size=5, min_num_dims=min_num_dims, max_num_dims=5 ) ) shape_b = draw( helpers.get_shape( - min_dim_size=2, max_dim_size=5, min_num_dims=0, max_num_dims=5 + min_dim_size=2, max_dim_size=5, min_num_dims=min_num_dims, max_num_dims=5 ) ) @@ -859,7 +860,6 @@ def _tucker_data(draw): fn_tree="functional.ivy.experimental.adjoint", dtype_x=helpers.dtype_and_values( available_dtypes=( - ivy.float16, ivy.float32, ivy.float64, ivy.complex64, @@ -875,7 +875,7 @@ def _tucker_data(draw): shared_dtype=True, ), ) -def test_adjoint(dtype_x, test_flags, backend_fw, fn_name): +def test_adjoint(dtype_x, test_flags, backend_fw, fn_name, on_device): dtype, x = dtype_x helpers.test_function( input_dtypes=dtype, @@ -883,6 +883,7 @@ def test_adjoint(dtype_x, test_flags, backend_fw, fn_name): backend_to_test=backend_fw, fn_name=fn_name, x=x[0], + on_device=on_device, ) @@ -1380,6 +1381,82 @@ def test_kronecker(*, data, test_flags, backend_fw, fn_name, on_device): ) +# lu_factor +@handle_test( + fn_tree="functional.ivy.experimental.lu_factor", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("numeric"), + min_num_dims=2, + max_num_dims=2, + min_dim_size=2, + max_dim_size=5, + ).filter( + lambda x: np.linalg.cond(x[1][0]) < 1 / sys.float_info.epsilon + and np.linalg.det(np.asarray(x[1][0])) != 0 + ), + test_gradients=st.just(False), +) +def test_lu_factor(dtype_x, test_flags, backend_fw, fn_name, on_device): + dtype, x = dtype_x + ret = helpers.test_function( + input_dtypes=dtype, + test_flags=test_flags, + on_device=on_device, + backend_to_test=backend_fw, + fn_name=fn_name, + x=x[0], + test_values=False, + ) + # check decomp is correct manually by getting the values from test_function above + # this is because the decomposition is not unique and test_values will not work + ret_f, ret_gt = ret + + # check that the decomposition is correct for current fw at least + LU, p = ret_f.LU, ret_f.p + L = np.tril(LU, -1) + np.eye(LU.shape[0]) + U = np.triu(LU) + P = np.eye(LU.shape[0])[p] + assert np.allclose(L @ U, P @ x[0]) + + +@handle_test( + fn_tree="functional.ivy.experimental.lu_solve", + dtype_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + shape=helpers.get_shape( + min_num_dims=2, max_num_dims=2, min_dim_size=2, max_dim_size=2 + ), + num_arrays=2, + shared_dtype=True, + ).filter( + lambda x: "float16" not in x[0] + and "bfloat16" not in x[0] + and np.linalg.cond(x[1][0]) < 1 / sys.float_info.epsilon + and np.linalg.det(np.asarray(x[1][0])) != 0 + ), + test_gradients=st.just(False), +) +def test_lu_solve(dtype_x, test_flags, backend_fw, fn_name, on_device): + dtype, arr = dtype_x + A, B = arr[0], arr[1] + ivy.set_backend(backend_fw) + lu_ = ivy.lu_factor(A) + lu, p = lu_.LU, lu_.p + X, X_gt = helpers.test_function( + input_dtypes=dtype, + test_flags=test_flags, + on_device=on_device, + backend_to_test=backend_fw, + fn_name=fn_name, + lu=lu, + p=p, + b=B, + test_values=False, + ) + + assert np.allclose(A @ X, B) + + @handle_test( fn_tree="functional.ivy.experimental.make_svd_non_negative", data=_make_svd_nn_data(), diff --git a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_manipulation.py b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_manipulation.py index 87b09dccecfd6..2c2c5cc7ca50c 100644 --- a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_manipulation.py +++ b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_manipulation.py @@ -6,6 +6,7 @@ # local import ivy import ivy_tests.test_ivy.helpers as helpers +from ivy_tests.test_ivy.helpers.hypothesis_helpers.general_helpers import sizes_ from ivy_tests.test_ivy.helpers import handle_test, create_concatenable_arrays_dtypes from ivy.functional.ivy.experimental.manipulation import _check_bounds from ivy_tests.test_ivy.test_functional.test_core.test_manipulation import _get_splits @@ -1470,6 +1471,45 @@ def test_trim_zeros( ) +# unflatten +@handle_test( + fn_tree="functional.ivy.experimental.unflatten", + shape=st.shared(helpers.get_shape(min_num_dims=1), key="shape"), + dtype_and_values=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("valid"), + min_num_dims=1, + shape_key="shape", + ), + axis=helpers.get_axis( + shape=st.shared(helpers.get_shape(min_num_dims=1), key="shape"), + force_int=True, + ), +) +def test_unflatten( + *, + dtype_and_values, + on_device, + fn_name, + test_flags, + backend_fw, + shape, + axis, +): + shape_ = sizes_(shape, axis) + dtype, x = dtype_and_values + helpers.test_function( + input_dtypes=dtype, + backend_to_test=backend_fw, + test_flags=test_flags, + fn_name=fn_name, + on_device=on_device, + test_values=False, + x=x[0], + shape=shape_, + dim=axis, + ) + + @handle_test( fn_tree="functional.ivy.experimental.unfold", dtype_values_axis=helpers.dtype_values_axis( diff --git a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_random.py b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_random.py index 730c1749af982..0da1bbb87a106 100644 --- a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_random.py +++ b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_random.py @@ -16,6 +16,7 @@ ), seed=helpers.ints(min_value=0, max_value=100), test_gradients=st.just(False), + ground_truth_backend="torch", ) def test_bernoulli( *, dtype_and_probs, seed, test_flags, backend_fw, fn_name, on_device @@ -25,18 +26,20 @@ def test_bernoulli( assume( not ("torch" in str(backend_fw) and "float16" in dtype and on_device == "cpu") ) - helpers.test_function( + ret_np_flat_from_target, ret_np_from_gt_flat = helpers.test_function( input_dtypes=dtype, test_flags=test_flags, on_device=on_device, backend_to_test=backend_fw, fn_name=fn_name, test_values=False, + return_flat_np_arrays=True, probs=probs[0], logits=None, shape=None, seed=seed, ) + helpers.assert_same_type_and_shape([ret_np_flat_from_target, ret_np_from_gt_flat]) # beta diff --git a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_statistical.py b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_statistical.py index 6ceea7b2c08a1..4a7f96a3f0714 100644 --- a/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_statistical.py +++ b/ivy_tests/test_ivy/test_functional/test_experimental/test_core/test_statistical.py @@ -599,7 +599,7 @@ def test_median(*, dtype_x_axis, keep_dims, test_flags, backend_fw, fn_name, on_ def test_nanmean( *, dtype_x_axis, keep_dims, dtype, test_flags, backend_fw, fn_name, on_device ): - input_dtype, x, axis = dtype_x_axis + input_dtype, x, axis, *_ = dtype_x_axis helpers.test_function( input_dtypes=input_dtype, test_flags=test_flags, diff --git a/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_activations.py b/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_activations.py index 5a79ef33ad3cf..d61e795307cb9 100644 --- a/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_activations.py +++ b/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_activations.py @@ -40,7 +40,7 @@ def test_celu( @handle_test( fn_tree="functional.ivy.experimental.elu", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("valid"), + available_dtypes=helpers.get_dtypes("float_and_complex"), large_abs_safety_factor=8, small_abs_safety_factor=8, safety_factor_scale="log", @@ -98,6 +98,28 @@ def test_hardshrink( ) +# hardsilu +@handle_test( + fn_tree="functional.ivy.experimental.hardsilu", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + large_abs_safety_factor=8, + small_abs_safety_factor=8, + safety_factor_scale="log", + ), +) +def test_hardsilu(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): + dtype, x = dtype_and_x + helpers.test_function( + input_dtypes=dtype, + backend_to_test=backend_fw, + test_flags=test_flags, + fn_name=fn_name, + on_device=on_device, + x=x[0], + ) + + # hardtanh @handle_test( fn_tree="functional.ivy.experimental.hardtanh", @@ -214,10 +236,11 @@ def test_prelu(*, dtype_and_x, slope, test_flags, backend_fw, fn_name, on_device @handle_test( fn_tree="functional.ivy.experimental.relu6", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("valid"), + available_dtypes=helpers.get_dtypes("float_and_complex"), large_abs_safety_factor=2, small_abs_safety_factor=2, safety_factor_scale="log", + min_value=1e-15, ), complex_mode=st.sampled_from(["jax", "split", "magnitude"]), ) diff --git a/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_layers.py b/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_layers.py index 3ab27f056aa8f..9c6b558267d4d 100644 --- a/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_layers.py +++ b/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_layers.py @@ -6,7 +6,7 @@ # local import ivy import ivy_tests.test_ivy.helpers as helpers -from ivy_tests.test_ivy.helpers import handle_test +from ivy_tests.test_ivy.helpers import handle_test, BackendHandler # --- Helpers --- # @@ -154,6 +154,93 @@ def _interp_args(draw, mode=None, mode_list=None): return (dtype, x, mode, size, align_corners, scale_factor, recompute_scale_factor) +@st.composite +def _lstm_helper(draw): + input_size = draw(helpers.ints(min_value=2, max_value=5)) + hidden_size = 4 * input_size + input_length = draw(helpers.ints(min_value=2, max_value=5)) + batch_size = draw(helpers.ints(min_value=1, max_value=4)) * 2 + dtype = draw(helpers.get_dtypes("float", full=False)) + (time_major, go_backwards, unroll, zero_output_for_mask, return_all_outputs) = draw( + helpers.array_bools(size=5) + ) + shape = [batch_size, input_length, input_size] + if time_major: + shape = [input_length, batch_size, input_size] + inputs = draw( + helpers.dtype_and_values( + available_dtypes=dtype, + shape=shape, + min_value=-1, + max_value=1, + abs_smallest_val=1e-5, + safety_factor_scale="log", + ) + )[1][0] + mask = draw( + st.just([None, [None]]) + | helpers.dtype_and_values( + available_dtypes=["bool"], + shape=[*shape[:2], 1], + ) + )[1][0] + kernel, recurrent_kernel = draw( + helpers.dtype_and_values( + available_dtypes=dtype, + num_arrays=2, + shape=(input_size, hidden_size), + min_value=-1, + max_value=1, + abs_smallest_val=1e-5, + safety_factor_scale="log", + ) + )[1] + bias, recurrent_bias = draw( + helpers.dtype_and_values( + available_dtypes=dtype, + num_arrays=2, + shape=(1, hidden_size), + min_value=-1, + max_value=1, + abs_smallest_val=1e-5, + safety_factor_scale="log", + ) + )[1] + init_h, init_c = draw( + helpers.dtype_and_values( + available_dtypes=dtype, + num_arrays=2, + shape=(batch_size, input_size), + min_value=-1, + max_value=1, + abs_smallest_val=1e-5, + safety_factor_scale="log", + ) + )[1] + dtypes = [dtype[0] for _ in range(7)] + if mask is not None: + dtypes.append("bool") + # ToDo : zero_output_for_mask doesn't work if we don't return_all_outputs + # in tensorflow + zero_output_for_mask = zero_output_for_mask and return_all_outputs + return ( + dtypes, + inputs, + kernel, + recurrent_kernel, + bias, + recurrent_bias, + [init_h, init_c], + go_backwards, + mask, + unroll, + input_length, + time_major, + zero_output_for_mask, + return_all_outputs, + ) + + @st.composite def _reduce_window_helper(draw, get_func_st): dtype = draw(helpers.get_dtypes("valid", full=False, index=2)) @@ -599,6 +686,42 @@ def test_adaptive_max_pool2d( ) +@handle_test( + fn_tree="functional.ivy.experimental.adaptive_max_pool3d", + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + min_num_dims=4, + max_num_dims=5, + min_dim_size=1, + max_value=100, + min_value=-100, + ), + output_size=st.one_of( + st.tuples( + helpers.ints(min_value=1, max_value=5), + helpers.ints(min_value=1, max_value=5), + helpers.ints(min_value=1, max_value=5), + ), + helpers.ints(min_value=1, max_value=5), + ), + test_with_out=st.just(False), + ground_truth_backend="torch", +) +def test_adaptive_max_pool3d( + *, dtype_and_x, output_size, test_flags, backend_fw, fn_name, on_device +): + input_dtype, x = dtype_and_x + helpers.test_function( + input_dtypes=input_dtype, + test_flags=test_flags, + backend_to_test=backend_fw, + on_device=on_device, + fn_name=fn_name, + input=x[0], + output_size=output_size, + ) + + @handle_test( fn_tree="functional.ivy.experimental.avg_pool1d", x_k_s_p=helpers.arrays_for_pooling(min_dims=3, max_dims=3, min_side=1, max_side=4), @@ -1400,6 +1523,95 @@ def test_rfftn( ) +# test_rnn +@handle_test( + fn_tree="functional.ivy.experimental.rnn", + rnn_args=_lstm_helper(), + test_with_out=st.just(False), + test_instance_method=st.just(False), +) +def test_rnn( + *, + rnn_args, + test_flags, + backend_fw, + fn_name, + on_device, +): + # ToDo : Get the tests passing with paddle + ( + input_dtypes, + inputs, + kernel_orig, + recurrent_kernel_orig, + bias_orig, + recurrent_bias_orig, + initial_states, + go_backwards, + mask, + unroll, + input_length, + time_major, + zero_output_for_mask, + return_all_outputs, + ) = rnn_args + + # unsupported dtype of float16 is in our _lstm_step function + # so can't be inferred through ivy.function_unsupported_devices_and_dtypes + assume(not (backend_fw == "torch" and input_dtypes[0] == "float16")) + + def _lstm_step(cell_inputs, cell_states): + with BackendHandler.update_backend( + ivy.current_backend( + cell_inputs.to_native() + if "ivy" in str(type(cell_inputs)) + else cell_inputs + ).backend + ) as ivy_backend: + nonlocal kernel_orig, recurrent_kernel_orig, bias_orig, recurrent_bias_orig + kernel = ivy_backend.array(kernel_orig) + recurrent_kernel = ivy_backend.array(recurrent_kernel_orig) + bias = ivy_backend.array(bias_orig) + recurrent_bias = ivy_backend.array(recurrent_bias_orig) + + h_tm1 = cell_states[0] # previous memory state + c_tm1 = cell_states[1] # previous carry state + + z = ivy_backend.dot(cell_inputs, kernel) + bias + z += ivy_backend.dot(h_tm1, recurrent_kernel) + recurrent_bias + + z0, z1, z2, z3 = ivy_backend.split(z, num_or_size_splits=4, axis=-1) + + i = ivy_backend.sigmoid(z0) # input + f = ivy_backend.sigmoid(z1) # forget + c = f * c_tm1 + i * ivy_backend.tanh(z2) + o = ivy_backend.sigmoid(z3) # output + + h = o * ivy_backend.tanh(c) + return h, [h, c] + + helpers.test_function( + input_dtypes=input_dtypes, + test_flags=test_flags, + backend_to_test=backend_fw, + on_device=on_device, + fn_name=fn_name, + rtol_=1e-1, + atol_=1e-1, + step_function=_lstm_step, + inputs=inputs, + initial_states=initial_states, + go_backwards=go_backwards, + mask=mask, + constants=None, + unroll=unroll, + input_length=input_length, + time_major=time_major, + zero_output_for_mask=zero_output_for_mask, + return_all_outputs=return_all_outputs, + ) + + @handle_test( fn_tree="functional.ivy.experimental.sliding_window", all_args=helpers.arrays_for_pooling(3, 3, 1, 2, return_dilation=True), diff --git a/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_losses.py b/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_losses.py index 2161ee814304b..8c0028d457e24 100644 --- a/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_losses.py +++ b/ivy_tests/test_ivy/test_functional/test_experimental/test_nn/test_losses.py @@ -7,6 +7,100 @@ from ivy_tests.test_ivy.helpers import handle_test +# --- Helpers --- # +# --------------- # + + +@st.composite +def _hinge_embedding_loss_input( + draw, min_num_dims=1, max_num_dims=5, min_dim_size=1, max_dim_size=10 +): + # determine the shape for both arrays (input and target) + shape = draw( + st.shared( + helpers.get_shape( + min_num_dims=min_num_dims, + max_num_dims=max_num_dims, + min_dim_size=min_dim_size, + max_dim_size=max_dim_size, + ), + key="shared_shape", + ) + ) + + # Generate an array of -1 and 1 with the given shape (target_array) + def _arrays_of_neg1_and_1(shape): + value_strategy = st.sampled_from([-1, 1]) + prod_shape = int(np.prod(shape)) # Convert np.int64 to int + array_data = draw( + st.lists(value_strategy, min_size=prod_shape, max_size=prod_shape) + ) + return np.asarray(array_data).reshape(shape) + + # input_array + dtype, xx = draw( + helpers.dtype_and_values( + shape=shape, + available_dtypes=helpers.get_dtypes("valid"), + safety_factor_scale="linear", + large_abs_safety_factor=2, + small_abs_safety_factor=2, + min_value=1, + max_value=10, + min_dim_size=1, + min_num_dims=1, + max_num_dims=5, + max_dim_size=5, + ) + ) + + # generate the target array 'yy' containing either 1 or -1 + yy = _arrays_of_neg1_and_1(shape=shape) + + return dtype, xx, yy + + +# --- Main --- # +# ------------ # + + +# hinge_embedding_loss +@handle_test( + fn_tree="functional.ivy.experimental.hinge_embedding_loss", + dtype_and_inputs=_hinge_embedding_loss_input(), + margin=st.floats(min_value=1, max_value=5), + reduction=st.sampled_from(["none", "sum", "mean"]), + test_gradients=st.just( + False + ), # Gradients are failing for "jax" and "paddle" backend. + test_with_out=st.just(False), + ground_truth_backend="torch", +) +def test_hinge_embedding_loss( + dtype_and_inputs, + margin, + reduction, + test_flags, + backend_fw, + fn_name, + on_device, +): + dtype, xx, yy = dtype_and_inputs + helpers.test_function( + input_dtypes=dtype, + test_flags=test_flags, + backend_to_test=backend_fw, + fn_name=fn_name, + on_device=on_device, + input=xx[0], + target=yy, + margin=margin, + reduction=reduction, + rtol_=1e-05, + atol_=1e-05, + ) + + # huber_loss @handle_test( fn_tree="functional.ivy.experimental.huber_loss", diff --git a/ivy_tests/test_ivy/test_functional/test_nn/test_activations.py b/ivy_tests/test_ivy/test_functional/test_nn/test_activations.py index 83a1d3985c6ff..5b2aa8086cd9f 100644 --- a/ivy_tests/test_ivy/test_functional/test_nn/test_activations.py +++ b/ivy_tests/test_ivy/test_functional/test_nn/test_activations.py @@ -166,7 +166,7 @@ def test_mish(*, dtype_and_x, test_flags, backend_fw, fn_name, on_device): @handle_test( fn_tree="functional.ivy.relu", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), + available_dtypes=helpers.get_dtypes("valid"), large_abs_safety_factor=8, small_abs_safety_factor=8, safety_factor_scale="log", @@ -208,6 +208,8 @@ def test_sigmoid( test_flags=test_flags, fn_name=fn_name, on_device=on_device, + atol_=1e-02, + rtol_=1e-02, x=x[0], complex_mode=complex_mode, ) diff --git a/ivy_tests/test_ivy/test_functional/test_nn/test_layers.py b/ivy_tests/test_ivy/test_functional/test_nn/test_layers.py index 73fe88ff2e848..385b19b1a4c18 100644 --- a/ivy_tests/test_ivy/test_functional/test_nn/test_layers.py +++ b/ivy_tests/test_ivy/test_functional/test_nn/test_layers.py @@ -9,7 +9,7 @@ # local import ivy_tests.test_ivy.helpers as helpers from ivy_tests.test_ivy.helpers import handle_test -from ivy.functional.ivy.layers import _deconv_length +from ivy.functional.ivy.layers import _deconv_length, _pack_padded_sequence # --- Helpers --- # @@ -83,6 +83,157 @@ def _general_transpose_helper(draw): return dims, x_f_d_df +@st.composite +def _lstm_helper(draw): + dtype = draw(helpers.get_dtypes("float", full=False)) + + has_ih_bias = draw(st.booleans()) + has_hh_bias = draw(st.booleans()) + weights_transposed = draw(st.booleans()) + bidirectional = draw(st.booleans()) + dropout = draw(st.floats(min_value=0, max_value=0.99)) + train = draw(st.booleans()) and not dropout + packed = draw(st.booleans()) + + batch_first = draw(st.booleans()) and not packed + num_batches = draw(st.integers(min_value=1, max_value=5)) + num_layers = draw(st.integers(min_value=1, max_value=3)) + num_directions = 2 if bidirectional else 1 + seq_size = draw(st.integers(min_value=1, max_value=5)) + in_size = draw(st.integers(min_value=1, max_value=3)) + hidden_size = draw(st.integers(min_value=1, max_value=3)) + + input = draw( + helpers.array_values( + dtype=dtype[0], + shape=( + (num_batches, seq_size, in_size) + if batch_first + else (seq_size, num_batches, in_size) + ), + min_value=0, + max_value=1, + ) + ) + + init_h = draw( + helpers.array_values( + dtype=dtype[0], + shape=(num_directions * num_layers, num_batches, hidden_size), + min_value=0, + max_value=1, + ) + ) + init_c = draw( + helpers.array_values( + dtype=dtype[0], + shape=(num_directions * num_layers, num_batches, hidden_size), + min_value=0, + max_value=1, + ) + ) + + all_weights = [] + for k in range(num_layers): + for _ in range(num_directions): + weight_ih = draw( + helpers.array_values( + dtype=dtype[0], + shape=( + (4 * hidden_size, in_size) + if k == 0 + else (4 * hidden_size, num_directions * hidden_size) + ), + min_value=0, + max_value=1, + ) + ) + weight_hh = draw( + helpers.array_values( + dtype=dtype[0], + shape=(4 * hidden_size, hidden_size), + min_value=0, + max_value=1, + ) + ) + all_weights += [weight_ih, weight_hh] + if has_ih_bias: + bias_ih = draw( + helpers.array_values( + dtype=dtype[0], + shape=(4 * hidden_size,), + min_value=0, + max_value=1, + ) + ) + all_weights.append(bias_ih) + if has_hh_bias: + bias_hh = draw( + helpers.array_values( + dtype=dtype[0], + shape=(4 * hidden_size,), + min_value=0, + max_value=1, + ) + ) + all_weights.append(bias_hh) + + if weights_transposed: + all_weights = [ + ivy.swapaxes(w, 0, 1) if w.dims() == 2 else w for w in all_weights + ] + + if packed: + batch_sizes = [seq_size] + batch_sizes += draw( + st.lists( + st.integers(min_value=1, max_value=seq_size), + min_size=num_batches - 1, + max_size=num_batches - 1, + ) + ) + batch_sizes = np.array(draw(st.permutations(batch_sizes))) + input, batch_sizes = ( + ivy.to_numpy(p) for p in _pack_padded_sequence(input, batch_sizes) + ) + else: + batch_sizes = None + + initial_states = init_h, init_c + all_weights = tuple(all_weights) + if batch_sizes is not None: + dtypes = dtype + ["int64"] + kwargs = { + "input": input, + "batch_sizes": batch_sizes, + "initial_states": initial_states, + "all_weights": all_weights, + "num_layers": num_layers, + "dropout": dropout, + "train": train, + "bidirectional": bidirectional, + "weights_transposed": weights_transposed, + "has_ih_bias": has_ih_bias, + "has_hh_bias": has_hh_bias, + } + else: + dtypes = dtype + kwargs = { + "input": input, + "initial_states": initial_states, + "all_weights": all_weights, + "num_layers": num_layers, + "dropout": dropout, + "train": train, + "bidirectional": bidirectional, + "batch_first": batch_first, + "weights_transposed": weights_transposed, + "has_ih_bias": has_ih_bias, + "has_hh_bias": has_hh_bias, + } + return dtypes, kwargs + + @st.composite def _mha_helper(draw, same_pre_embed_dim=False, batch_second=False): _qkv_same_dim = draw(st.booleans()) @@ -1391,7 +1542,30 @@ def test_linear(*, dtype_x_weight_bias, test_flags, backend_fw, fn_name, on_devi ) +# TODO: fix this test # lstm +# @handle_test( +# fn_tree="functional.ivy.lstm", +# dtypes_kwargs=_lstm_helper(), +# ground_truth_backend="torch", +# test_with_out=st.just(False), +# ) +# def test_lstm(*, dtypes_kwargs, test_flags, backend_fw, fn_name, on_device): +# dtypes, kwargs = dtypes_kwargs +# assume("batch_sizes" not in kwargs) +# helpers.test_function( +# input_dtypes=dtypes, +# test_flags=test_flags, +# backend_to_test=backend_fw, +# fn_name=fn_name, +# on_device=on_device, +# rtol_=1e-01, +# atol_=1e-01, +# **kwargs, +# ) + + +# lstm_update @handle_test( fn_tree="functional.ivy.lstm_update", dtype_lstm=_x_and_lstm( diff --git a/ivy_tests/test_ivy/test_misc/test_shape.py b/ivy_tests/test_ivy/test_misc/test_shape.py index f20c34bb3a386..9ab019cb59275 100644 --- a/ivy_tests/test_ivy/test_misc/test_shape.py +++ b/ivy_tests/test_ivy/test_misc/test_shape.py @@ -1,24 +1,25 @@ from hypothesis import assume, strategies as st import numpy as np +import ivy import ivy_tests.test_ivy.helpers as helpers from ivy_tests.test_ivy.helpers import handle_method +CLASS_TREE = "ivy.Shape" +DUMMY_DTYPE = ["int32"] + + @handle_method( + init_tree=CLASS_TREE, method_tree="Shape.__add__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - num_arrays=2, - large_abs_safety_factor=2.5, - small_abs_safety_factor=2.5, - safety_factor_scale="log", - shared_dtype=True, - ), + shape_1=helpers.get_shape(), + shape_2=helpers.get_shape(), ) def test_shape__add__( - dtype_and_x, + shape_1, + shape_2, method_name, class_name, ground_truth_backend, @@ -27,17 +28,16 @@ def test_shape__add__( method_flags, on_device, ): - dtype, x = dtype_and_x helpers.test_method( on_device=on_device, ground_truth_backend=ground_truth_backend, backend_to_test=backend_fw, init_flags=init_flags, method_flags=method_flags, - init_all_as_kwargs_np={"shape": x[0]}, - init_input_dtypes=dtype, - method_input_dtypes=dtype, - method_all_as_kwargs_np={"other": x[1]}, + init_all_as_kwargs_np={"shape_tup": shape_1}, + init_input_dtypes=DUMMY_DTYPE, + method_input_dtypes=DUMMY_DTYPE, + method_all_as_kwargs_np={"other": shape_2}, class_name=class_name, method_name=method_name, ) @@ -113,15 +113,14 @@ def test_shape__eq__( @handle_method( + init_tree=CLASS_TREE, method_tree="Shape.__ge__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - num_arrays=2, - shared_dtype=True, - ), + shape_1=helpers.get_shape(), + shape_2=helpers.get_shape(), ) def test_shape__ge__( - dtype_and_x, + shape_1, + shape_2, method_name, class_name, ground_truth_backend, @@ -130,17 +129,16 @@ def test_shape__ge__( method_flags, on_device, ): - dtype, x = dtype_and_x helpers.test_method( on_device=on_device, ground_truth_backend=ground_truth_backend, backend_to_test=backend_fw, init_flags=init_flags, method_flags=method_flags, - init_all_as_kwargs_np={"shape": x[0]}, - init_input_dtypes=dtype, - method_input_dtypes=dtype, - method_all_as_kwargs_np={"other": x[1]}, + init_all_as_kwargs_np={"shape_tup": shape_1}, + init_input_dtypes=DUMMY_DTYPE, + method_input_dtypes=DUMMY_DTYPE, + method_all_as_kwargs_np={"other": shape_2}, class_name=class_name, method_name=method_name, ) @@ -424,18 +422,14 @@ def test_shape__mod__( @handle_method( + init_tree=CLASS_TREE, method_tree="Shape.__mul__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - num_arrays=2, - large_abs_safety_factor=2.5, - small_abs_safety_factor=2.5, - safety_factor_scale="log", - shared_dtype=True, - ), + shape=helpers.get_shape(), + other=st.integers(min_value=1, max_value=10), ) def test_shape__mul__( - dtype_and_x, + shape, + other, method_name, class_name, backend_fw, @@ -444,35 +438,30 @@ def test_shape__mul__( method_flags, on_device, ): - dtype, x = dtype_and_x helpers.test_method( on_device=on_device, ground_truth_backend=ground_truth_backend, backend_to_test=backend_fw, init_flags=init_flags, method_flags=method_flags, - init_all_as_kwargs_np={"data": x[0]}, - init_input_dtypes=dtype, - method_input_dtypes=dtype, - method_all_as_kwargs_np={"other": x[1]}, + init_all_as_kwargs_np={"shape_tup": shape}, + init_input_dtypes=DUMMY_DTYPE, + method_input_dtypes=DUMMY_DTYPE, + method_all_as_kwargs_np={"other": other}, class_name=class_name, method_name=method_name, ) @handle_method( + init_tree=CLASS_TREE, method_tree="Shape.__radd__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - num_arrays=2, - large_abs_safety_factor=2.5, - small_abs_safety_factor=2.5, - safety_factor_scale="log", - shared_dtype=True, - ), + shape_1=helpers.get_shape(), + shape_2=helpers.get_shape(), ) def test_shape__radd__( - dtype_and_x, + shape_1, + shape_2, method_name, class_name, backend_fw, @@ -481,17 +470,16 @@ def test_shape__radd__( method_flags, on_device, ): - dtype, x = dtype_and_x helpers.test_method( on_device=on_device, ground_truth_backend=ground_truth_backend, backend_to_test=backend_fw, init_flags=init_flags, method_flags=method_flags, - init_all_as_kwargs_np={"shape": x[0]}, - init_input_dtypes=dtype, - method_input_dtypes=dtype, - method_all_as_kwargs_np={"other": x[1]}, + init_all_as_kwargs_np={"shape_tup": shape_1}, + init_input_dtypes=DUMMY_DTYPE, + method_input_dtypes=DUMMY_DTYPE, + method_all_as_kwargs_np={"other": shape_2}, class_name=class_name, method_name=method_name, ) @@ -574,18 +562,14 @@ def test_shape__rmod__( @handle_method( + init_tree=CLASS_TREE, method_tree="Shape.__rmul__", - dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("numeric"), - num_arrays=2, - large_abs_safety_factor=2.5, - small_abs_safety_factor=2.5, - safety_factor_scale="log", - shared_dtype=True, - ), + shape=helpers.get_shape(), + other=st.integers(min_value=1, max_value=10), ) def test_shape__rmul__( - dtype_and_x, + shape, + other, method_name, class_name, ground_truth_backend, @@ -594,17 +578,16 @@ def test_shape__rmul__( method_flags, on_device, ): - dtype, x = dtype_and_x helpers.test_method( on_device=on_device, ground_truth_backend=ground_truth_backend, backend_to_test=backend_fw, init_flags=init_flags, method_flags=method_flags, - init_all_as_kwargs_np={"data": x[0]}, - init_input_dtypes=dtype, - method_input_dtypes=dtype, - method_all_as_kwargs_np={"other": x[1]}, + init_all_as_kwargs_np={"shape_tup": shape}, + init_input_dtypes=DUMMY_DTYPE, + method_input_dtypes=DUMMY_DTYPE, + method_all_as_kwargs_np={"other": other}, class_name=class_name, method_name=method_name, ) @@ -682,3 +665,13 @@ def test_shape__sub__( class_name=class_name, method_name=method_name, ) + + +def test_shape_in_conditions(): + shape = ivy.Shape((1, 2)) + condition_is_true = True if shape else False + assert condition_is_true + + shape = ivy.Shape(()) + condition_is_true = True if shape else False + assert not condition_is_true diff --git a/ivy_tests/test_ivy/test_stateful/test_layers.py b/ivy_tests/test_ivy/test_stateful/test_layers.py index a315c74766451..f3ec09355af54 100644 --- a/ivy_tests/test_ivy/test_stateful/test_layers.py +++ b/ivy_tests/test_ivy/test_stateful/test_layers.py @@ -1053,7 +1053,7 @@ def test_dropout_layer( test_values=False, on_device=on_device, ) - ret = helpers.flatten_and_to_np(ret=ret) + ret = helpers.flatten_and_to_np(ret=ret, backend=backend_fw) for u in ret: # cardinality test assert u.shape == x[0].shape diff --git a/pyproject.toml b/pyproject.toml index 23f6dc2c85e4a..c0e38e22ac6ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,12 +6,51 @@ requires = [ ] build-backend = "setuptools.build_meta" + +[tool.docformatter] +wrap-summaries = 88 +pre-summary-newline = true + + +[tool.autoflake] +in-place = true +remove-all-unused-imports = true +ignore-init-module-imports = true +remove-duplicate-keys = true +remove-unused-variables = true +quiet = true +ignore-pass-after-docstring = true +exclude = ["__init__.py"] + + [tool.ruff] +line-length = 88 target-version = "py38" -select = ["D"] # Enabling Only pydocstyle checks as of now (https://docs.astral.sh/ruff/rules/#pydocstyle-d) +[tool.ruff.lint] +select = [ + # pyflakes + "F", + # pycodestyle + "E", "W", + # pydocstyle + "D", + "I002", # Missing required import. + "UP008", # Checks for super calls that pass redundant arguments. + "G010", # deprecated-log-warn. + "PLR1722", # Use sys.exit() instead of exit() and quit(). + "TRY004", # Prefer TypeError exception for invalid type. + "PT014", # pytest-duplicate-parametrize-test-cases. + "PT006", # Checks for the type of parameter names passed to pytest.mark.parametrize. + "PT007", # Checks for the type of parameter values passed to pytest.mark.parametrize. + "PT018", # Checks for assertions that combine multiple independent conditions. +] + ignore = [ + "E203", # Whitespace-before-punctuation. + "E402", # Module-import-not-at-top-of-file. + "E731", # Do not assign a lambda expression, use a def. "D100", # Missing docstring in public module. "D101", # Missing docstring in public class. "D102", # Missing docstring in public method. @@ -26,12 +65,14 @@ ignore = [ "D213", # Multi-line docstring summary should start at the second line. "D209", # Multi-line docstring closing quotes should be on a separate line. "D400", # First line should end with a period. + "D413", # Missing blank line after last section of docstrings. "D401", # First line of docstring should be in imperative mood. "D415", # First line should end with a period, question mark, or exclamation point. "D416", # Section name should end with a colon ("Attributes"). "D417", # Missing argument description in the docstring for argument "X". ] -exclude = [ -'ivy/functional/(frontends|backends)/(?!.*/func_wrapper\.py$).*(?!__init__\.py$)', -] +[tool.ruff.lint.per-file-ignores] +'ivy/functional/(frontends|backends)/(?!.*/func_wrapper\.py$).*(?!__init__\.py$)' = ["D"] +"**/__init__.py" = ["F401","F403","F405","F811","F821", "E501"] +"ivy/functional/frontends/paddle/**" = ["F401", "F403", "F405"] diff --git a/scripts/backend_generation/generate.py b/scripts/backend_generation/generate.py index 90886b67f61b4..523ad1b6f28a7 100644 --- a/scripts/backend_generation/generate.py +++ b/scripts/backend_generation/generate.py @@ -167,8 +167,7 @@ def _should_install_backend(package_name): ) from e elif ret.lower() == "n": print( - Fore.YELLOW - + "Will continue without backend installed, " + Fore.YELLOW + "Will continue without backend installed, " "type checking won't be available.\n" ) else: diff --git a/scripts/backend_generation/tree_generation.py b/scripts/backend_generation/tree_generation.py index 871ef7abbc343..7c94d01ef603c 100644 --- a/scripts/backend_generation/tree_generation.py +++ b/scripts/backend_generation/tree_generation.py @@ -208,6 +208,9 @@ def _copy_tree(backend_reference_path: str, backend_generation_path: str): def _create_type_mapping(config: dict, reference_backend_init_path: str): + # print pwd for debugging + print(os.getcwd()) + print with open(reference_backend_init_path, "r") as file: file_src = file.read() @@ -238,7 +241,7 @@ def generate(config_file): global _target_backend _target_backend = _config["name"] - backends_root = "../../ivy/functional/backends/" + backends_root = "ivy/functional/backends/" backend_reference_path = backends_root + _backend_reference backend_generation_path = backends_root + _target_backend @@ -289,15 +292,17 @@ def generate(config_file): generated_file.write(astunparse.unparse(tree_to_write)) subprocess.run(["black", "-q", backend_generation_path]) - subprocess.run([ - "autoflake", - "-i", - "--remove-all-unused-imports", - "--ignore-init-module-imports", - "--quiet", - "-r", - backend_generation_path, - ]) + subprocess.run( + [ + "autoflake", + "-i", + "--remove-all-unused-imports", + "--ignore-init-module-imports", + "--quiet", + "-r", + backend_generation_path, + ] + ) if __name__ == "__main__": diff --git a/scripts/generate_intelligent_tests_workflow.py b/scripts/generate_intelligent_tests_workflow.py index 6b8b8a3a301cb..6cdf8ff51b7dd 100644 --- a/scripts/generate_intelligent_tests_workflow.py +++ b/scripts/generate_intelligent_tests_workflow.py @@ -5,7 +5,7 @@ print("on:") print(" workflow_dispatch:") print(" pull_request:") -print(" types: [ labeled, opened, synchronize, reopened, review_requested ]") +print(" types: [opened, synchronize, reopened, review_requested ]") print() print("permissions:") print(" actions: read") diff --git a/scripts/run_tests/run_tests.py b/scripts/run_tests/run_tests.py index ac5704b461004..18a1e1e9bef13 100644 --- a/scripts/run_tests/run_tests.py +++ b/scripts/run_tests/run_tests.py @@ -20,9 +20,10 @@ gpu_flag = sys.argv[5] workflow_id = sys.argv[6] priority_flag = sys.argv[7] + tracer_flag = sys.argv[8] - if len(sys.argv) > 8 and sys.argv[8] != "null": - run_id = sys.argv[8] + if len(sys.argv) > 9 and sys.argv[9] != "null": + run_id = sys.argv[9] else: run_id = f"https://github.com/unifyai/ivy/actions/runs/{workflow_id}" @@ -30,6 +31,13 @@ if gpu_flag == "true": device = "gpu" + tracer_str = "" + if tracer_flag == "true": + tracer_flag = "tracer_" + tracer_str = " --with-trace-testing" + else: + tracer_flag = "" + cluster = MongoClient( f"mongodb+srv://deep-ivy:{mongo_key}@cluster0.qdvf8q3.mongodb.net/?retryWrites=true&w=majority" # noqa ) @@ -103,6 +111,7 @@ image = "unifyai/ivy:latest-gpu" device_str = " --device=gpu:0" device_access_str = " --gpus all" + os.system("docker pull unifyai/ivy:latest-gpu") os.system( f"docker run{device_access_str} --name test-container -v " @@ -111,7 +120,7 @@ ) command = ( "docker exec test-container python3 -m pytest --tb=short" - f" {test_path}{device_str} --backend {backend}" + f" {test_path}{device_str} --backend {backend}{tracer_str}" ) os.system(command) @@ -207,12 +216,16 @@ "_id": function_name, "test_path": test_path, "submodule": submodule, - f"{prefix_str}{backend}.{version}.status.{device}": not failed, - f"{prefix_str}{backend}.{version}.workflow.{device}": run_id, + f"{prefix_str}{backend}.{version}.{tracer_flag}status.{device}": ( + not failed + ), + f"{prefix_str}{backend}.{version}.{tracer_flag}workflow.{device}": ( + run_id + ), } # add transpilation metrics if report generated - if not failed and report_content: + if not failed and report_content and not tracer_flag: if is_frontend_test: test_info = { **test_info, @@ -238,10 +251,6 @@ # delete the container os.system("docker rm -f test-container") - # delete pulled image before terminating - if device == "gpu": - os.system("docker rmi unifyai/ivy:latest-gpu") - # if any tests fail, the workflow fails if failed: sys.exit(1) diff --git a/scripts/setup_tests/cron_tests.py b/scripts/setup_tests/cron_tests.py index 810401efffb48..e589a78461fc0 100644 --- a/scripts/setup_tests/cron_tests.py +++ b/scripts/setup_tests/cron_tests.py @@ -2,7 +2,7 @@ from get_all_tests import get_all_tests -run_iter, gpu = int(sys.argv[1]), sys.argv[2] +run_iter, gpu, tracer = int(sys.argv[1]), sys.argv[2], sys.argv[3] if gpu == "true": from setup_priority_tests import main @@ -13,6 +13,8 @@ else: test_names = get_all_tests() tests_per_run = 150 + if tracer == "true": + tests_per_run = 20 num_tests = len(test_names) start = run_iter * tests_per_run end = (run_iter + 1) * tests_per_run diff --git a/scripts/setup_tests/setup_failing_tests.py b/scripts/setup_tests/setup_failing_tests.py new file mode 100644 index 0000000000000..713d089910a99 --- /dev/null +++ b/scripts/setup_tests/setup_failing_tests.py @@ -0,0 +1,120 @@ +from get_all_tests import BACKENDS +from packaging import version +from pymongo import MongoClient +import requests +import sys + + +def get_latest_package_version(package_name): + try: + url = f"https://pypi.org/pypi/{package_name}/json" + response = requests.get(url, timeout=10) + response.raise_for_status() + package_info = response.json() + versions = list(package_info["releases"].keys()) + key = lambda x: version.parse(x) + return sorted(versions, key=key, reverse=True) + except requests.exceptions.RequestException: + print(f"Error: Failed to fetch package information for {package_name}.") + return None + + +def main(): + # connect to the database + priority = sys.argv[1] == "true" + run_iter = int(sys.argv[2]) - 1 + cluster = MongoClient( + "mongodb+srv://readonly-user:hvpwV5yVeZdgyTTm@cluster0.qdvf8q3.mongodb.net" + ) + ci_dashboard_db = cluster["ci_dashboard"] + ivy_tests_collection = ci_dashboard_db["ivy_tests"] + frontend_tests_collection = ci_dashboard_db["frontend_tests"] + + # iterate over demos and collect ivy and frontend functions used + ivy_test_docs = ivy_tests_collection.find() + frontend_test_docs = frontend_tests_collection.find() + ivy_functions = [ + ivy_test_doc["_id"] + for ivy_test_doc in ivy_test_docs + if not priority or ivy_test_doc.get("demos", None) + ] + frontend_functions = [ + frontend_test_doc["_id"] + for frontend_test_doc in frontend_test_docs + if not priority or frontend_test_doc.get("demos", None) + ] + ivy_functions = sorted(list(set(ivy_functions))) + frontend_functions = sorted(list(set(frontend_functions))) + versions = { + backend: [ + version_name.replace(".", "_") + for version_name in get_latest_package_version(backend) + ] + for backend in BACKENDS + } + + # find corresponding test paths for those functions + ivy_test_paths = [] + frontend_test_paths = [] + for function in ivy_functions: + print("function", function) + result = ivy_tests_collection.find_one({"_id": function}) + if result: + for backend in BACKENDS: + if backend in result: + for version_name in versions[backend]: + if version_name in result[backend]: + if "status" in result[backend][version_name]: + status = result[backend][version_name]["status"].get( + "cpu" + ) + if not status and status is not None: + ivy_test_paths.append( + f"{result['test_path']},{backend}" + ) + break + + for function in frontend_functions: + print("frontend function", function) + frontend = function.split(".")[0] + result = frontend_tests_collection.find_one({"_id": function}) + if result and frontend in versions: + for frontend_version in versions[frontend]: + if frontend_version in result: + backend_result = result[frontend_version] + for backend in BACKENDS: + if backend in backend_result: + for version_name in versions[backend]: + if version_name in backend_result[backend]: + if ( + "status" + in backend_result[backend][version_name] + ): + status = backend_result[backend][version_name][ + "status" + ].get("cpu") + if not status and status is not None: + frontend_test_paths.append( + f"{result['test_path']},{backend}" + ) + break + + all_tests = ivy_test_paths + frontend_test_paths + all_tests = [test_path.strip() for test_path in all_tests] + tests_per_run = 50 + num_tests = len(all_tests) + start = run_iter * tests_per_run + end = (run_iter + 1) * tests_per_run + end = min(end, num_tests) + if start < end: + tests = all_tests[start:end] + else: + tests = [] + + # add those paths to the tests_to_run + with open("tests_to_run", "w") as write_file: + write_file.write("\n".join(tests)) + + +if __name__ == "__main__": + main() diff --git a/scripts/setup_tests/setup_priority_tests.py b/scripts/setup_tests/setup_priority_tests.py index 6f1f85ea30e9e..7e124af88a828 100644 --- a/scripts/setup_tests/setup_priority_tests.py +++ b/scripts/setup_tests/setup_priority_tests.py @@ -10,16 +10,22 @@ def main(): ci_dashboard_db = cluster["ci_dashboard"] ivy_tests_collection = ci_dashboard_db["ivy_tests"] frontend_tests_collection = ci_dashboard_db["frontend_tests"] - demos_collection = ci_dashboard_db["demos"] # iterate over demos and collect ivy and frontend functions used - demos = demos_collection.find() - ivy_functions, frontend_functions = [], [] - for demo in demos: - ivy_functions += demo.get("ivy_functions", []) - frontend_functions += demo.get("frontend_functions", []) - ivy_functions = list(set(ivy_functions)) - frontend_functions = list(set(frontend_functions)) + ivy_test_docs = ivy_tests_collection.find() + frontend_test_docs = frontend_tests_collection.find() + ivy_functions = [ + ivy_test_doc["_id"] + for ivy_test_doc in ivy_test_docs + if ivy_test_doc.get("demos", None) + ] + frontend_functions = [ + frontend_test_doc["_id"] + for frontend_test_doc in frontend_test_docs + if frontend_test_doc.get("demos", None) + ] + ivy_functions = sorted(list(set(ivy_functions))) + frontend_functions = sorted(list(set(frontend_functions))) # find corresponding test paths for those functions ivy_test_paths = [] diff --git a/scripts/shell/deploy_pypi.sh b/scripts/shell/deploy_pypi.sh index c185f62dbb87d..cb51bbcc1e196 100644 --- a/scripts/shell/deploy_pypi.sh +++ b/scripts/shell/deploy_pypi.sh @@ -1,5 +1,6 @@ jq -c '.compiler[]' available_configs.json | while read config; do export TAG=${config:1:${#config}-2} + export CLEAN=true python -m build python3 scripts/rename_wheels.py done diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 5f868b342a912..0000000000000 --- a/setup.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[flake8] -max-line-length = 88 -ignore = E203, E402, E731, E704, W503, W504, W291, W293 - -per-file-ignores = - **/__init__.py: F401,F403,F405,F811,F821 - ivy/functional/frontends/paddle/**: F401,F403,F405 - -[autoflake] -in-place = true -remove-all-unused-imports = true -ignore-init-module-imports = true -remove-duplicate-keys = true -remove-unused-variables = true -quiet = true -ignore-pass-after-docstring = true -exclude = __init__.py - -[pydocstyle] -convention = numpy -add-ignore = D100,D101,D102,D103,D104,D105,D106,D107,D400,D205 - -[docformatter] -wrap-summaries = 88 -pre-summary-newline = true diff --git a/setup.py b/setup.py index e98695ecf1b84..02b111d8c7865 100644 --- a/setup.py +++ b/setup.py @@ -27,8 +27,9 @@ def _get_paths_from_binaries(binaries, root_dir=""): """Get all the paths from the binaries.json into a list.""" paths = [] + ext = "pyd" if os.name == "nt" else "so" if isinstance(binaries, str): - return [os.path.join(root_dir, binaries)] + return [os.path.join(root_dir, binaries + "." + ext)] elif isinstance(binaries, dict): for k, v in binaries.items(): paths += _get_paths_from_binaries(v, os.path.join(root_dir, k)) @@ -46,9 +47,10 @@ def _strip(line): binaries_dict = json.load(open("binaries.json")) available_configs = json.load(open("available_configs.json")) binaries_paths = _get_paths_from_binaries(binaries_dict) -version = os.environ["VERSION"] if "VERSION" in os.environ else "main" +version = os.environ.get("VERSION", "main") +fixed_tag = os.environ.get("TAG", None) +clean = os.environ.get("CLEAN", None) terminate = False -fixed_tag = os.environ["TAG"] if "TAG" in os.environ else None all_tags, python_tag, plat_name, options = None, None, None, None if fixed_tag: python_tag, _, plat_name = str(fixed_tag).split("-") @@ -65,11 +67,14 @@ def _strip(line): break for path in binaries_paths: module = path.split(os.sep)[1] - if os.path.exists(path) or str(tag) not in available_configs[module]: + if (os.path.exists(path) and not clean) or str(tag) not in available_configs[ + module + ]: continue folders = path.split(os.sep) folder_path, file_path = os.sep.join(folders[:-1]), folders[-1] - file_name = f"{file_path[:-3]}_{tag}.so" + ext = "pyd" if os.name == "nt" else "so" + file_name = f"{file_path[:-(len(ext)+1)]}_{tag}.{ext}" search_path = f"{module}/{file_name}" try: response = request.urlopen( diff --git a/wrappers.json b/wrappers.json new file mode 100644 index 0000000000000..fea73ecbb96e4 --- /dev/null +++ b/wrappers.json @@ -0,0 +1,200 @@ +{ + "ivy": { + "functional": ["negative.so", + "bitwise_xor.so", + "vander.so", + "std.so", + "atanh.so", + "argmin.so", + "asinh.so", + "squeeze.so", + "square.so", + "matrix_norm.so", + "not_equal.so", + "log.so", + "expand_dims.so", + "divide.so", + "min.so", + "unique_counts.so", + "vector_norm.so", + "matrix_rank.so", + "equal.so", + "expm1.so", + "sigmoid.so", + "adam_update.so", + "cumsum.so", + "lars_update.so", + "isinf.so", + "pinv.so", + "deg2rad.so", + "var.so", + "pow.so", + "random_uniform.so", + "trapz.so", + "adam_step.so", + "tile.so", + "tan.so", + "sparse_cross_entropy.so", + "det.so", + "round.so", + "acos.so", + "matrix_power.so", + "while_loop.so", + "cross.so", + "trunc.so", + "jac.so", + "sqrt.so", + "bitwise_left_shift.so", + "atan.so", + "clip.so", + "conv2d_transpose.so", + "exp2.so", + "less.so", + "conv2d.so", + "einsum.so", + "searchsorted.so", + "floor.so", + "cross_entropy.so", + "seed.so", + "scaled_dot_product_attention.so", + "bitwise_and.so", + "logaddexp2.so", + "optimizer_update.so", + "mish.so", + "mean.so", + "argsort.so", + "eigh.so", + "svd.so", + "cumprod.so", + "eigvalsh.so", + "asin.so", + "random_normal.so", + "try_except.so", + "split.so", + "log_softmax.so", + "nan_to_num.so", + "cmp_isnot.so", + "matrix_transpose.so", + "diag.so", + "remainder.so", + "sinh.so", + "bitwise_or.so", + "softplus.so", + "flip.so", + "conv_general_transpose.so", + "shuffle.so", + "roi_align.so", + "log1p.so", + "tensordot.so", + "zero_pad.so", + "logical_xor.so", + "inv.so", + "softmax.so", + "greater.so", + "logical_not.so", + "conv1d.so", + "vecdot.so", + "multi_head_attention.so", + "diagonal.so", + "isnan.so", + "inner.so", + "bitwise_invert.so", + "slogdet.so", + "tensorsolve.so", + "value_and_grad.so", + "depthwise_conv2d.so", + "trunc_divide.so", + "erf.so", + "svdvals.so", + "reshape.so", + "constant_pad.so", + "unique_all.so", + "qr.so", + "isfinite.so", + "logical_and.so", + "if_else.so", + "nonzero.so", + "tanh.so", + "conv.so", + "add.so", + "subtract.so", + "argmax.so", + "maximum.so", + "real.so", + "msort.so", + "fmin.so", + "abs.so", + "lstm_update.so", + "permute_dims.so", + "lamb_update.so", + "swapaxes.so", + "cosh.so", + "log10.so", + "bitwise_right_shift.so", + "for_loop.so", + "imag.so", + "dropout.so", + "where.so", + "roll.so", + "leaky_relu.so", + "fmod.so", + "randint.so", + "logical_or.so", + "relu.so", + "binary_cross_entropy.so", + "unique_values.so", + "linear.so", + "sin.so", + "vector_to_skew_symmetric_matrix.so", + "closest_valid_dtype.so", + "atan2.so", + "stack.so", + "max.so", + "sign.so", + "exp.so", + "cholesky.so", + "ceil.so", + "cmp_is.so", + "repeat.so", + "gelu.so", + "reciprocal.so", + "unstack.so", + "conv1d_transpose.so", + "less_equal.so", + "stop_gradient.so", + "angle.so", + "matmul.so", + "cos.so", + "execute_with_gradients.so", + "gradient_descent_update.so", + "softsign.so", + "unique_inverse.so", + "solve.so", + "sum.so", + "argwhere.so", + "greater_equal.so", + "outer.so", + "rad2deg.so", + "floor_divide.so", + "conv_general_dilated.so", + "logaddexp.so", + "concat.so", + "positive.so", + "minimum.so", + "log2.so", + "lcm.so", + "acosh.so", + "conv3d_transpose.so", + "multinomial.so", + "lu_factor.so", + "layer_norm.so", + "eig.so", + "conv3d.so", + "sort.so", + "isreal.so", + "multiply.so", + "gcd.so", + "grad.so", + "prod.so"] + } +}