diff --git a/.github/workflows/deploy-cpp.yml b/.github/workflows/deploy-cpp.yml index ea39676f55..4d01fce65d 100644 --- a/.github/workflows/deploy-cpp.yml +++ b/.github/workflows/deploy-cpp.yml @@ -91,7 +91,7 @@ jobs: - name: Prepare build files run: pipx run nox -s prepare - - uses: pypa/cibuildwheel@v2.12.1 + - uses: pypa/cibuildwheel@v2.13.1 env: CIBW_BUILD: ${{ matrix.build }} CIBW_ARCHS: ${{ matrix.arch }} @@ -138,9 +138,9 @@ jobs: - name: Prepare build files run: pipx run nox -s prepare - - uses: docker/setup-qemu-action@v2.1.0 + - uses: docker/setup-qemu-action@v2.2.0 - - uses: pypa/cibuildwheel@v2.12.1 + - uses: pypa/cibuildwheel@v2.13.1 env: CIBW_BUILD: cp${{ matrix.python }}-* CIBW_ARCHS: ${{ matrix.arch }} @@ -166,12 +166,14 @@ jobs: needs: [build_wheels, build_alt_wheels, make_sdist] runs-on: ubuntu-latest if: inputs.publish-pypi + permissions: + id-token: write + environment: + name: "deploy-cpp-pypi" steps: - uses: actions/download-artifact@v3 with: name: artifact path: dist - - uses: pypa/gh-action-pypi-publish@v1.8.5 - with: - password: ${{ secrets.PYPI_PASSWORD_CPP }} + - uses: pypa/gh-action-pypi-publish@v1.8.6 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 948d4a3764..4b2fea4d2b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -102,15 +102,17 @@ jobs: needs: [build, check-requirements, check-cpp-on-pypi] runs-on: ubuntu-latest if: (github.event_name == 'release' && github.event.action == 'published') || inputs.publish-pypi + permissions: + id-token: write + environment: + name: "deploy-pypi" steps: - uses: actions/download-artifact@v3 with: name: distributions path: dist - - uses: pypa/gh-action-pypi-publish@v1.8.5 - with: - password: ${{ secrets.PYPI_PASSWORD }} + - uses: pypa/gh-action-pypi-publish@v1.8.6 publish-headers: name: "Publish header-only libraries alongside release" diff --git a/.github/workflows/docs-version.yml b/.github/workflows/docs-version.yml new file mode 100644 index 0000000000..53c9b889c6 --- /dev/null +++ b/.github/workflows/docs-version.yml @@ -0,0 +1,38 @@ +name: Sync Docs Selector + +on: + push: + branches: + - main + paths: + - docs/switcher.json + +concurrency: + group: 'docs-version-${{ github.head_ref || github.run_id }}' + cancel-in-progress: true + +jobs: + coverage: + runs-on: ubuntu-20.04 + name: Push version switcher + permissions: + id-token: write + contents: read + env: + S3_BUCKET: "awkward-array.org" + CLOUDFRONT_ID: "EFM4QVENUIXHS" + environment: + name: docs-prod + steps: + - uses: actions/checkout@v3 + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE }} + # Pushes to main trigger latest + - name: Push version selector + run: | + aws s3 cp docs/switcher.json "s3://${S3_BUCKET}/doc/switcher.json" + aws cloudfront create-invalidation --distribution-id "${CLOUDFRONT_ID}" \ + --paths "/doc/switcher.json" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a9a76887a3..2856fe7529 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -81,13 +81,13 @@ jobs: # solve with different external library versions. By default, # ROOT uses cxx-compiler too, so hopefully this won't be an issue - name: Setup Python via Conda - uses: mamba-org/provision-with-micromamba@main + uses: mamba-org/setup-micromamba@v1 with: # Cache invalidates daily by default - cache-env: true + cache-environment: true cache-downloads: true environment-file: docs/environment.yml - extra-specs: | + create-args: >- python=${{ env.PYTHON_VERSION }} doxygen @@ -157,13 +157,13 @@ jobs: # solve with different external library versions. By default, # ROOT uses cxx-compiler too, so hopefully this won't be an issue - name: Setup Python via Conda - uses: mamba-org/provision-with-micromamba@main + uses: mamba-org/setup-micromamba@v1 with: # Cache invalidates daily by default - cache-env: true + cache-environment: true cache-downloads: true environment-file: docs/environment.yml - extra-specs: | + create-args: >- python=${{ env.PYTHON_VERSION }} doxygen diff --git a/.github/workflows/packaging-test.yml b/.github/workflows/packaging-test.yml index 6f03953b16..eba3002284 100644 --- a/.github/workflows/packaging-test.yml +++ b/.github/workflows/packaging-test.yml @@ -56,7 +56,7 @@ jobs: - name: Prepare build files run: pipx run nox -s prepare - - uses: pypa/cibuildwheel@v2.12.1 + - uses: pypa/cibuildwheel@v2.13.1 env: CIBW_ARCHS_MACOS: universal2 CIBW_BUILD: cp39-win_amd64 cp37-manylinux_x86_64 cp38-macosx_universal2 @@ -64,7 +64,7 @@ jobs: config-file: cibuildwheel.toml package-dir: awkward-cpp - - uses: pypa/cibuildwheel@v2.12.1 + - uses: pypa/cibuildwheel@v2.13.1 if: matrix.os == 'ubuntu-latest' env: CIBW_BUILD: cp311-manylinux_x86_64 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e3231a3756..d3fd610691 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -91,7 +91,7 @@ jobs: run: pipx run nox -s diagnostics -- --check-spec-sorted - name: Install test requirements - run: python -m pip install -v -r requirements-test.txt + run: python -m pip install -v -r requirements-test.txt pytest-github-actions-annotate-failures - name: Test specification if: steps.cache-awkward-cpp-wheel.outputs.cache-hit != 'true' @@ -162,7 +162,7 @@ jobs: run: pipx run nox -s diagnostics -- --check-spec-sorted - name: Install test requirements - run: python -m pip install -v -r requirements-test.txt + run: python -m pip install -v -r requirements-test.txt pytest-github-actions-annotate-failures - name: Test specification if: steps.cache-awkward-cpp-wheel.outputs.cache-hit != 'true' @@ -238,7 +238,7 @@ jobs: run: pipx run nox -s diagnostics -- --check-spec-sorted - name: Install test requirements - run: python -m pip install -v -r requirements-test.txt + run: python -m pip install -v -r requirements-test.txt pytest-github-actions-annotate-failures - name: Test specification if: steps.cache-awkward-cpp-wheel.outputs.cache-hit != 'true' @@ -285,14 +285,12 @@ jobs: submodules: true - name: Setup Python via Conda - uses: mamba-org/provision-with-micromamba@main + uses: mamba-org/setup-micromamba@v1 with: # Cache invalidates daily by default - cache-env: true - environment-file: false + cache-environment: true environment-name: awkward - channels: conda-forge - extra-specs: | + create-args: >- python=${{ env.PYTHON_VERSION }} numpy root @@ -323,7 +321,7 @@ jobs: run: python -m pip list - name: Install test requirements - run: python -m pip install -v -r requirements-test.txt + run: python -m pip install -v -r requirements-test.txt pytest-github-actions-annotate-failures - name: Test run: python -m pytest -vv -rs tests diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5b93dc0abf..83603259e9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ repos: args: ["--pytest-test-first"] - repo: https://github.com/asottile/setup-cfg-fmt - rev: v2.2.0 + rev: v2.3.0 hooks: - id: setup-cfg-fmt args: [--include-version-classifiers, --max-py-version=3.11] @@ -39,7 +39,7 @@ repos: additional_dependencies: [pyyaml] - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.261 + rev: v0.0.272 hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -59,7 +59,7 @@ repos: exclude: .pre-commit-config.yaml - repo: https://github.com/shellcheck-py/shellcheck-py - rev: "v0.9.0.2" + rev: "v0.9.0.5" hooks: - id: shellcheck diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 33a5b5adc9..491d327a4b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -271,11 +271,16 @@ There are two kinds of releases: (1) `awkward-cpp` updates, which only occur whe If you need your merged pull request to be deployed in a release, just ask! -#### Awkward-cpp releases -When making an `awkward-cpp` release (1), the following manual steps must also be taken: -- Creating a `git` tag `awkward-cpp-{version}` for the new version epoch. - -#### Awkward releases -When making an `awkward` release (2), the following manual steps must also be taken: -- Attaching the `headers.zip` from the `deploy.yml` workflow to the release artefacts. -- Adding a `doc/switcher.json` entry for new minor/major versions. +#### `awkward-cpp` releases +To make an `awkward-cpp` release: +1. A commit to `main` should increase the version number in `awkward-cpp/pyproject.toml` +2. The [Deploy C++](https://github.com/scikit-hep/awkward/actions/workflows/deploy-cpp.yml) GitHub Actions workflow should be manually triggered. +3. A `git` tag `awkward-cpp-{version}` should be created for the new version epoch. + +#### `awkward` releases +To make an `awkward` release: +1. A commit to `main` should increase the version number in `pyproject.toml` +2. A new GitHub release must be published. +3. A `docs/switcher.json` entry must be added for new minor/major versions. + +Pushes that modify `docs/switcher.json` on `main` will automatically be synchronised with AWS. diff --git a/awkward-cpp/include/awkward/common.h b/awkward-cpp/include/awkward/common.h index 619241f0f3..cc84c6de47 100644 --- a/awkward-cpp/include/awkward/common.h +++ b/awkward-cpp/include/awkward/common.h @@ -58,7 +58,6 @@ extern "C" { const char* filename; int64_t identity; int64_t attempt; - bool pass_through; }; const int8_t kMaxInt8 = 127; // 2**7 - 1 @@ -76,7 +75,6 @@ extern "C" { out.filename = nullptr; out.identity = kSliceNone; out.attempt = kSliceNone; - out.pass_through = false; return out; }; @@ -91,22 +89,6 @@ extern "C" { out.filename = filename; out.identity = identity; out.attempt = attempt; - out.pass_through = false; - return out; - }; - - inline struct Error - failure_pass_through( - const char* str, - int64_t identity, - int64_t attempt, - const char* filename) { - struct Error out; - out.str = str; - out.filename = filename; - out.identity = identity; - out.attempt = attempt; - out.pass_through = true; return out; }; } diff --git a/awkward-cpp/include/awkward/datetime_util.h b/awkward-cpp/include/awkward/datetime_util.h deleted file mode 100644 index f7ca08d445..0000000000 --- a/awkward-cpp/include/awkward/datetime_util.h +++ /dev/null @@ -1,112 +0,0 @@ -// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE - -#ifndef AWKWARD_DATETIME_UTIL_H_ -#define AWKWARD_DATETIME_UTIL_H_ - -#include -#include -#include -#include -#include - -#include "awkward/common.h" - -#ifndef _MSC_VER - #include "dlfcn.h" -#endif - -namespace awkward { - - namespace util { - /// @brief Convert a format string into a datetime units string. - const std::string - format_to_units(const std::string& format); - - /// @brief Convert a datetime units string into a format string. - const std::string - units_to_format(dtype dt, const std::string& units, int64_t step); - - template - struct NameValuePair { - using value_type = T; - const T value; - const char* const name; - const int64_t scale_up; - const int64_t scale_down; - }; - - template - std::string name(Mapping a, V value) { - auto pos = std::find_if( - std::begin(a), std::end(a), [&value](const typename Mapping::value_type& t) { return ((V)t.value == value); }); - if (pos != std::end(a)) { - return pos->name; - } - return std::begin(a)->name; - } - - template - typename Mapping::value_type::value_type value(Mapping a, const std::string& name) { - auto unit_name(name); - std::string chars = "[]1234567890"; - unit_name.erase(remove_if(unit_name.begin(), unit_name.end(), - [&chars](const char &c) { - return chars.find(c) != std::string::npos; - }), - unit_name.end()); - auto pos = std::find_if( - std::begin(a), std::end(a), [&](const typename Mapping::value_type& t) { - return (unit_name == t.name); - }); - if (pos != std::end(a)) { - return pos->value; - } - return std::begin(a)->value; - } - - /// @brief Valid datetime units. - /// Different units of two datetime type Arrays will be normalized to - /// the smallest unit (== a larger enum value). - enum class datetime_units { - unknown = -1, // unknown - Y = 1, // year - M = 2, // month - W = 3, // week - D = 4, // day - h = 5, // hour - m = 6, // minute - s = 7, // second - ms = 8, // millisecond - us = 9, // microsecond: note, 'μs' string is not supported - ns = 10, // nanosecond - ps = 11, // picosecond - fs = 12, // femtosecond - as = 13, // attosecond - }; - - // One calendar common year has 365 days: 31536000 seconds - // One calendar leap year has 366 days: 31622400 seconds - const std::array, 14> units_map { - {{datetime_units::unknown, "unknown", 1, 1}, - {datetime_units::Y, "Y", 31556952, 1}, // seconds in average Gregorian year - {datetime_units::M, "M", 2629746, 1}, - {datetime_units::W, "W", 604800, 1}, - {datetime_units::D, "D", 86400, 1}, - {datetime_units::h, "h", 3600, 1}, - {datetime_units::m, "m", 60, 1}, - {datetime_units::s, "s", 1, 1}, - {datetime_units::ms, "ms", 1, 1000}, - {datetime_units::us, "us", 1, 1000000}, - {datetime_units::ns, "ns", 1, 1000000000}, - {datetime_units::ps, "ps", 1, 1000000000000}, - {datetime_units::fs, "fs", 1, 1000000000000000}, - {datetime_units::as, "as", 1, 1000000000000000000}} - }; - - std::tuple datetime_data(const std::string& format); - - double scale_from_units(const std::string& format, uint64_t index); - } -} - -#endif // AWKWARD_DATETIME_UTIL_H_ diff --git a/awkward-cpp/include/awkward/python/content.h b/awkward-cpp/include/awkward/python/content.h index ba3655deeb..215078e3e1 100644 --- a/awkward-cpp/include/awkward/python/content.h +++ b/awkward-cpp/include/awkward/python/content.h @@ -13,26 +13,6 @@ namespace py = pybind11; namespace ak = awkward; -template -std::string -repr(const T& self) { - return self.tostring(); -} - -template -int64_t -len(const T& self) { - return self.length(); -} - -int64_t -check_maxdecimals(const py::object& maxdecimals); - -ak::util::Parameters -dict2parameters(const py::object& in); - -py::dict -parameters2dict(const ak::util::Parameters& in); /// @brief Makes an ArrayBuilder class in Python that mirrors the one in C++. py::class_ diff --git a/awkward-cpp/include/awkward/util.h b/awkward-cpp/include/awkward/util.h index 117a60b112..25d79f3395 100644 --- a/awkward-cpp/include/awkward/util.h +++ b/awkward-cpp/include/awkward/util.h @@ -42,57 +42,14 @@ namespace awkward { size }; - /// @brief Returns the name associated with a given dtype. - dtype - name_to_dtype(const std::string& name); - /// @brief Returns the name associated with a given dtype. const std::string dtype_to_name(dtype dt); - /// @brief Convert a NumPy format string and itemsize into a dtype enum. - dtype - format_to_dtype(const std::string& format, int64_t itemsize); - /// @brief Convert a dtype enum into a NumPy format string. const std::string dtype_to_format(dtype dt, const std::string& format = ""); - /// @brief Convert a dtype enum into an itemsize. - int64_t - dtype_to_itemsize(dtype dt); - - /// @brief True if the dtype is a non-boolean integer (signed or unsigned). - bool - is_integer(dtype dt); - - /// @brief True if the dtype is a signed integer. - bool - is_signed(dtype dt); - - /// @brief True if the dtype is an unsigned integer. - bool - is_unsigned(dtype dt); - - /// @brief True if the dtype is a non-complex floating point number. - bool - is_real(dtype dt); - - /// @brief True if the dtype is a complex number. - bool - is_complex(dtype dt); - - /// @brief If the Error struct contains an error message (from a - /// cpu-kernel through the C interface), raise that error as a C++ - /// exception. - /// - /// @param err The Error struct from a cpu-kernel. - /// @param classname The name of this class to include in the error - /// message. - void - handle_error(const struct Error &err, - const std::string &classname = std::string("")); - /// @brief Puts quotation marks around a string and escapes the appropriate /// characters. /// @@ -106,100 +63,6 @@ namespace awkward { std::string quote(const std::string& x); - using RecordLookup = std::vector; - using RecordLookupPtr = std::shared_ptr; - - /// @brief Initializes a RecordLookup by assigning each element with - /// a string representation of its field index position. - /// - /// For example, if `numfields = 3`, the return value is `["0", "1", "2"]`. - RecordLookupPtr - init_recordlookup(int64_t numfields); - - /// @brief Returns the field index associated with a key, given - /// a RecordLookup and a number of fields. - int64_t - fieldindex(const RecordLookupPtr& recordlookup, - const std::string& key, - int64_t numfields); - - /// @brief Returns the key associated with a field index, given a - /// RecordLookup and a number of fields. - const std::string - key(const RecordLookupPtr& recordlookup, - int64_t fieldindex, - int64_t numfields); - - /// @brief Returns `true` if a RecordLookup has a given `key`; `false` - /// otherwise. - bool - haskey(const RecordLookupPtr& recordlookup, - const std::string& key, - int64_t numfields); - - /// @brief Returns a given RecordLookup as keys or generate anonymous ones - /// form a number of fields. - const std::vector - keys(const RecordLookupPtr& recordlookup, int64_t numfields); - - using Parameters = std::map; - - /// @brief Returns `true` if `myvalue` is equal to `value` when interpreted - /// as JSON. - bool - json_equals(const std::string &myvalue, const std::string &value); - - /// @brief Returns `true` if the value associated with a `key` in - /// `parameters` is equal to the specified `value`. - /// - /// Keys are simple strings, but values are JSON-encoded strings. - /// For this reason, values that represent single strings are - /// double-quoted: e.g. `"\"actual_value\""`. - bool - parameter_equals(const Parameters& parameters, - const std::string& key, - const std::string& value); - - /// @brief Returns `true` if all key-value pairs in `self` is equal to - /// all key-value pairs in `other`. - /// - /// Keys are simple strings, but values are JSON-encoded strings. - /// For this reason, values that represent single strings are - /// double-quoted: e.g. `"\"actual_value\""`. - /// - /// If `check_all`, every parameter is checked; otherwise, only - /// `"__array__"` and `"__record__"` are checked. - bool - parameters_equal(const Parameters& self, const Parameters& other, bool check_all); - - /// @brief Merges a set of `input` parameters with `output`, keeping - /// only those that are common to all sets. - void - merge_parameters(Parameters& output, const Parameters& input); - - /// @brief Returns `true` if the parameter associated with `key` is a - /// string; `false` otherwise. - bool - parameter_isstring(const Parameters& parameters, const std::string& key); - - /// @brief Returns `true` if the parameter associated with `key` is a - /// string that matches `[A-Za-z_][A-Za-z_0-9]*`; `false` otherwise. - bool - parameter_isname(const Parameters& parameters, const std::string& key); - - /// @brief Returns the parameter associated with `key` as a string if - /// #parameter_isstring; raises an error otherwise. - const std::string - parameter_asstring(const Parameters& parameters, const std::string& key); - - using TypeStrs = std::map; - - /// @brief Extracts a custom type string from `typestrs` if required by - /// one of the `parameters` or an empty string if there is no match. - std::string - gettypestr(const Parameters& parameters, - const TypeStrs& typestrs); - /// @brief Exhaustive list of runtime errors possible in the ForthMachine. enum class ForthError { // execution can continue diff --git a/awkward-cpp/pyproject.toml b/awkward-cpp/pyproject.toml index c3cd2530c4..ea9c2bfff5 100644 --- a/awkward-cpp/pyproject.toml +++ b/awkward-cpp/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "scikit_build_core.build" [project] name = "awkward_cpp" -version = "14" +version = "17" dependencies = [ "numpy>=1.17.0" ] diff --git a/awkward-cpp/src/cpu-kernels/awkward_ListOffsetArray_compact_offsets.cpp b/awkward-cpp/src/cpu-kernels/awkward_ListOffsetArray_compact_offsets.cpp deleted file mode 100644 index f4334be762..0000000000 --- a/awkward-cpp/src/cpu-kernels/awkward_ListOffsetArray_compact_offsets.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE - -#define FILENAME(line) FILENAME_FOR_EXCEPTIONS_C("src/cpu-kernels/awkward_ListOffsetArray_compact_offsets.cpp", line) - -#include "awkward/kernels.h" - -template -ERROR awkward_ListOffsetArray_compact_offsets( - T* tooffsets, - const C* fromoffsets, - int64_t length) { - int64_t diff = (int64_t)fromoffsets[0]; - tooffsets[0] = 0; - for (int64_t i = 0; i < length; i++) { - tooffsets[i + 1] = fromoffsets[i + 1] - diff; - } - return success(); -} -ERROR awkward_ListOffsetArray32_compact_offsets_64( - int64_t* tooffsets, - const int32_t* fromoffsets, - int64_t length) { - return awkward_ListOffsetArray_compact_offsets( - tooffsets, - fromoffsets, - length); -} -ERROR awkward_ListOffsetArrayU32_compact_offsets_64( - int64_t* tooffsets, - const uint32_t* fromoffsets, - int64_t length) { - return awkward_ListOffsetArray_compact_offsets( - tooffsets, - fromoffsets, - length); -} -ERROR awkward_ListOffsetArray64_compact_offsets_64( - int64_t* tooffsets, - const int64_t* fromoffsets, - int64_t length) { - return awkward_ListOffsetArray_compact_offsets( - tooffsets, - fromoffsets, - length); -} diff --git a/awkward-cpp/src/cpu-kernels/awkward_RecordArray_reduce_nonlocal_outoffsets_64.cpp b/awkward-cpp/src/cpu-kernels/awkward_RecordArray_reduce_nonlocal_outoffsets_64.cpp new file mode 100644 index 0000000000..5f3ab89174 --- /dev/null +++ b/awkward-cpp/src/cpu-kernels/awkward_RecordArray_reduce_nonlocal_outoffsets_64.cpp @@ -0,0 +1,55 @@ +// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +#define FILENAME(line) FILENAME_FOR_EXCEPTIONS_C("src/cpu-kernels/awkward_RecordArray_reduce_local_outoffsets_64.cpp", line) + +#include "awkward/kernels.h" + +ERROR awkward_RecordArray_reduce_nonlocal_outoffsets_64( + int64_t* outoffsets, + int64_t* outcarry, + const int64_t* parents, + int64_t lenparents, + int64_t outlength) { + int64_t i = 0; + int64_t j_stop = 0; + int64_t k_sublist = 0; + + // The first offset is always 0 + outoffsets[0] = 0; + + // Initialise carry to unique value, indicating "missing" parent + for (i = 0; i < outlength; i++) { + outcarry[i] = -1; + } + + // Fill offsets with stop index of sublists in parents array. Ignore ordering given by parents, this is done by subsequent carry + i = 0; + for (j_stop = 1; j_stop < lenparents; j_stop++) { + if (parents[i] != parents[j_stop]) { + outoffsets[k_sublist + 1] = j_stop; + outcarry[parents[i]] = k_sublist; + i = j_stop; + k_sublist++; + } + } + // Close the last sublist! + if (lenparents > 0) { + outoffsets[k_sublist + 1] = j_stop; + outcarry[parents[i]] = k_sublist; + i = j_stop; + k_sublist++; + } + + // Append empty lists for missing parents + for (i = k_sublist; i < outlength; i++) { + outoffsets[i + 1] = lenparents; + } + + // Replace unique value with index of appended empty lists + for (i = 0; i <= outlength; i++) { + if (outcarry[i] == -1) { + outcarry[i] = k_sublist++; + } + } + return success(); +} diff --git a/awkward-cpp/src/cpu-kernels/awkward_RegularArray_broadcast_tooffsets.cpp b/awkward-cpp/src/cpu-kernels/awkward_RegularArray_broadcast_tooffsets.cpp deleted file mode 100644 index c91379b264..0000000000 --- a/awkward-cpp/src/cpu-kernels/awkward_RegularArray_broadcast_tooffsets.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE - -#define FILENAME(line) FILENAME_FOR_EXCEPTIONS_C("src/cpu-kernels/awkward_RegularArray_broadcast_tooffsets.cpp", line) - -#include "awkward/kernels.h" - -template -ERROR awkward_RegularArray_broadcast_tooffsets( - const T* fromoffsets, - int64_t offsetslength, - int64_t size) { - for (int64_t i = 0; i < offsetslength - 1; i++) { - int64_t count = (int64_t)(fromoffsets[i + 1] - fromoffsets[i]); - if (count < 0) { - return failure("broadcast's offsets must be monotonically increasing", i, kSliceNone, FILENAME(__LINE__)); - } - if (size != count) { - return failure("cannot broadcast nested list", i, kSliceNone, FILENAME(__LINE__)); - } - } - return success(); -} -ERROR awkward_RegularArray_broadcast_tooffsets_64( - const int64_t* fromoffsets, - int64_t offsetslength, - int64_t size) { - return awkward_RegularArray_broadcast_tooffsets( - fromoffsets, - offsetslength, - size); -} diff --git a/awkward-cpp/src/cpu-kernels/awkward_RegularArray_broadcast_tooffsets_size1.cpp b/awkward-cpp/src/cpu-kernels/awkward_RegularArray_broadcast_tooffsets_size1.cpp deleted file mode 100644 index 126371e683..0000000000 --- a/awkward-cpp/src/cpu-kernels/awkward_RegularArray_broadcast_tooffsets_size1.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE - -#define FILENAME(line) FILENAME_FOR_EXCEPTIONS_C("src/cpu-kernels/awkward_RegularArray_broadcast_tooffsets_size1.cpp", line) - -#include "awkward/kernels.h" - -template -ERROR awkward_RegularArray_broadcast_tooffsets_size1( - T* tocarry, - const T* fromoffsets, - int64_t offsetslength) { - int64_t k = 0; - for (int64_t i = 0; i < offsetslength - 1; i++) { - int64_t count = (int64_t)(fromoffsets[i + 1] - fromoffsets[i]); - if (count < 0) { - return failure("broadcast's offsets must be monotonically increasing", i, kSliceNone, FILENAME(__LINE__)); - } - for (int64_t j = 0; j < count; j++) { - tocarry[k] = (T)i; - k++; - } - } - return success(); -} -ERROR awkward_RegularArray_broadcast_tooffsets_size1_64( - int64_t* tocarry, - const int64_t* fromoffsets, - int64_t offsetslength) { - return awkward_RegularArray_broadcast_tooffsets_size1( - tocarry, - fromoffsets, - offsetslength); -} diff --git a/awkward-cpp/src/cpu-kernels/awkward_RegularArray_compact_offsets.cpp b/awkward-cpp/src/cpu-kernels/awkward_RegularArray_compact_offsets.cpp deleted file mode 100644 index 93d54eb679..0000000000 --- a/awkward-cpp/src/cpu-kernels/awkward_RegularArray_compact_offsets.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE - -#define FILENAME(line) FILENAME_FOR_EXCEPTIONS_C("src/cpu-kernels/awkward_RegularArray_compact_offsets.cpp", line) - -#include "awkward/kernels.h" - -template -ERROR awkward_RegularArray_compact_offsets( - T* tooffsets, - int64_t length, - int64_t size) { - tooffsets[0] = 0; - for (int64_t i = 0; i < length; i++) { - tooffsets[i + 1] = (i + 1)*size; - } - return success(); -} -ERROR awkward_RegularArray_compact_offsets64( - int64_t* tooffsets, - int64_t length, - int64_t size) { - return awkward_RegularArray_compact_offsets( - tooffsets, - length, - size); -} diff --git a/awkward-cpp/src/libawkward/builder/DatetimeBuilder.cpp b/awkward-cpp/src/libawkward/builder/DatetimeBuilder.cpp index 44265bd334..b7ea9b95ef 100644 --- a/awkward-cpp/src/libawkward/builder/DatetimeBuilder.cpp +++ b/awkward-cpp/src/libawkward/builder/DatetimeBuilder.cpp @@ -11,7 +11,6 @@ #include "awkward/builder/DatetimeBuilder.h" #include "awkward/util.h" -#include "awkward/datetime_util.h" namespace awkward { const BuilderPtr diff --git a/awkward-cpp/src/libawkward/util.cpp b/awkward-cpp/src/libawkward/util.cpp index 0d423919df..02b941559a 100644 --- a/awkward-cpp/src/libawkward/util.cpp +++ b/awkward-cpp/src/libawkward/util.cpp @@ -8,78 +8,13 @@ #include "rapidjson/document.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/writer.h" - -#include "awkward/kernels.h" - #include "awkward/util.h" -#include "awkward/datetime_util.h" namespace rj = rapidjson; namespace awkward { namespace util { - dtype - name_to_dtype(const std::string& name) { - if (name == "bool") { - return util::dtype::boolean; - } - else if (name == "int8") { - return util::dtype::int8; - } - else if (name == "int16") { - return util::dtype::int16; - } - else if (name == "int32") { - return util::dtype::int32; - } - else if (name == "int64") { - return util::dtype::int64; - } - else if (name == "uint8") { - return util::dtype::uint8; - } - else if (name == "uint16") { - return util::dtype::uint16; - } - else if (name == "uint32") { - return util::dtype::uint32; - } - else if (name == "uint64") { - return util::dtype::uint64; - } - else if (name == "float16") { - return util::dtype::float16; - } - else if (name == "float32") { - return util::dtype::float32; - } - else if (name == "float64") { - return util::dtype::float64; - } - else if (name == "float128") { - return util::dtype::float128; - } - else if (name == "complex64") { - return util::dtype::complex64; - } - else if (name == "complex128") { - return util::dtype::complex128; - } - else if (name == "complex256") { - return util::dtype::complex256; - } - else if (name.rfind("datetime64", 0) == 0) { - return util::dtype::datetime64; - } - else if (name.rfind("timedelta64", 0) == 0) { - return util::dtype::timedelta64; - } - else { - return util::dtype::NOT_PRIMITIVE; - } - } - const std::string dtype_to_name(dtype dt) { switch (dt) { @@ -124,103 +59,6 @@ namespace awkward { } } - dtype - format_to_dtype(const std::string& format, int64_t itemsize) { - int32_t test = 1; - bool little_endian = (*(int8_t*)&test == 1); - - std::string fmt = format; - if (format.length() > 1) { - std::string endianness = format.substr(0, 1); - if ((endianness == ">" && !little_endian) || - (endianness == "<" && little_endian) || - (endianness == "=")) { - fmt = format.substr(1, format.length() - 1); - } - else if ((endianness == ">" && little_endian) || - (endianness == "<" && !little_endian)) { - return dtype::NOT_PRIMITIVE; - } - } - - if (fmt == std::string("?")) { - return dtype::boolean; - } - else if (fmt == std::string("b") || - fmt == std::string("h") || - fmt == std::string("i") || - fmt == std::string("l") || - fmt == std::string("q")) { - if (itemsize == 1) { - return dtype::int8; - } - else if (itemsize == 2) { - return dtype::int16; - } - else if (itemsize == 4) { - return dtype::int32; - } - else if (itemsize == 8) { - return dtype::int64; - } - else { - return dtype::NOT_PRIMITIVE; - } - } - else if (fmt == std::string("c") || - fmt == std::string("B") || - fmt == std::string("H") || - fmt == std::string("I") || - fmt == std::string("L") || - fmt == std::string("Q")) { - if (itemsize == 1) { - return dtype::uint8; - } - else if (itemsize == 2) { - return dtype::uint16; - } - else if (itemsize == 4) { - return dtype::uint32; - } - else if (itemsize == 8) { - return dtype::uint64; - } - else { - return dtype::NOT_PRIMITIVE; - } - } - else if (fmt == std::string("e")) { - return dtype::float16; - } - else if (fmt == std::string("f")) { - return dtype::float32; - } - else if (fmt == std::string("d")) { - return dtype::float64; - } - else if (fmt == std::string("g")) { - return dtype::float128; - } - else if (fmt == std::string("Zf")) { - return dtype::complex64; - } - else if (fmt == std::string("Zd")) { - return dtype::complex128; - } - else if (fmt == std::string("Zg")) { - return dtype::complex256; - } - else if (fmt.substr(0, 2) == std::string("M8")) { - return dtype::datetime64; - } - else if (fmt.substr(0, 2) == std::string("m8")) { - return dtype::timedelta64; - } - else { - return dtype::NOT_PRIMITIVE; - } - } - const std::string dtype_to_format(dtype dt, const std::string& format) { switch (dt) { @@ -281,172 +119,6 @@ namespace awkward { } } - const std::string - format_to_units(const std::string& format) { - auto pos_from = format.find('['); - if (pos_from != std::string::npos) { - auto pos_to = format.find(']'); - if (pos_to != std::string::npos) { - return format.substr(format.find('['), format.find(']')); - } - } - return std::string("[us]"); - } - - const std::string - units_to_format(dtype dt, const std::string& units, int64_t step) { - std::string result; - switch (dt) { - case dtype::datetime64: - result.append("M"); - break; - case dtype::timedelta64: - result.append("m"); - break; - default: - break; - } - result.append(std::to_string(dtype_to_itemsize(dt))).append("["); - if (step > 1) { - result.append(std::to_string(step)); - } - result.append(units).append("]"); - return result; - } - - int64_t - dtype_to_itemsize(dtype dt) { - switch (dt) { - case dtype::boolean: - return 1; - case dtype::int8: - return 1; - case dtype::int16: - return 2; - case dtype::int32: - return 4; - case dtype::int64: - return 8; - case dtype::uint8: - return 1; - case dtype::uint16: - return 2; - case dtype::uint32: - return 4; - case dtype::uint64: - return 8; - case dtype::float16: - return 2; - case dtype::float32: - return 4; - case dtype::float64: - return 8; - case dtype::float128: - return 16; - case dtype::complex64: - return 8; - case dtype::complex128: - return 16; - case dtype::complex256: - return 32; - case dtype::datetime64: - return 8; - case dtype::timedelta64: - return 8; - default: - return 0; - } - } - - bool - is_integer(dtype dt) { - switch (dt) { - case dtype::int8: - case dtype::int16: - case dtype::int32: - case dtype::int64: - case dtype::uint8: - case dtype::uint16: - case dtype::uint32: - case dtype::uint64: - return true; - default: - return false; - } - } - - bool - is_signed(dtype dt) { - switch (dt) { - case dtype::int8: - case dtype::int16: - case dtype::int32: - case dtype::int64: - return true; - default: - return false; - } - } - - bool - is_unsigned(dtype dt) { - switch (dt) { - case dtype::uint8: - case dtype::uint16: - case dtype::uint32: - case dtype::uint64: - return true; - default: - return false; - } - } - - bool - is_real(dtype dt) { - switch (dt) { - case dtype::float16: - case dtype::float32: - case dtype::float64: - case dtype::float128: - return true; - default: - return false; - } - } - - bool - is_complex(dtype dt) { - switch (dt) { - case dtype::complex64: - case dtype::complex128: - case dtype::complex256: - return true; - default: - return false; - } - } - - void - handle_error(const struct Error& err, - const std::string& classname) { - std::string filename = (err.filename == nullptr ? "" : err.filename); - - if (err.pass_through == true) { - throw std::invalid_argument(std::string(err.str) + filename); - } - else { - if (err.str != nullptr) { - std::stringstream out; - out << "in " << classname; - if (err.attempt != kSliceNone) { - out << " attempting to get " << err.attempt; - } - out << ", " << err.str << filename; - throw std::invalid_argument(out.str()); - } - } - } - std::string quote(const std::string &x) { rj::StringBuffer buffer; @@ -454,143 +126,5 @@ namespace awkward { writer.String(x.c_str(), (rj::SizeType)x.length()); return std::string(buffer.GetString()); } - - RecordLookupPtr - init_recordlookup(int64_t numfields) { - RecordLookupPtr out = std::make_shared(); - for (int64_t i = 0; i < numfields; i++) { - out.get()->push_back(std::to_string(i)); - } - return out; - } - - int64_t - fieldindex(const RecordLookupPtr &recordlookup, - const std::string &key, - int64_t numfields) { - int64_t out = -1; - if (recordlookup.get() != nullptr) { - for (size_t i = 0; i < recordlookup.get()->size(); i++) { - if (recordlookup.get()->at(i) == key) { - out = (int64_t) i; - break; - } - } - } - if (out == -1) { - try { - out = (int64_t) std::stoi(key); - } - catch (std::invalid_argument const& /* err */) { - throw std::invalid_argument( - std::string("key ") + quote(key) - + std::string(" does not exist (not in record)") + FILENAME(__LINE__)); - } - if (!(0 <= out && out < numfields)) { - throw std::invalid_argument( - std::string("key interpreted as fieldindex ") + key - + std::string(" for records with only ") + std::to_string(numfields) - + std::string(" fields") + FILENAME(__LINE__)); - } - } - return out; - } - - const std::string - key(const RecordLookupPtr &recordlookup, - int64_t fieldindex, - int64_t numfields) { - if (fieldindex >= numfields) { - throw std::invalid_argument( - std::string("fieldindex ") + std::to_string(fieldindex) - + std::string(" for records with only ") + std::to_string(numfields) - + std::string(" fields") + FILENAME(__LINE__)); - } - if (recordlookup.get() != nullptr) { - return recordlookup.get()->at((size_t) fieldindex); - } else { - return std::to_string(fieldindex); - } - } - - bool - haskey(const RecordLookupPtr &recordlookup, - const std::string &key, - int64_t numfields) { - try { - fieldindex(recordlookup, key, numfields); - } - catch (std::invalid_argument const& /* err */) { - return false; - } - return true; - } - - const std::vector - keys(const RecordLookupPtr &recordlookup, int64_t numfields) { - std::vector out; - if (recordlookup.get() != nullptr) { - out.insert(out.end(), - recordlookup.get()->begin(), - recordlookup.get()->end()); - } else { - int64_t cols = numfields; - for (int64_t j = 0; j < cols; j++) { - out.push_back(std::to_string(j)); - } - } - return out; - } - - bool - parameter_equals(const Parameters ¶meters, - const std::string &key, - const std::string &value) { - auto item = parameters.find(key); - std::string myvalue; - if (item == parameters.end()) { - myvalue = "null"; - } else { - myvalue = item->second; - } - rj::Document mine; - rj::Document yours; - mine.Parse(myvalue.c_str()); - yours.Parse(value.c_str()); - return mine == yours; - } - - std::string - datetime_units(const std::string& format) { - auto units(format); - std::string chars = "[]1234567890"; - units.erase(remove_if(units.begin(), units.end(), - [&chars](const char &c) { - return chars.find(c) != std::string::npos; - }), - units.end()); - return units; - } - - std::tuple - datetime_data(const std::string& format) { - std::string next_format(format); - int64_t next_interval = 1; - - std::string next_units = next_format.substr( - next_format.find_first_of("["), - next_format.find_last_of("]")); - - auto begin_pos = next_units.find_first_of("0123456789"); - if (begin_pos != std::string::npos) { - auto end_pos = next_units.find_last_of("0123456789"); - if (end_pos != std::string::npos) { - std::string tmp = next_units.substr(begin_pos, end_pos); - next_interval = std::stoi(tmp); - } - } - - return std::make_tuple(datetime_units(next_units), next_interval); - } } } diff --git a/awkward-cpp/src/python/content.cpp b/awkward-cpp/src/python/content.cpp index bccc3e1f70..336d23ca8b 100644 --- a/awkward-cpp/src/python/content.cpp +++ b/awkward-cpp/src/python/content.cpp @@ -9,7 +9,7 @@ #include "awkward/python/content.h" #include "awkward/python/util.h" -#include "awkward/datetime_util.h" + using namespace pybind11::literals; @@ -197,7 +197,7 @@ make_ArrayBuilder(const py::handle& m, const std::string& name) { return (py::class_(m, name.c_str()) .def(py::init([](const int64_t initial, double resize) -> ak::ArrayBuilder { return ak::ArrayBuilder({initial, resize}); - }), py::arg("initial") = 1024, py::arg("resize") = 1.5) + }), py::arg("initial") = 1024, py::arg("resize") = 8) .def_property_readonly("_ptr", [](const ak::ArrayBuilder* self) -> size_t { return reinterpret_cast(self); diff --git a/dev/generate-kernel-signatures.py b/dev/generate-kernel-signatures.py index 42516c1ca0..8a7479bd93 100644 --- a/dev/generate-kernel-signatures.py +++ b/dev/generate-kernel-signatures.py @@ -21,7 +21,6 @@ "awkward_IndexedArray_mask", "awkward_ByteMaskedArray_mask", "awkward_zero_mask", - "awkward_RegularArray_compact_offsets", "awkward_IndexedArray_fill_count", "awkward_UnionArray_fillna", "awkward_localindex", @@ -58,13 +57,11 @@ "awkward_RegularArray_getitem_jagged_expand", "awkward_ListArray_getitem_jagged_expand", "awkward_ListArray_getitem_next_array", - "awkward_RegularArray_broadcast_tooffsets", "awkward_NumpyArray_fill_tobool", "awkward_NumpyArray_reduce_adjust_starts_64", "awkward_NumpyArray_reduce_adjust_starts_shifts_64", "awkward_regularize_arrayslice", "awkward_RegularArray_getitem_next_at", - "awkward_ListOffsetArray_compact_offsets", "awkward_BitMaskedArray_to_IndexedOptionArray", "awkward_ByteMaskedArray_getitem_nextcarry", "awkward_ByteMaskedArray_getitem_nextcarry_outindex", @@ -270,7 +267,6 @@ class ERROR(Structure): ("filename", c_char_p), ("id", c_int64), ("attempt", c_int64), - ("pass_through", c_bool), ] diff --git a/dev/generate-tests.py b/dev/generate-tests.py index 12d63ad94b..dc168c99eb 100644 --- a/dev/generate-tests.py +++ b/dev/generate-tests.py @@ -551,7 +551,6 @@ def gencpukerneltests(specdict): "awkward_IndexedArray_mask", "awkward_ByteMaskedArray_mask", "awkward_zero_mask", - "awkward_RegularArray_compact_offsets", "awkward_IndexedArray_fill_count", "awkward_UnionArray_fillna", "awkward_localindex", @@ -588,13 +587,11 @@ def gencpukerneltests(specdict): "awkward_RegularArray_getitem_jagged_expand", "awkward_ListArray_getitem_jagged_expand", "awkward_ListArray_getitem_next_array", - "awkward_RegularArray_broadcast_tooffsets", "awkward_NumpyArray_fill_tobool", "awkward_NumpyArray_reduce_adjust_starts_64", "awkward_NumpyArray_reduce_adjust_starts_shifts_64", "awkward_regularize_arrayslice", "awkward_RegularArray_getitem_next_at", - "awkward_ListOffsetArray_compact_offsets", "awkward_BitMaskedArray_to_IndexedOptionArray", "awkward_ByteMaskedArray_getitem_nextcarry", "awkward_ByteMaskedArray_getitem_nextcarry_outindex", diff --git a/docs/reference/ak.behavior.md b/docs/reference/ak.behavior.md new file mode 100644 index 0000000000..df42dea02d --- /dev/null +++ b/docs/reference/ak.behavior.md @@ -0,0 +1,688 @@ +# ak.behavior + +```{py:data} ak.behavior +``` + +## Motivation + +A data structure is defined both in terms of the information it encodes and +in how it can be used. For example, a hash-table is not just a buffer, it's +also the "get" and "set" operations that make the buffer usable as a key-value +store. Awkward Arrays have a suite of operations for transforming tree +structures into new tree structures, but an application of these structures to +a data analysis problem should be able to interpret them as objects in the +analysis domain, such as latitude-longitude coordinates in geographical +studies or Lorentz vectors in particle physics. + +Object-oriented programming unites data with its operations. This is a +conceptual improvement for data analysts because functions like "distance +between this latitude-longitude point and another on a spherical globe" can +be bound to the objects that represent latitude-longitude points. It +matches the way that data analysts usually think about their data. + +However, if these methods are saved in the data, or are written in a way +that will only work for one version of the data structures, then it becomes +difficult to work with large datasets. Old data that do not "fit" the new +methods would have to be converted, or the analysis would have to be broken +into different cases for each data generation. This problem is known as +schema evolution, and there are many solutions to it. + +The approach taken by the Awkward Array library is to encode very little +interpretation into the data themselves and apply an interpretation as +late as possible. Thus, a latitude-longitude record might be stamped with +the name `"latlon"`, but the operations on it are added immediately before +the user wants them. These operations can be written in such a way that +they only require the `"latlon"` to have `lat` and `lon` fields, so +different versions of the data can have additional fields or even be +embedded in different structures. + +## Parameters and behaviors + +In Awkward Array, metadata are embedded in data using an array node's +**parameters**, and parameter-dependent operations can be defined using +**behavior**. A global mapping from parameters to behavior is in a dict called +{data}`.behavior`: + +```python +>>> import awkward as ak +>>> ak.behavior +``` + +but behavior dicts can also be loaded into {class}`ak.Array`, +{class}`ak.Record`, and {class}`ak.ArrayBuilder` objects as a +constructor argument. See +{attr}`ak.Array.behavior`. + +The general flow is + +- **parameters** link data objects to names; +- **behavior** links names to code. + +In large datasets, parameters may be hard to change (permanently, at least: +on-the-fly parameter changes are easier), but behavior is easy to change +(it is always assigned on-the-fly). + +In the following example, we create two nested arrays of records with fields +`"x"` and `"y"` and the records are named `"point"`. + +```python +one = ak.Array([[{"x": 1, "y": 1.1}, {"x": 2, "y": 2.2}, {"x": 3, "y": 3.3}], + [], + [{"x": 4, "y": 4.4}, {"x": 5, "y": 5.5}], + [{"x": 6, "y": 6.6}], + [{"x": 7, "y": 7.7}, {"x": 8, "y": 8.8}, {"x": 9, "y": 9.9}]], + with_name="point") +two = ak.Array([[{"x": 0.9, "y": 1}, {"x": 2, "y": 2.2}, {"x": 2.9, "y": 3}], + [], + [{"x": 3.9, "y": 4}, {"x": 5, "y": 5.5}], + [{"x": 5.9, "y": 6}], + [{"x": 6.9, "y": 7}, {"x": 8, "y": 8.8}, {"x": 8.9, "y": 9}]], + with_name="point") +``` + +The name appears in the way the type is presented as a string (a departure from +[Datashape notation](https://datashape.readthedocs.io/)): + +```python +>>> ak.type(one) +5 * var * point["x": int64, "y": float64] +``` + +and it may be accessed as the `"__record__"` property, through the +{attr}`ak.Array.layout`: + +```python +>>> one.layout + + + + + "point" + + + + + + + + + +>>> one.layout.content.parameters +{'__record__': 'point'} +``` + +We have to dig into the layout's content because the `"__record__"` parameter +is set on the {class}`ak.contents.RecordArray`, which is buried inside of a +{class}`ak.contents.ListOffsetArray`. + +Alternatively, we can navigate to a single {class}`ak.Record` first: + +```python +>>> one[0, 0] + +>>> one[0, 0].layout.parameters +{'__record__': 'point'} +``` + +## Adding behavior to records + +Suppose we want the points in the above example to be able to calculate +distances to other points. We can do this by creating a subclass of +{class}`ak.Record` that has the new methods and associating it with +the `"__record__"` name. + +```python +class Point(ak.Record): + def distance(self, other): + return np.sqrt((self.x - other.x)**2 + (self.y - other.y)**2) + +ak.behavior["point"] = Point +``` + +Now `one[0, 0]` is instantiated as a `Point`, rather than a {class}`ak.Record`, + +```python +>>> one[0, 0] + +``` + +and it has the `distance` method. + +```python +>>> for xs, ys in zip(one, two): +... for x, y in zip(xs, ys): +... print(x.distance(y)) +0.14142135623730953 +0.0 +0.31622776601683783 +0.4123105625617664 +0.0 +0.6082762530298216 +0.7071067811865477 +0.0 +0.905538513813742 +``` + +Looping over data in Python is inconvenient and slow; we want to compute +quantities like this with array-at-a-time methods, but `distance` is +bound to a {class}`ak.Record`, not an {class}`ak.Array` of records. + +```python +>>> one.distance(two) +AttributeError: no field named 'distance' +``` + +To add `distance` as a method on arrays of points, create a subclass of +{class}`ak.Array` and attach that as `ak.behavior[".", "point"]` for +"array of points." + +```python +class PointArray(ak.Array): + def distance(self, other): + return np.sqrt((self.x - other.x)**2 + (self.y - other.y)**2) + +ak.behavior[".", "point"] = PointArray +``` + +Now `one[0]` is a `PointArray` and can compute `distance` on arrays at a +time. Thanks to NumPy's +[universal function](https://docs.scipy.org/doc/numpy/reference/ufuncs.html) +(ufunc) syntax, the expression is the same (and could perhaps be implemented +once and used by both `Point` and `PointArray`). + +```python +>>> one[0] + +>>> one[0].distance(two[0]) + +``` + +But `one` itself is an `Array` of `PointArrays`, and does not apply. + +```python +>>> one + +>>> one.distance(two) +AttributeError: no field named 'distance' +``` + +We can make the assignment work at all levels of list-depth by using a `"*"` +instead of a `"."`. + +```python +ak.behavior["*", "point"] = PointArray +``` + +One last caveat: our `one` array was created *before* this behavior was +assigned, so it needs to be recreated to be a member of the new class. The +normal {class}`ak.Array` constructor is sufficient for this. This is only +an issue if you're working interactively (but something to think about when +debugging!). + +```python +>>> one = ak.Array(one) +>>> two = ak.Array(two) +``` + +Now it works, and again we're taking advantage of the fact that the expression +for `distance` based on ufuncs works equally well on Awkward Arrays. + +```python +>>> one + +>>> one.distance(two) + +``` + +**In most cases, you want to apply array-of-records for all levels of list-depth:** use `ak.behavior["*", record_name]`. + +## Overriding NumPy ufuncs and binary operators + +The {class}`ak.Array` class overrides Python's binary operators with the +equivalent ufuncs, so `__eq__` actually calls {data}`numpy.equal`, for instance. +This is also true of other basic functions, like `__abs__` for overriding +{func}`abs` with {data}`numpy.absolute`. Each ufunc is then passed down to the leaves +(deepest sub-elements) of an Awkward data structure. + +For example, + +```python +>>> ak.Array([[1, 2, 3], [], [4]]) == ak.Array([[3, 2, 1], [], [4]]) + +``` + +However, this does not apply to records or named types until they are explicitly +overridden: + +```python +>>> one == two +Traceback (most recent call last): + File "", line 1, in +... +ValueError: no overloads for custom types: equal(point, point) +``` + +We might want to take an object-oriented view in which the `==` operation +applies to points, regardless of how deeply they are nested. If we try to do +it by adding `__eq__` as a method on `PointArray`, it would work if the +`PointArray` is the top of the data structure, but not if it's nested within +another structure. + +Instead, we should override {data}`numpy.equal` itself. Custom ufunc overrides are +checked at every step in broadcasting, so the override would be applied if +point objects are discovered at any level. + +```python +def point_equal(left, right): + return np.logical_and(left.x == right.x, left.y == right.y) + +ak.behavior[np.equal, "point", "point"] = point_equal +``` + +The above should be read as "override :data\`np.equal\` for cases in which both +arguments are `"point"`." + +```python +>>> ak.to_list(one == two) +[[False, True, False], [], [False, True], [False], [False, True, False]] +``` + +Similarly for overriding {func}`abs` + +```python +>>> def point_abs(point): +... return np.sqrt(point.x**2 + point.y**2) +... +>>> ak.behavior[np.absolute, "point"] = point_abs +>>> ak.to_list(abs(one)) +[[1.4866068747318506, 2.973213749463701, 4.459820624195552], + [], + [5.946427498927402, 7.433034373659253], + [8.919641248391104], + [10.406248123122953, 11.892854997854805, 13.379461872586655]] +``` + +and all other ufuncs. + +If you need a placeholder for "any number," use {class}`numbers.Real`, +{class}`numbers.Integral`, etc. Non-arrays are resolved by type; builtin Python +numbers and NumPy numbers are subclasses of the generic number types in the +{mod}`numbers` library. + +Also, for commutative operations, be sure to override both operator orders. +(Function signatures are matched to {data}`ak.behavior` using multiple dispatch.) + +```python +>>> import numbers +>>> def point_lmult(point, scalar): +... return ak.Array({"x": point.x * scalar, "y": point.y * scalar}) +... +>>> def point_rmult(scalar, point): +... return point_lmult(point, scalar) +... +>>> ak.behavior[np.multiply, "point", numbers.Real] = point_lmult +>>> ak.behavior[np.multiply, numbers.Real, "point"] = point_rmult +>>> ak.to_list(one * 10) +[[{'x': 10, 'y': 11.0}, {'x': 20, 'y': 22.0}, {'x': 30, 'y': 33.0}], + [], + [{'x': 40, 'y': 44.0}, {'x': 50, 'y': 55.0}], + [{'x': 60, 'y': 66.0}], + [{'x': 70, 'y': 77.0}, {'x': 80, 'y': 88.0}, {'x': 90, 'y': 99.0}]] +``` + +If you need to override ufuncs in more generality, you can use the +{class}`numpy.ufunc` interface: + +```python +>>> def apply_ufunc(ufunc, method, args, kwargs): +... if ufunc in (np.sin, np.cos, np.tan): +... x = ufunc(args[0].x) +... y = ufunc(args[0].y) +... return ak.Array({"x": x, "y": y}) +... else: +... return NotImplemented +... +>>> ak.behavior[np.ufunc, "point"] = apply_ufunc +>>> ak.to_list(np.sin(one)) +[[{'x': 0.8414709848078965, 'y': 0.8912073600614354}, + {'x': 0.9092974268256817, 'y': 0.8084964038195901}, + {'x': 0.1411200080598672, 'y': -0.1577456941432482}], + [], + [{'x': -0.7568024953079282, 'y': -0.951602073889516}, + {'x': -0.9589242746631385, 'y': -0.7055403255703919}], + [{'x': -0.27941549819892586, 'y': 0.31154136351337786}], + [{'x': 0.6569865987187891, 'y': 0.9881682338770004}, + {'x': 0.9893582466233818, 'y': 0.5849171928917617}, + {'x': 0.4121184852417566, 'y': -0.45753589377532133}]] +>>> np.sqrt(one) +Traceback (most recent call last): + File "", line 1, in +... +ValueError: no overloads for custom types: sqrt(point) +``` + +But be forewarned: the `ak.behavior[np.ufunc, name]` syntax will match +*any* ufunc that has an array containing an array with type `name` +*anywhere* in the argument list. The first array in the argument list +with type `name` will be matched instead of more detailed argument lists +with type `name` at a later spot in the list. The "apply_ufunc" interface +is *greedy*. + +## Overriding NumPy reducers + +In addition to ufuncs, it is also possible to override _reducers_ on records. Consider a 2D vector that implements binary addition: + +```python +def vector_add(left, right): + return ak.contents.RecordArray( + [ + ak.to_layout(left["rho"] + right["rho"]), + ak.to_layout(left["phi"] + right["phi"]), + ], + ["rho", "phi"], + parameters={"__record__": "Vector2D"}, + ) + + +ak.behavior[np.add, "Vector2D", "Vector2D"] = vector_add +``` + +Whilst the `np.add` overload permits binary addition of `Vector2D` objects, + +```pycon +>>> vector = ak.Array( +... [[{"rho": -1.1, "phi": -0.1}, {"rho": 1.1, "phi": 0.1}], [{"rho": -2.2, "phi": 0.0}, {"rho": 3.1, "phi": 0.9}]], +... with_name="Vector2D", +... ) +>>> (vector + vector).show() +[[{rho: -2.2, phi: -0.2}, {rho: 2.2, phi: 0.2}], + [{rho: -4.4, phi: 0}, {rho: 6.2, phi: 1.8}]] +``` + +it does not permit the use of the `ak.sum` reducer: + +```pycon +>>> ak.sum(vector, axis=-1) +TypeError: no ak.sum overloads for custom types: rho, phi + +This error occurred while calling + + ak.sum( + array = + axis = -1 + keepdims = False + mask_identity = False + highlevel = True + behavior = None + ) +``` + +To implement support for reducers like `ak.sum`, we should override them with a behavior: + +```pycon +>>> def vector_sum(vector, mask_identity): +... return ak.contents.RecordArray( +... [ +... ak.sum(vector["rho"], highlevel=False, axis=-1), +... ak.sum(vector["phi"], highlevel=False, axis=-1), +... ], +... ["rho", "phi"], +... parameters={"__record__": "Vector2D"}, +... ) +>>> ak.behavior[ak.sum, "Vector2D"] = vector_sum +>>> ak.sum(vector, axis=-1).show() +[{rho: 0, phi: 0}, +{rho: 0.9, phi: 0.9}] +``` + +Custom reducers are invoked with two arguments: a 2D array containing lists of records, and a boolean `mask_identity` indicating whether the reducer should introduce an option type (for reductions along empty sublists). If the reducer does not introduce an option type, and `mask=True`, Awkward will mask the result at the appropriate positions. The reducer should return an {class}`ak.Array` or {class}`ak.contents.Content` with the same number of elements as the input array. The reduction itself should be performed along `axis=1`, dropping the reduced dimension (i.e. `keepdims=False`). + + +## Mixin decorators + +The pattern of adding additional properties and function overrides to records +and arrays of records is quite common, and can be nicely described by the "mixin" +idiom: a class with no constructor that is mixed with both the {class}`ak.Array` and {class}`ak.Record` +class as to create new derived classes. The {func}`ak.mixin_class` and {func}`ak.mixin_class_method` +python decorators assist with some of this boilerplate. Consider the `Point` class +from above; we can implement all the functionality so far described as follows: + +```python +@ak.mixin_class(ak.behavior) +class Point: + def distance(self, other): + return np.sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2) + + @ak.mixin_class_method(np.equal, {"Point"}) + def point_equal(self, other): + return np.logical_and(self.x == other.x, self.y == other.y) + + @ak.mixin_class_method(np.abs) + def point_abs(self): + return np.sqrt(self.x ** 2 + self.y ** 2) +``` + +The behavior name is taken as the mixin class name, e.g. here it is `Point` (as opposed +to lowercase `point` previously). We can extend our implementation to allow `Point` types +to be added by overriding the `np.add` ufunc (appending to our class definition): + +```python +class Point: + # ... + + @ak.mixin_class_method(np.add, {"Point"}) + def point_add(self, other): + return ak.zip( + {"x": self.x + other.x, "y": self.y + other.y}, with_name="Point", + ) +``` + +The real power of using mixin classes comes from the ability to inherit behaviors. +Consider a `Point`-like record that also has a `weight` field. Suppose that we want +these `WeightedPoint` types to have the same distance and magnitude functionality, but +only be considered equal when they have the same weight. Also, suppose we want the addition +of two weighted points to give their weighted mean rather than a sum. We could implement +such a class as follows: + +```python +@ak.mixin_class(ak.behavior) +class WeightedPoint(Point): + @ak.mixin_class_method(np.equal, {"WeightedPoint"}) + def weighted_equal(self, other): + return np.logical_and(self.point_equal(other), self.weight == other.weight) + + @ak.mixin_class_method(np.add, {"WeightedPoint"}) + def weighted_add(self, other): + sumw = self.weight + other.weight + return ak.zip( + { + "x": (self.x * self.weight + other.x * other.weight) / sumw, + "y": (self.y * self.weight + other.y * other.weight) / sumw, + "weight": sumw, + }, + with_name="WeightedPoint", + ) +``` + +A footnote: in this implementation, adding a WeightedPoint and a Point returns a Point. +One may wish to disable this by type-checking, since the functionalities are rather different. + +## Adding behavior to arrays + +Occasionally, you may want to add behavior to an array that does not contain +records. A good example of this is to implement strings: strings are not a +special data type in Awkward Array as they are in many other libraries, they +are a behavior overlaid on arrays. + +There are four predefined string behaviors: + +- {class}`ak.CharBehavior`: an array of UTF-8 encoded characters; +- {class}`ak.ByteBehavior`: an array of unencoded characters; +- {class}`ak.StringBehavior`: an array of variable-length UTF-8 encoded strings; +- {class}`ak.ByteStringBehavior`: an array of variable-length unencoded bytestrings. + +All four override the string representations (`__str__` and `__repr__`), +but the string behaviors additionally override equality: + +```python +>>> ak.Array(["one", "two", "three"]) == ak.Array(["1", "TWO", "three"]) + +``` + +The only difference here is the parameter: instead of setting `"__record__"`, +we set `"__array__"`. + +```python +>>> ak.Array(["one", "two", "three"]).layout + + + "string" + + + + + "char" + + + +``` + +In `ak.behaviors.string`, string behaviors are assigned with lines like + +```python +ak.behavior["string"] = StringBehavior +ak.behavior[np.equal, "string", "string"] = _string_equal +``` + +## Custom type names + +To make the string type appear as `string` in type representations, a +`"__typestr__"` behavior is overriden (in `ak.behaviors.string`): + +```python +ak.behavior["__typestr__", "string"] = "string" +``` + +so that + +```python +>>> ak.type(ak.Array(["one", "two", "three"])) +3 * string +``` + +## Overriding behavior in Numba + +Awkward Arrays can be arguments and return values of functions compiled with +[Numba](http://numba.pydata.org). Since these functions run on low-level +objects, most functionality must be reimplemented, including behavioral +overrides. + +The documentation on +[Extending Numba](https://numba.pydata.org/numba-doc/dev/extending/index.html) +introduces **typing**, **lowering**, and **models**, which are necessary for +reimplementing the behavior of a Python object in the compiled environment. +To apply the same to records and arrays from an Awkward data structure, we +use {data}`ak.behavior` hooks that start with `"__numba_typer__"` and +`"__numba_lower__"`. + +**Case 1:** Adding a property, such as `rec.property_name`. + +```python +ak.behavior["__numba_typer__", record_name, property_name] = typer +ak.behavior["__numba_lower__", record_name, property_name] = lower +``` + +The `typer` function takes an +{func}`ak._connect._numba.arrayview.ArrayViewType` as its only argument +and returns the property's type. + +The `lower` function takes the standard `context, builder, sig, args` +arguments and returns the lowered value. Given a Python `function` that +takes one record and returns the property, the `lower` can be + +```python +def lower(context, builder, sig, args): + return context.compile_internal(builder, function, sig, args) +``` + +**Case 2:** Adding a method, such as `rec.method_name(arg0, arg1)`. + +```python +ak.behavior["__numba_typer__", record_name, method_name, ()] = typer +ak.behavior["__numba_lower__", record_name, method_name, ()] = lower +``` + +The last item is an *empty* tuple, `()` (regardless of whether the method +takes any arguments). + +In this case, the `typer` takes an +{func}`ak._connect._numba.arrayview.ArrayViewType` as well as any arguments +and returns the property's type, and the `sig` and `args` in `lower` +include these arguments. + +**Case 3:** Unary and binary operations, like `-rec1` and `rec1 + rec2`. + +```python +ak.behavior["__numba_typer__", operator.neg, "rec1"] = typer +ak.behavior["__numba_lower__", operator.neg, "rec1"] = lower + +ak.behavior["__numba_typer__", "rec1", operator.add, "rec2"] = typer +ak.behavior["__numba_lower__", "rec1", operator.add, "rec2"] = lower +``` + +**Case 4:** Completely replacing the Awkward record with an object in Numba. + +If a fully defined model for the object already exists and Numba, we can +have references to Awkward records or arrays simply *become* these objects, +which implies some overhead from copying data and a loss of the functionality +that Awkward would bring. + +Strings, for instance, are replaced by Numba's built-in string model so that +all string operations will work, but Awkward operations like broadcasting +characters will not. + +For this case, the signatures are + +```python +# parameters["__record__"] = record_name +ak.behavior["__numba_typer__", record_name] = typer +ak.behavior["__numba_lower__", record_name] = lower + +# for an array one-level deep +ak.behavior["__numba_typer__", ".", record_name] = typer +ak.behavior["__numba_lower__", ".", record_name] = lower + +# for an array any number of levels deep +ak.behavior["__numba_typer__", "*", record_name] = typer +ak.behavior["__numba_lower__", "*", record_name] = lower + +# parameters["__array__"] = array_name +ak.behavior["__numba_typer__", array_name] = typer +ak.behavior["__numba_lower__", array_name] = lower +``` + +The `typer` function takes an +{func}`ak._connect._numba.arrayview.ArrayViewType` as its only argument +and returns the Numba type of its replacement, while the `lower` +function takes + +- `context`: Numba context +- `builder`: Numba builder +- `rettype`: the Numba type of its replacement +- `viewtype`: an {func}`ak._connect._numba.arrayview.ArrayViewType` +- `viewval`: a Numba value of the view +- `viewproxy`: a Numba proxy (`context.make_helper`) of the view +- `attype`: the Numba integer type of the index position +- `atval`: the Numba value of the index position + +% Add back once https://github.com/scikit-hep/vector/issues/273 is completed + +% Complete example + +% ================ + +% The + +% `Vector design prototype `__ + +% has a complete example, including Numba. diff --git a/docs/reference/ak.behavior.rst b/docs/reference/ak.behavior.rst deleted file mode 100644 index 47ee52d0ea..0000000000 --- a/docs/reference/ak.behavior.rst +++ /dev/null @@ -1,678 +0,0 @@ -ak.behavior ------------ - -.. py:data:: ak.behavior - -* `Motivation <#motivation>`__ -* `Parameters and behaviors <#parameters-and-behaviors>`__ -* `Adding behavior to records <#adding-behavior-to-records>`__ -* `Overriding NumPy ufuncs and binary operators <#overriding-numpy-ufuncs-and-binary-operators>`__ -* `Mixin decorators <#mixin-decorators>`__ -* `Adding behavior to arrays <#adding-behavior-to-arrays>`__ -* `Custom type names <#custom-type-names>`__ -* `Custom broadcasting <#custom-broadcasting>`__ -* `Overriding behavior in Numba <#overriding-behavior-in-numba>`__ -* `Complete example <#complete-example>`__ - -Motivation -========== - -A data structure is defined both in terms of the information it encodes and -in how it can be used. For example, a hash-table is not just a buffer, it's -also the "get" and "set" operations that make the buffer usable as a key-value -store. Awkward Arrays have a suite of operations for transforming tree -structures into new tree structures, but an application of these structures to -a data analysis problem should be able to interpret them as objects in the -analysis domain, such as latitude-longitude coordinates in geographical -studies or Lorentz vectors in particle physics. - -Object-oriented programming unites data with its operations. This is a -conceptual improvement for data analysts because functions like "distance -between this latitude-longitude point and another on a spherical globe" can -be bound to the objects that represent latitude-longitude points. It -matches the way that data analysts usually think about their data. - -However, if these methods are saved in the data, or are written in a way -that will only work for one version of the data structures, then it becomes -difficult to work with large datasets. Old data that do not "fit" the new -methods would have to be converted, or the analysis would have to be broken -into different cases for each data generation. This problem is known as -schema evolution, and there are many solutions to it. - -The approach taken by the Awkward Array library is to encode very little -interpretation into the data themselves and apply an interpretation as -late as possible. Thus, a latitude-longitude record might be stamped with -the name ``"latlon"``, but the operations on it are added immediately before -the user wants them. These operations can be written in such a way that -they only require the ``"latlon"`` to have ``lat`` and ``lon`` fields, so -different versions of the data can have additional fields or even be -embedded in different structures. - -Parameters and behaviors -======================== - -In Awkward Array, metadata are embedded in data using an array node's -**parameters**, and parameter-dependent operations can be defined using -**behavior**. A global mapping from parameters to behavior is in a dict called -:data:`.behavior`: - -.. code-block:: python - - >>> import awkward as ak - >>> ak.behavior - -but behavior dicts can also be loaded into :class:`ak.Array`, -:class:`ak.Record`, and :class:`ak.ArrayBuilder` objects as a -constructor argument. See -:attr:`ak.Array.behavior`. - -The general flow is - -* **parameters** link data objects to names; -* **behavior** links names to code. - -In large datasets, parameters may be hard to change (permanently, at least: -on-the-fly parameter changes are easier), but behavior is easy to change -(it is always assigned on-the-fly). - -In the following example, we create two nested arrays of records with fields -``"x"`` and ``"y"`` and the records are named ``"point"``. - -.. code-block:: python - - one = ak.Array([[{"x": 1, "y": 1.1}, {"x": 2, "y": 2.2}, {"x": 3, "y": 3.3}], - [], - [{"x": 4, "y": 4.4}, {"x": 5, "y": 5.5}], - [{"x": 6, "y": 6.6}], - [{"x": 7, "y": 7.7}, {"x": 8, "y": 8.8}, {"x": 9, "y": 9.9}]], - with_name="point") - two = ak.Array([[{"x": 0.9, "y": 1}, {"x": 2, "y": 2.2}, {"x": 2.9, "y": 3}], - [], - [{"x": 3.9, "y": 4}, {"x": 5, "y": 5.5}], - [{"x": 5.9, "y": 6}], - [{"x": 6.9, "y": 7}, {"x": 8, "y": 8.8}, {"x": 8.9, "y": 9}]], - with_name="point") - -The name appears in the way the type is presented as a string (a departure from -`Datashape notation `__): - -.. code-block:: python - - >>> ak.type(one) - 5 * var * point["x": int64, "y": float64] - -and it may be accessed as the ``"__record__"`` property, through the -:attr:`ak.Array.layout`: - -.. code-block:: python - - >>> one.layout - - - - - "point" - - - - - - - - - - >>> one.layout.content.parameters - {'__record__': 'point'} - -We have to dig into the layout's content because the ``"__record__"`` parameter -is set on the :class:`ak.contents.RecordArray`, which is buried inside of a -:class:`ak.contents.ListOffsetArray`. - -Alternatively, we can navigate to a single :class:`ak.Record` first: - -.. code-block:: python - - >>> one[0, 0] - - >>> one[0, 0].layout.parameters - {'__record__': 'point'} - -Adding behavior to records -========================== - -Suppose we want the points in the above example to be able to calculate -distances to other points. We can do this by creating a subclass of -:class:`ak.Record` that has the new methods and associating it with -the ``"__record__"`` name. - -.. code-block:: python - - class Point(ak.Record): - def distance(self, other): - return np.sqrt((self.x - other.x)**2 + (self.y - other.y)**2) - - ak.behavior["point"] = Point - -Now ``one[0, 0]`` is instantiated as a ``Point``, rather than a :class:`ak.Record`, - -.. code-block:: python - - >>> one[0, 0] - - -and it has the ``distance`` method. - -.. code-block:: python - - >>> for xs, ys in zip(one, two): - ... for x, y in zip(xs, ys): - ... print(x.distance(y)) - 0.14142135623730953 - 0.0 - 0.31622776601683783 - 0.4123105625617664 - 0.0 - 0.6082762530298216 - 0.7071067811865477 - 0.0 - 0.905538513813742 - -Looping over data in Python is inconvenient and slow; we want to compute -quantities like this with array-at-a-time methods, but ``distance`` is -bound to a :class:`ak.Record`, not an :class:`ak.Array` of records. - -.. code-block:: python - - >>> one.distance(two) - AttributeError: no field named 'distance' - -To add ``distance`` as a method on arrays of points, create a subclass of -:class:`ak.Array` and attach that as ``ak.behavior[".", "point"]`` for -"array of points." - -.. code-block:: python - - class PointArray(ak.Array): - def distance(self, other): - return np.sqrt((self.x - other.x)**2 + (self.y - other.y)**2) - - ak.behavior[".", "point"] = PointArray - -Now ``one[0]`` is a ``PointArray`` and can compute ``distance`` on arrays at a -time. Thanks to NumPy's -`universal function `__ -(ufunc) syntax, the expression is the same (and could perhaps be implemented -once and used by both ``Point`` and ``PointArray``). - -.. code-block:: python - - >>> one[0] - - >>> one[0].distance(two[0]) - - -But ``one`` itself is an ``Array`` of ``PointArrays``, and does not apply. - -.. code-block:: python - - >>> one - - >>> one.distance(two) - AttributeError: no field named 'distance' - -We can make the assignment work at all levels of list-depth by using a ``"*"`` -instead of a ``"."``. - -.. code-block:: python - - ak.behavior["*", "point"] = PointArray - -One last caveat: our ``one`` array was created *before* this behavior was -assigned, so it needs to be recreated to be a member of the new class. The -normal :class:`ak.Array` constructor is sufficient for this. This is only -an issue if you're working interactively (but something to think about when -debugging!). - -.. code-block:: python - - >>> one = ak.Array(one) - >>> two = ak.Array(two) - -Now it works, and again we're taking advantage of the fact that the expression -for ``distance`` based on ufuncs works equally well on Awkward Arrays. - -.. code-block:: python - - >>> one - - >>> one.distance(two) - - -**In most cases, you want to apply array-of-records for all levels of list-depth:** use ``ak.behavior["*", record_name]``. - -Overriding NumPy ufuncs and binary operators -============================================ - -The :class:`ak.Array` class overrides Python's binary operators with the -equivalent ufuncs, so ``__eq__`` actually calls :data:`numpy.equal`, for instance. -This is also true of other basic functions, like ``__abs__`` for overriding -:func:`abs` with :data:`numpy.absolute`. Each ufunc is then passed down to the leaves -(deepest sub-elements) of an Awkward data structure. - -For example, - -.. code-block:: python - - >>> ak.Array([[1, 2, 3], [], [4]]) == ak.Array([[3, 2, 1], [], [4]]) - - - -However, this does not apply to records or named types until they are explicitly -overridden: - -.. code-block:: python - - >>> one == two - Traceback (most recent call last): - File "", line 1, in - ... - ValueError: no overloads for custom types: equal(point, point) - -We might want to take an object-oriented view in which the ``==`` operation -applies to points, regardless of how deeply they are nested. If we try to do -it by adding ``__eq__`` as a method on ``PointArray``, it would work if the -``PointArray`` is the top of the data structure, but not if it's nested within -another structure. - -Instead, we should override :data:`numpy.equal` itself. Custom ufunc overrides are -checked at every step in broadcasting, so the override would be applied if -point objects are discovered at any level. - -.. code-block:: python - - def point_equal(left, right): - return np.logical_and(left.x == right.x, left.y == right.y) - - ak.behavior[np.equal, "point", "point"] = point_equal - -The above should be read as "override :data`np.equal` for cases in which both -arguments are ``"point"``." - -.. code-block:: python - - >>> ak.to_list(one == two) - [[False, True, False], [], [False, True], [False], [False, True, False]] - -Similarly for overriding :func:`abs` - -.. code-block:: python - - >>> def point_abs(point): - ... return np.sqrt(point.x**2 + point.y**2) - ... - >>> ak.behavior[np.absolute, "point"] = point_abs - >>> ak.to_list(abs(one)) - [[1.4866068747318506, 2.973213749463701, 4.459820624195552], - [], - [5.946427498927402, 7.433034373659253], - [8.919641248391104], - [10.406248123122953, 11.892854997854805, 13.379461872586655]] - -and all other ufuncs. - -If you need a placeholder for "any number," use :class:`numbers.Real`, -:class:`numbers.Integral`, etc. Non-arrays are resolved by type; builtin Python -numbers and NumPy numbers are subclasses of the generic number types in the -:mod:`numbers` library. - -Also, for commutative operations, be sure to override both operator orders. -(Function signatures are matched to :data:`ak.behavior` using multiple dispatch.) - -.. code-block:: python - - >>> import numbers - >>> def point_lmult(point, scalar): - ... return ak.Array({"x": point.x * scalar, "y": point.y * scalar}) - ... - >>> def point_rmult(scalar, point): - ... return point_lmult(point, scalar) - ... - >>> ak.behavior[np.multiply, "point", numbers.Real] = point_lmult - >>> ak.behavior[np.multiply, numbers.Real, "point"] = point_rmult - >>> ak.to_list(one * 10) - [[{'x': 10, 'y': 11.0}, {'x': 20, 'y': 22.0}, {'x': 30, 'y': 33.0}], - [], - [{'x': 40, 'y': 44.0}, {'x': 50, 'y': 55.0}], - [{'x': 60, 'y': 66.0}], - [{'x': 70, 'y': 77.0}, {'x': 80, 'y': 88.0}, {'x': 90, 'y': 99.0}]] - -If you need to override ufuncs in more generality, you can use the -:class:`numpy.ufunc` interface: - -.. code-block:: python - - >>> def apply_ufunc(ufunc, method, args, kwargs): - ... if ufunc in (np.sin, np.cos, np.tan): - ... x = ufunc(args[0].x) - ... y = ufunc(args[0].y) - ... return ak.Array({"x": x, "y": y}) - ... else: - ... return NotImplemented - ... - >>> ak.behavior[np.ufunc, "point"] = apply_ufunc - >>> ak.to_list(np.sin(one)) - [[{'x': 0.8414709848078965, 'y': 0.8912073600614354}, - {'x': 0.9092974268256817, 'y': 0.8084964038195901}, - {'x': 0.1411200080598672, 'y': -0.1577456941432482}], - [], - [{'x': -0.7568024953079282, 'y': -0.951602073889516}, - {'x': -0.9589242746631385, 'y': -0.7055403255703919}], - [{'x': -0.27941549819892586, 'y': 0.31154136351337786}], - [{'x': 0.6569865987187891, 'y': 0.9881682338770004}, - {'x': 0.9893582466233818, 'y': 0.5849171928917617}, - {'x': 0.4121184852417566, 'y': -0.45753589377532133}]] - >>> np.sqrt(one) - Traceback (most recent call last): - File "", line 1, in - ... - ValueError: no overloads for custom types: sqrt(point) - -But be forewarned: the ``ak.behavior[np.ufunc, name]`` syntax will match -*any* ufunc that has an array containing an array with type ``name`` -*anywhere* in the argument list. The first array in the argument list -with type ``name`` will be matched instead of more detailed argument lists -with type ``name`` at a later spot in the list. The "apply_ufunc" interface -is *greedy*. - -Mixin decorators -================ -The pattern of adding additional properties and function overrides to records -and arrays of records is quite common, and can be nicely described by the "mixin" -idiom: a class with no constructor that is mixed with both the :class:`ak.Array` and :class:`ak.Record` -class as to create new derived classes. The :func:`ak.mixin_class` and :func:`ak.mixin_class_method` -python decorators assist with some of this boilerplate. Consider the ``Point`` class -from above; we can implement all the functionality so far described as follows: - -.. code-block:: python - - @ak.mixin_class(ak.behavior) - class Point: - def distance(self, other): - return np.sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2) - - @ak.mixin_class_method(np.equal, {"Point"}) - def point_equal(self, other): - return np.logical_and(self.x == other.x, self.y == other.y) - - @ak.mixin_class_method(np.abs) - def point_abs(self): - return np.sqrt(self.x ** 2 + self.y ** 2) - -The behavior name is taken as the mixin class name, e.g. here it is ``Point`` (as opposed -to lowercase ``point`` previously). We can extend our implementation to allow ``Point`` types -to be added by overriding the ``np.add`` ufunc (appending to our class definition): - -.. code-block:: python - - class Point: - # ... - - @ak.mixin_class_method(np.add, {"Point"}) - def point_add(self, other): - return ak.zip( - {"x": self.x + other.x, "y": self.y + other.y}, with_name="Point", - ) - -The real power of using mixin classes comes from the ability to inherit behaviors. -Consider a ``Point``-like record that also has a ``weight`` field. Suppose that we want -these ``WeightedPoint`` types to have the same distance and magnitude functionality, but -only be considered equal when they have the same weight. Also, suppose we want the addition -of two weighted points to give their weighted mean rather than a sum. We could implement -such a class as follows: - -.. code-block:: python - - @ak.mixin_class(ak.behavior) - class WeightedPoint(Point): - @ak.mixin_class_method(np.equal, {"WeightedPoint"}) - def weighted_equal(self, other): - return np.logical_and(self.point_equal(other), self.weight == other.weight) - - @ak.mixin_class_method(np.add, {"WeightedPoint"}) - def weighted_add(self, other): - sumw = self.weight + other.weight - return ak.zip( - { - "x": (self.x * self.weight + other.x * other.weight) / sumw, - "y": (self.y * self.weight + other.y * other.weight) / sumw, - "weight": sumw, - }, - with_name="WeightedPoint", - ) - -A footnote: in this implementation, adding a WeightedPoint and a Point returns a Point. -One may wish to disable this by type-checking, since the functionalities are rather different. - -Adding behavior to arrays -========================= - -Occasionally, you may want to add behavior to an array that does not contain -records. A good example of this is to implement strings: strings are not a -special data type in Awkward Array as they are in many other libraries, they -are a behavior overlaid on arrays. - -There are four predefined string behaviors: - -* :class:`ak.CharBehavior`: an array of UTF-8 encoded characters; -* :class:`ak.ByteBehavior`: an array of unencoded characters; -* :class:`ak.StringBehavior`: an array of variable-length UTF-8 encoded strings; -* :class:`ak.ByteStringBehavior`: an array of variable-length unencoded bytestrings. - -All four override the string representations (``__str__`` and ``__repr__``), -but the string behaviors additionally override equality: - -.. code-block:: python - - >>> ak.Array(["one", "two", "three"]) == ak.Array(["1", "TWO", "three"]) - - -The only difference here is the parameter: instead of setting ``"__record__"``, -we set ``"__array__"``. - -.. code-block:: python - - >>> ak.Array(["one", "two", "three"]).layout - - - "string" - - - - - "char" - - - - -In ``ak.behaviors.string``, string behaviors are assigned with lines like - -.. code-block:: python - - ak.behavior["string"] = StringBehavior - ak.behavior[np.equal, "string", "string"] = _string_equal - -Custom type names -================= - -To make the string type appear as ``string`` in type representations, a -``"__typestr__"`` behavior is overriden (in ``ak.behaviors.string``): - -.. code-block:: python - - ak.behavior["__typestr__", "string"] = "string" - -so that - -.. code-block:: python - - >>> ak.type(ak.Array(["one", "two", "three"])) - 3 * string - -Custom broadcasting -=================== - -In situations where we want to think about lists as objects, such as strings, -we may even need to override the broadcasting rules. For instance, given - -.. code-block:: python - - ak.Array(["HAL"]) + ak.Array([[1, 1, 1, 1, 1]]) - -we might expect ``"HAL"`` to broadcast to each ``1``, like - -.. code-block:: python - - [[[73, 66, 77], [73, 66, 77], [73, 66, 77], [73, 66, 77], [73, 66, 77]]] - -but (without custom broadcasting) instead it raises a broadcasting for any -length of ``1`` list other than 3: - -.. code-block:: python - - >>> # without custom broadcasting - >>> print(ak.Array(["HAL"]) + ak.Array([[1, 1, 1, 1, 1]])) - ValueError: in ListOffsetArray64, cannot broadcast nested list - >>> print(ak.Array(["HAL"]) + ak.Array([[1, 1, 1]])) - [[73, 66, 77]] - -It's matching each character of ``"HAL"`` with a number from the list, but we -want the string to be taken as an object. That is fixed (in -``ak.behaviors.string``) with a custom broadcasting rule: - -.. code-block:: python - - def _string_broadcast(layout, offsets): - # layout: an ak.layout.Content object - # offsets: an ak.layout.Index of offsets to match - # - # should return: an ak.layout.Content object of the broadcasted result - ... - - awkward.behavior["__broadcast__", "string"] = _string_broadcast - -Very few applications would need to do this, but the :data:`ak.behavior` object -provides a lot of room for customization hooks like this. - -Overriding behavior in Numba -============================ - -Awkward Arrays can be arguments and return values of functions compiled with -`Numba `__. Since these functions run on low-level -objects, most functionality must be reimplemented, including behavioral -overrides. - -The documentation on -`Extending Numba `__ -introduces **typing**, **lowering**, and **models**, which are necessary for -reimplementing the behavior of a Python object in the compiled environment. -To apply the same to records and arrays from an Awkward data structure, we -use :data:`ak.behavior` hooks that start with ``"__numba_typer__"`` and -``"__numba_lower__"``. - -**Case 1:** Adding a property, such as ``rec.property_name``. - -.. code-block:: python - - ak.behavior["__numba_typer__", record_name, property_name] = typer - ak.behavior["__numba_lower__", record_name, property_name] = lower - -The ``typer`` function takes an -:func:`ak._connect._numba.arrayview.ArrayViewType` as its only argument -and returns the property's type. - -The ``lower`` function takes the standard ``context, builder, sig, args`` -arguments and returns the lowered value. Given a Python ``function`` that -takes one record and returns the property, the ``lower`` can be - -.. code-block:: python - - def lower(context, builder, sig, args): - return context.compile_internal(builder, function, sig, args) - -**Case 2:** Adding a method, such as ``rec.method_name(arg0, arg1)``. - -.. code-block:: python - - ak.behavior["__numba_typer__", record_name, method_name, ()] = typer - ak.behavior["__numba_lower__", record_name, method_name, ()] = lower - -The last item is an *empty* tuple, ``()`` (regardless of whether the method -takes any arguments). - -In this case, the ``typer`` takes an -:func:`ak._connect._numba.arrayview.ArrayViewType` as well as any arguments -and returns the property's type, and the ``sig`` and ``args`` in ``lower`` -include these arguments. - -**Case 3:** Unary and binary operations, like ``-rec1`` and ``rec1 + rec2``. - -.. code-block:: python - - ak.behavior["__numba_typer__", operator.neg, "rec1"] = typer - ak.behavior["__numba_lower__", operator.neg, "rec1"] = lower - - ak.behavior["__numba_typer__", "rec1", operator.add, "rec2"] = typer - ak.behavior["__numba_lower__", "rec1", operator.add, "rec2"] = lower - -**Case 4:** Completely replacing the Awkward record with an object in Numba. - -If a fully defined model for the object already exists and Numba, we can -have references to Awkward records or arrays simply *become* these objects, -which implies some overhead from copying data and a loss of the functionality -that Awkward would bring. - -Strings, for instance, are replaced by Numba's built-in string model so that -all string operations will work, but Awkward operations like broadcasting -characters will not. - -For this case, the signatures are - -.. code-block:: python - - # parameters["__record__"] = record_name - ak.behavior["__numba_typer__", record_name] = typer - ak.behavior["__numba_lower__", record_name] = lower - - # for an array one-level deep - ak.behavior["__numba_typer__", ".", record_name] = typer - ak.behavior["__numba_lower__", ".", record_name] = lower - - # for an array any number of levels deep - ak.behavior["__numba_typer__", "*", record_name] = typer - ak.behavior["__numba_lower__", "*", record_name] = lower - - # parameters["__array__"] = array_name - ak.behavior["__numba_typer__", array_name] = typer - ak.behavior["__numba_lower__", array_name] = lower - -The ``typer`` function takes an -:func:`ak._connect._numba.arrayview.ArrayViewType` as its only argument -and returns the Numba type of its replacement, while the ``lower`` -function takes - -* ``context``: Numba context -* ``builder``: Numba builder -* ``rettype``: the Numba type of its replacement -* ``viewtype``: an :func:`ak._connect._numba.arrayview.ArrayViewType` -* ``viewval``: a Numba value of the view -* ``viewproxy``: a Numba proxy (``context.make_helper``) of the view -* ``attype``: the Numba integer type of the index position -* ``atval``: the Numba value of the index position - -.. Add back once https://github.com/scikit-hep/vector/issues/273 is completed -.. Complete example -.. ================ - -.. The -.. `Vector design prototype `__ -.. has a complete example, including Numba. diff --git a/docs/reference/ak.builder.ArrayBuilder.rst b/docs/reference/ak.builder.ArrayBuilder.rst index 6d4b1b450b..bb53a77a74 100644 --- a/docs/reference/ak.builder.ArrayBuilder.rst +++ b/docs/reference/ak.builder.ArrayBuilder.rst @@ -10,11 +10,11 @@ object is wrapped by :class:`ak.ArrayBuilder`. underscores after "begin" and "end," but that hasn't happened in the low-level interface, yet or possibly at all.) -.. py:class:: ArrayBuilder(initial=1024, resize=1.5) +.. py:class:: ArrayBuilder(initial=1024, resize=8) .. py:method:: ArrayBuilder.__getitem__(where) -.. py:method:: ArrayBuilder.__init__(initial=1024, resize=1.5) +.. py:method:: ArrayBuilder.__init__(initial=1024, resize=8) .. py:method:: ArrayBuilder.__iter__() diff --git a/docs/reference/toctree.txt b/docs/reference/toctree.txt index ce300fe746..f442d9cb2c 100644 --- a/docs/reference/toctree.txt +++ b/docs/reference/toctree.txt @@ -135,6 +135,7 @@ :caption: Broadcasting generated/ak.broadcast_arrays + generated/ak.broadcast_fields .. toctree:: :caption: Combinatorics ("for loop" replacements) @@ -147,6 +148,7 @@ .. toctree:: :caption: Value and type conversions + generated/ak.enforce_type generated/ak.nan_to_none generated/ak.nan_to_num generated/ak.values_astype @@ -300,6 +302,7 @@ generated/ak.forms.UnmaskedForm generated/ak.forms.from_dict generated/ak.forms.from_json + generated/ak.forms.from_type .. toctree:: :caption: Builtin behaviors diff --git a/docs/switcher.json b/docs/switcher.json index 1f5429f7f6..3e95ecf872 100644 --- a/docs/switcher.json +++ b/docs/switcher.json @@ -7,6 +7,10 @@ "name": "main", "url": "https://awkward-array.org/doc/main/" }, + { + "version": "2.2", + "url": "https://awkward-array.org/doc/2.2/" + }, { "version": "2.1", "url": "https://awkward-array.org/doc/2.1/" diff --git a/kernel-specification.yml b/kernel-specification.yml index 865fa8ca67..d6fe83775d 100644 --- a/kernel-specification.yml +++ b/kernel-specification.yml @@ -2139,33 +2139,6 @@ kernels: automatic-tests: true manual-tests: [] - - name: awkward_ListOffsetArray_compact_offsets - specializations: - - name: awkward_ListOffsetArray32_compact_offsets_64 - args: - - {name: tooffsets, type: "List[int64_t]", dir: out} - - {name: fromoffsets, type: "Const[List[int32_t]]", dir: in, role: ListOffsetArray-offsets} - - {name: length, type: "int64_t", dir: in, role: default} - - name: awkward_ListOffsetArray64_compact_offsets_64 - args: - - {name: tooffsets, type: "List[int64_t]", dir: out} - - {name: fromoffsets, type: "Const[List[int64_t]]", dir: in, role: ListOffsetArray-offsets} - - {name: length, type: "int64_t", dir: in, role: default} - - name: awkward_ListOffsetArrayU32_compact_offsets_64 - args: - - {name: tooffsets, type: "List[int64_t]", dir: out} - - {name: fromoffsets, type: "Const[List[uint32_t]]", dir: in, role: ListOffsetArray-offsets} - - {name: length, type: "int64_t", dir: in, role: default} - description: null - definition: | - def awkward_ListOffsetArray_compact_offsets(tooffsets, fromoffsets, length): - diff = int(fromoffsets[0]) - tooffsets[0] = 0 - for i in range(length): - tooffsets[i + 1] = fromoffsets[i + 1] - diff - automatic-tests: true - manual-tests: [] - - name: awkward_ListOffsetArray_drop_none_indexes specializations: - name: awkward_ListOffsetArray_drop_none_indexes_32 @@ -3459,43 +3432,53 @@ kernels: automatic-tests: false manual-tests: [] - - name: awkward_RegularArray_broadcast_tooffsets + - name: awkward_RecordArray_reduce_nonlocal_outoffsets_64 specializations: - - name: awkward_RegularArray_broadcast_tooffsets_64 + - name: awkward_RecordArray_reduce_nonlocal_outoffsets_64 args: - - {name: fromoffsets, type: "Const[List[int64_t]]", dir: in, role: ListOffsetArray-offsets} - - {name: offsetslength, type: "int64_t", dir: in, role: default} - - {name: size, type: "int64_t", dir: in, role: RegularArray-size} + - {name: outoffsets, type: "List[int64_t]", dir: out} + - {name: outcarry, type: "List[int64_t]", dir: out} + - {name: parents, type: "Const[List[int64_t]]", dir: in, role: reducer-parents} + - {name: lenparents, type: "int64_t", dir: in, role: reducer-lenparents} + - {name: outlength, type: "int64_t", dir: in, role: reducer-outlength} description: null definition: | - def awkward_RegularArray_broadcast_tooffsets(fromoffsets, offsetslength, size): - for i in range(offsetslength - 1): - count = int(fromoffsets[i + 1] - fromoffsets[i]) - if count < 0: - raise ValueError("broadcast's offsets must be monotonically increasing") - if size != count: - raise ValueError("cannot broadcast nested list") - automatic-tests: true - manual-tests: [] + def awkward_RecordArray_reduce_nonlocal_outoffsets_64( + outoffsets, outcarry, parents, lenparents, outlength + ): + # Zero initialise offsets + outoffsets[0] = 0 + + # Initialise carry to unique value, indicating "missing" + for i in range(outlength): + outcarry[i] = -1 + + # Fill offsets with lengths of sublists (in order of appearance, *NOT* parents) + i = 0 + k_sublist = 0 + for j in range(1, lenparents): + if parents[i] != parents[j]: + outoffsets[k_sublist + 1] = j + outcarry[parents[i]] = k_sublist + i = j + k_sublist += 1 + + # Close open sublist + if lenparents > 0: + outoffsets[k_sublist + 1] = j + outcarry[parents[i]] = k_sublist + k_sublist += 1 + + # Append empty lists for missing parents + for i in range(k_sublist, outlength): + outoffsets[i + 1] = lenparents + + # Replace unique value with index of appended empty list + for i in range(outlength): + if outcarry[i] == -1: + outcarry[i] = k_sublist + k_sublist += 1 - - name: awkward_RegularArray_broadcast_tooffsets_size1 - specializations: - - name: awkward_RegularArray_broadcast_tooffsets_size1_64 - args: - - {name: tocarry, type: "List[int64_t]", dir: out} - - {name: fromoffsets, type: "Const[List[int64_t]]", dir: in, role: ListOffsetArray-offsets} - - {name: offsetslength, type: "int64_t", dir: in, role: default} - description: null - definition: | - def awkward_RegularArray_broadcast_tooffsets_size1(tocarry, fromoffsets, offsetslength): - k = 0 - for i in range(offsetslength - 1): - count = int(fromoffsets[i + 1] - fromoffsets[i]) - if count < 0: - raise ValueError("broadcast's offsets must be monotonically increasing") - for j in range(count): - tocarry[k] = float(i) - k = k + 1 automatic-tests: true manual-tests: [] @@ -3516,22 +3499,6 @@ kernels: automatic-tests: false manual-tests: [] - - name: awkward_RegularArray_compact_offsets - specializations: - - name: awkward_RegularArray_compact_offsets64 - args: - - {name: tooffsets, type: "List[int64_t]", dir: out} - - {name: length, type: "int64_t", dir: in, role: default} - - {name: size, type: "int64_t", dir: in, role: RegularArray-size} - description: null - definition: | - def awkward_RegularArray_compact_offsets(tooffsets, length, size): - tooffsets[0] = 0 - for i in range(length): - tooffsets[i + 1] = (i + 1) * size - automatic-tests: true - manual-tests: [] - - name: awkward_RegularArray_getitem_carry specializations: - name: awkward_RegularArray_getitem_carry_64 diff --git a/kernel-test-data.json b/kernel-test-data.json index 8f30e90465..d602e7f372 100644 --- a/kernel-test-data.json +++ b/kernel-test-data.json @@ -1 +1 @@ -{"tests": {"reducer": [], "ListArray": [{"ListArray-starts": [2, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "ListArray-starts-offset": 0, "ListArray-stops": [3, 2, 4, 5, 3, 4, 2, 5, 3, 4, 6, 11], "ListArray-stops-offset": 0, "ListArray-length": 3, "ListArray-at": 0}, {"ListArray-starts": [1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1], "ListArray-starts-offset": 1, "ListArray-stops": [8, 4, 5, 6, 5, 5, 7], "ListArray-stops-offset": 1, "ListArray-length": 10, "ListArray-at": 5}, {"ListArray-starts": [1, 4, 5, 6, 5, 5, 7, 1, 2, 1, 3, 1, 5, 3, 2], "ListArray-starts-offset": 1, "ListArray-stops": [1, 4, 5, 6, 5, 5, 7, 1, 2, 1, 3, 1, 5, 3, 2], "ListArray-stops-offset": 1, "ListArray-length": 5, "ListArray-at": 0}, {"ListArray-starts": [1, 7, 6, 1, 3, 4, 2, 5, 2, 3, 1, 2, 3, 4, 5, 6, 7, 1, 2], "ListArray-starts-offset": 2, "ListArray-stops": [1, 9, 6, 2, 4, 5, 3, 6, 3, 4, 2, 4, 5, 5, 7, 8, 2, 3], "ListArray-stops-offset": 2, "ListArray-length": 3, "ListArray-at": 2}, {"ListArray-starts": [0, 0, 0, 0, 0, 0, 0, 0], "ListArray-starts-offset": 0, "ListArray-stops": [1, 1, 1, 1, 1, 1, 1, 1], "ListArray-stops-offset": 0, "ListArray-length": 6, "ListArray-at": 1}], "ListOffsetArray": [{"ListOffsetArray-offsets": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "ListOffsetArray-offsets-offset": 0, "ListOffsetArray-length": 5, "ListOffsetArray-rawoffsets": [[1, 2, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4], [2, 1, 0, 3, 1, 2, 0, 3, 1, 2, 2, 2, 1, 2, 3, 1, 0, 2, 3, 0, 2, 1]]}, {"ListOffsetArray-offsets": [2, 3, 3, 4, 5, 5, 5, 5, 5, 6, 7, 8, 10, 11], "ListOffsetArray-offsets-offset": 1, "ListOffsetArray-length": 1, "ListOffsetArray-rawoffsets": [[1, 1, 1, 2, 2, 2, 1, 3, 1, 2, 3, 4, 1, 2, 4, 1, 2, 3, 4], [0, 1, 3, 3, 1, 0, 0, 3, 1, 2, 2, 2, 1, 2]]}, {"ListOffsetArray-offsets": [2, 1, 0, 1, 2, 0, 1, 2, 2, 2, 1, 2, 1, 0, 0, 0, 0], "ListOffsetArray-offsets-offset": 1, "ListOffsetArray-length": 6, "ListOffsetArray-rawoffsets": [[3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4], [2, 1, 2, 3, 1, 0, 2, 3, 0, 2, 1]]}, {"ListOffsetArray-offsets": [1, 0, 2, 3, 1, 2, 0, 0, 1, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "ListOffsetArray-offsets-offset": 2, "ListOffsetArray-length": 3, "ListOffsetArray-rawoffsets": [[1, 2, 3, 2, 3, 1, 3, 3, 3, 2, 3, 1, 2, 3, 4, 1, 2], [2, 1, 2, 1, 2, 1, 2, 3, 1, 2, 3, 1, 3, 2, 3]]}, {"ListOffsetArray-offsets": [0, 0, 0, 0, 0, 0, 0, 0], "ListOffsetArray-offsets-offset": 0, "ListOffsetArray-length": 6, "ListOffsetArray-rawoffsets": [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]}], "Identities": [{"Identities-array": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], "Identities-array-offset": 0}, {"Identities-array": [0, 2, 1, 1, 1, 1, 2, 0, 1, 2, 0, 1, 0, 2, 0, 1, 1, 1, 0, 2, 2, 2, 1, 2, 0, 1], "Identities-array-offset": 1}, {"Identities-array": [1, 4, 3, 1, 2, 4, 5, 2, 3, 4, 1, 7, 5, 4, 2, 3, 1, 4, 2, 7, 8, 4, 3, 3, 4, 1, 5, 9, 7, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "Identities-array-offset": 2}, {"Identities-array": [1, 3, 2, 3, 1, 2, 5, 4, 3, 2, 1, 4, 3, 5, 1, 2, 3, 5, 1, 4, 2, 3, 2, 1, 2, 3, 5, 4, 3, 2, 1, 4, 2, 3, 1, 5, 2, 3, 4, 1, 5, 1, 2, 1, 1, 1], "Identities-array-offset": 3}, {"Identities-array": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "Identities-array-offset": 0}], "RegularArray": [{"RegularArray-size": 3}, {"RegularArray-size": 2}, {"RegularArray-size": 1}, {"RegularArray-size": 2}, {"RegularArray-size": 0}], "IndexedArray": [{"IndexedArray-index": [1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1], "IndexedArray-index-offset": 0, "IndexedArray-length": 2, "IndexedArray-parents": [1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1], "IndexedArray-parents-offset": 1}, {"IndexedArray-index": [1, 2, 2, 3, 0, 2, 0, 2, 1, 1], "IndexedArray-index-offset": 0, "IndexedArray-length": 1, "IndexedArray-parents": [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1], "IndexedArray-parents-offset": 0}, {"IndexedArray-index": [1, 3, 0, 3, 5, 2, 0, 2, 1, 1], "IndexedArray-index-offset": 0, "IndexedArray-length": 1, "IndexedArray-parents": [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0], "IndexedArray-parents-offset": 1}, {"IndexedArray-index": [1, 4, 2, 3, 1, 2, 3, 1, 4, 3, 2, 1, 3, 2, 4, 5, 1, 2, 3, 4, 5], "IndexedArray-index-offset": 1, "IndexedArray-length": 2, "IndexedArray-parents": [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1], "IndexedArray-parents-offset": 2}, {"IndexedArray-index": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "IndexedArray-index-offset": 0, "IndexedArray-length": 5, "IndexedArray-parents": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "IndexedArray-parents-offset": 0}], "UnionArray": [{"UnionArray-tags": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "UnionArray-tags-offset": 1, "UnionArray-which": 0, "UnionArray-length": 3}, {"UnionArray-tags": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "UnionArray-tags-offset": 0, "UnionArray-which": 1, "UnionArray-length": 2}, {"UnionArray-tags": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "UnionArray-tags-offset": 1, "UnionArray-which": 2, "UnionArray-length": 3}, {"UnionArray-tags": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "UnionArray-tags-offset": 2, "UnionArray-which": 1, "UnionArray-length": 3}, {"UnionArray-tags": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "UnionArray-tags-offset": 0, "UnionArray-which": 0, "UnionArray-length": 10}], "NumpyArray": [{"NumpyArray-ptr": [1, 2, 4, 2, 3, 1, 4, 2, 2, 2, 1, 4, 3], "NumpyArray-ptr-offset": 0, "NumpyArray-length": 5}, {"NumpyArray-ptr": [-1, 2, 4, 0, -3], "NumpyArray-ptr-offset": 1, "NumpyArray-length": 3}, {"NumpyArray-ptr": [-1, -3, 2, 1, -5, 7, 8, 9, 2, 3, 4, -1, -5, -3, -7, 5], "NumpyArray-ptr-offset": 2, "NumpyArray-length": 4}, {"NumpyArray-ptr": [1.1, -8.1, 3.1, 9.1, 4.1, 7.1, 9.1], "NumpyArray-ptr-offset": 1, "NumpyArray-length": 2}, {"NumpyArray-ptr": [0, 0, 0, 0, 0, 0, 0], "NumpyArray-ptr-offset": 0, "NumpyArray-length": 5}], "ByteMaskedArray": [{"ByteMaskedArray-mask": [1, 1, 1, 1, 1], "ByteMaskedArray-mask-offset": 0, "ByteMaskedArray-valid_when": true, "ByteMaskedArray-length": 0}, {"ByteMaskedArray-mask": [0, 0, 0, 0, 0], "ByteMaskedArray-mask-offset": 0, "ByteMaskedArray-valid_when": false, "ByteMaskedArray-length": 5}, {"ByteMaskedArray-mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "ByteMaskedArray-mask-offset": 1, "ByteMaskedArray-valid_when": true, "ByteMaskedArray-length": 7}, {"ByteMaskedArray-mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "ByteMaskedArray-mask-offset": 1, "ByteMaskedArray-valid_when": true, "ByteMaskedArray-length": 7}, {"ByteMaskedArray-mask": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "ByteMaskedArray-mask-offset": 0, "ByteMaskedArray-valid_when": true, "ByteMaskedArray-length": 7}], "BitMaskedArray": [{"BitMaskedArray-mask": [1, 1, 1, 1, 1], "BitMaskedArray-mask-offset": 0, "BitMaskedArray-valid_when": true, "BitMaskedArray-lsb_order": true}, {"BitMaskedArray-mask": [0, 0, 0, 0, 0], "BitMaskedArray-mask-offset": 0, "BitMaskedArray-valid_when": false, "BitMaskedArray-lsb_order": false}, {"BitMaskedArray-mask": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "BitMaskedArray-mask-offset": 1, "BitMaskedArray-valid_when": true, "BitMaskedArray-lsb_order": false}, {"BitMaskedArray-mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "BitMaskedArray-mask-offset": 2, "BitMaskedArray-valid_when": true, "BitMaskedArray-lsb_order": true}, {"BitMaskedArray-mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "BitMaskedArray-mask-offset": 0, "BitMaskedArray-valid_when": false, "BitMaskedArray-lsb_order": false}], "num": 3}, "unit-tests": [{"name": "awkward_missing_repeat", "tests": [{"error": false, "inputs": {"index": [0], "indexlength": 1, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0]}}, {"error": false, "inputs": {"index": [0, 1], "indexlength": 2, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1], "indexlength": 3, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1], "indexlength": 3, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1], "indexlength": 4, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1], "indexlength": 4, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 1], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 1], "indexlength": 5, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1, 2]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2, 3], "indexlength": 6, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1, 2, 3]}}, {"error": false, "inputs": {"index": [0, 1, 1, 2], "indexlength": 4, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 2]}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 1], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 2, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3], "indexlength": 5, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 2, 3]}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 4, 5], "indexlength": 7, "regularsize": 6, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"index": [0, 1, 2, 1], "indexlength": 4, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 1]}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 1], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 3], "indexlength": 5, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 1, 3]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1], "indexlength": 5, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 3, 1]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1, 4, 5], "indexlength": 7, "regularsize": 6, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 3, 1, 4, 5]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 4, 5], "indexlength": 6, "regularsize": 6, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"index": [1, 0], "indexlength": 2, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 0]}}, {"error": false, "inputs": {"index": [1, 0, 1], "indexlength": 3, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1], "indexlength": 3, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1], "indexlength": 4, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1], "indexlength": 4, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 1], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 1], "indexlength": 5, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 2], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1, 2]}}, {"error": false, "inputs": {"index": [1, 0, 1, 2], "indexlength": 4, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 2]}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 1], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 2, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 3], "indexlength": 5, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 2, 3]}}, {"error": false, "inputs": {"index": [1, 1, 0], "indexlength": 3, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1], "indexlength": 4, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1], "indexlength": 4, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 1], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 1], "indexlength": 5, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 2], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1, 2]}}, {"error": false, "inputs": {"index": [1, 1, 1, 0], "indexlength": 4, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 0]}}, {"error": false, "inputs": {"index": [1, 1, 1, 0, 1], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 1, 1, 0, 1], "indexlength": 5, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 0, 1]}}, {"error": false, "inputs": {"index": [1], "indexlength": 1, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1]}}, {"error": false, "inputs": {"index": [1, 1, 1, 1, 0], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 1, 0]}}, {"error": false, "inputs": {"index": [1, 1, 1, 1, 1], "indexlength": 5, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1, 1, 1], "indexlength": 4, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1, 1], "indexlength": 3, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1], "indexlength": 2, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1, 1]}}]}, {"name": "awkward_index_rpad_and_clip_axis0", "tests": [{"error": false, "inputs": {"length": 2, "target": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 3, "target": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 3, "target": 3}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "target": 4}, "outputs": {"toindex": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 5, "target": 5}, "outputs": {"toindex": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 6, "target": 6}, "outputs": {"toindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 5, "target": 3}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"length": 6, "target": 3}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "target": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 3, "target": 1}, "outputs": {"toindex": [0]}}, {"error": false, "inputs": {"length": 5, "target": 1}, "outputs": {"toindex": [0]}}, {"error": false, "inputs": {"length": 6, "target": 1}, "outputs": {"toindex": [0]}}]}, {"name": "awkward_BitMaskedArray_to_ByteMaskedArray", "tests": [{"error": false, "inputs": {"bitmasklength": 2, "frombitmask": [58, 59], "lsb_order": false, "validwhen": false}, "outputs": {"tobytemask": [0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"bitmasklength": 1, "frombitmask": [66], "lsb_order": true, "validwhen": false}, "outputs": {"tobytemask": [0, 1, 0, 0, 0, 0, 1, 0]}}, {"error": false, "inputs": {"bitmasklength": 2, "frombitmask": [58, 59], "lsb_order": true, "validwhen": false}, "outputs": {"tobytemask": [0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0]}}]}, {"name": "awkward_ByteMaskedArray_getitem_nextcarry", "tests": [{"error": false, "inputs": {"length": 2, "mask": [0, 0], "validwhen": false}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"length": 5, "mask": [0, 0, 1, 1, 0], "validwhen": false}, "outputs": {"tocarry": [0, 1, 4]}}]}, {"name": "awkward_ByteMaskedArray_getitem_nextcarry_outindex", "tests": [{"error": false, "inputs": {"length": 1, "mask": [0], "validwhen": true}, "outputs": {"outindex": [-1], "tocarry": [123]}}, {"error": false, "inputs": {"length": 4, "mask": [0, 0, 0, 0], "validwhen": true}, "outputs": {"outindex": [-1, -1, -1, -1], "tocarry": [123, 123, 123, 123]}}]}, {"name": "awkward_ByteMaskedArray_numnull", "tests": [{"error": false, "inputs": {"length": 4, "mask": [0, 0, 0, 0], "validwhen": false}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"length": 2, "mask": [0, 0], "validwhen": false}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"length": 1, "mask": [0], "validwhen": false}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"length": 30, "mask": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], "validwhen": false}, "outputs": {"numnull": [10]}}, {"error": false, "inputs": {"length": 30, "mask": [0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0], "validwhen": false}, "outputs": {"numnull": [10]}}, {"error": false, "inputs": {"length": 30, "mask": [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0], "validwhen": false}, "outputs": {"numnull": [10]}}, {"error": false, "inputs": {"length": 4, "mask": [0, 1, 0, 0], "validwhen": false}, "outputs": {"numnull": [1]}}, {"error": false, "inputs": {"length": 1, "mask": [0], "validwhen": true}, "outputs": {"numnull": [1]}}, {"error": false, "inputs": {"length": 3, "mask": [0, 1, 1], "validwhen": true}, "outputs": {"numnull": [1]}}, {"error": false, "inputs": {"length": 6, "mask": [0, 0, 1, 1, 0, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 5, "mask": [0, 0, 1, 1, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 9, "mask": [0, 1, 0, 0, 0, 0, 1, 0, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 6, "mask": [0, 1, 0, 0, 1, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 3, "mask": [0, 1, 0], "validwhen": true}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 3, "mask": [1, 1, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 8, "mask": [0, 1, 0, 0, 1, 0, 1, 0], "validwhen": false}, "outputs": {"numnull": [3]}}, {"error": false, "inputs": {"length": 10, "mask": [0, 1, 1, 0, 1, 0, 0, 1, 1, 0], "validwhen": true}, "outputs": {"numnull": [5]}}]}, {"name": "awkward_ByteMaskedArray_toIndexedOptionArray", "tests": [{"error": false, "inputs": {"length": 2, "mask": [0, 0], "validwhen": false}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 4, "mask": [0, 0, 0, 0], "validwhen": false}, "outputs": {"toindex": [0, 1, 2, 3]}}]}, {"name": "awkward_IndexedArray_flatten_nextcarry", "tests": [{"error": false, "inputs": {"fromindex": [0, 1], "lencontent": 2, "lenindex": 2}, "outputs": {"tocarry": [0, 1]}}]}, {"name": "awkward_IndexedArray_getitem_nextcarry", "tests": [{"error": false, "inputs": {"fromindex": [0, 0, 0, 0, 0, 0, 0], "lencontent": 1, "lenindex": 7}, "outputs": {"tocarry": [0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0, 0, 0, 0], "lencontent": 1, "lenindex": 6}, "outputs": {"tocarry": [0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0, 0, 0], "lencontent": 1, "lenindex": 5}, "outputs": {"tocarry": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0], "lencontent": 1, "lenindex": 3}, "outputs": {"tocarry": [0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0], "lencontent": 1, "lenindex": 2}, "outputs": {"tocarry": [0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0, 1, 1, 1, 2, 2, 2], "lencontent": 3, "lenindex": 9}, "outputs": {"tocarry": [0, 0, 0, 1, 1, 1, 2, 2, 2]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0, 2, 3, 3, 4], "lencontent": 5, "lenindex": 7}, "outputs": {"tocarry": [0, 0, 0, 2, 3, 3, 4]}}, {"error": false, "inputs": {"fromindex": [0, 1], "lencontent": 2, "lenindex": 2}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2], "lencontent": 3, "lenindex": 3}, "outputs": {"tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3], "lencontent": 4, "lenindex": 4}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4], "lencontent": 5, "lenindex": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromindex": [1, 1, 1], "lencontent": 6, "lenindex": 3}, "outputs": {"tocarry": [1, 1, 1]}}, {"error": false, "inputs": {"fromindex": [1], "lencontent": 5, "lenindex": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"fromindex": [1], "lencontent": 6, "lenindex": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"fromindex": [1, 2], "lencontent": 3, "lenindex": 2}, "outputs": {"tocarry": [1, 2]}}, {"error": false, "inputs": {"fromindex": [1, 3], "lencontent": 6, "lenindex": 2}, "outputs": {"tocarry": [1, 3]}}, {"error": false, "inputs": {"fromindex": [2, 1, 0, 3, 3, 4], "lencontent": 5, "lenindex": 6}, "outputs": {"tocarry": [2, 1, 0, 3, 3, 4]}}, {"error": false, "inputs": {"fromindex": [2, 2, 1, 0], "lencontent": 3, "lenindex": 4}, "outputs": {"tocarry": [2, 2, 1, 0]}}, {"error": false, "inputs": {"fromindex": [2, 2, 1, 0, 3], "lencontent": 4, "lenindex": 5}, "outputs": {"tocarry": [2, 2, 1, 0, 3]}}, {"error": false, "inputs": {"fromindex": [2], "lencontent": 3, "lenindex": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"fromindex": [2], "lencontent": 5, "lenindex": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"fromindex": [2, 4, 4, 0, 8], "lencontent": 10, "lenindex": 5}, "outputs": {"tocarry": [2, 4, 4, 0, 8]}}, {"error": false, "inputs": {"fromindex": [3, 2, 1, 0], "lencontent": 4, "lenindex": 4}, "outputs": {"tocarry": [3, 2, 1, 0]}}, {"error": false, "inputs": {"fromindex": [4, 3, 2, 1, 0], "lencontent": 5, "lenindex": 5}, "outputs": {"tocarry": [4, 3, 2, 1, 0]}}, {"error": false, "inputs": {"fromindex": [4], "lencontent": 5, "lenindex": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"fromindex": [6, 4, 4, 8, 0], "lencontent": 10, "lenindex": 5}, "outputs": {"tocarry": [6, 4, 4, 8, 0]}}, {"error": false, "inputs": {"fromindex": [6, 5, 4, 3, 2, 1, 0], "lencontent": 7, "lenindex": 7}, "outputs": {"tocarry": [6, 5, 4, 3, 2, 1, 0]}}]}, {"name": "awkward_IndexedArray_getitem_nextcarry_outindex", "tests": [{"error": false, "inputs": {"fromindex": [0, 1, 2, 3], "lencontent": 4, "lenindex": 4}, "outputs": {"tocarry": [0, 1, 2, 3], "toindex": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromindex": [3, 2, 1, 0], "lencontent": 4, "lenindex": 4}, "outputs": {"tocarry": [3, 2, 1, 0], "toindex": [0, 1, 2, 3]}}]}, {"name": "awkward_IndexedArray_numnull", "tests": [{"error": false, "inputs": {"fromindex": [0, 1], "lenindex": 2}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3], "lenindex": 4}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4, 5, 6], "lenindex": 7}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [1, 2], "lenindex": 2}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [1, 2, 3], "lenindex": 3}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [1, 2, 3, 4], "lenindex": 4}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [2, 3], "lenindex": 2}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [2, 3, 4], "lenindex": 3}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [3, 2, 1, 0], "lenindex": 4}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [3, 4], "lenindex": 2}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [4, 3, 2, 1, 0], "lenindex": 5}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [5, 2, 4, 1, 3, 0], "lenindex": 6}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [5, 4, 3, 2, 1, 0], "lenindex": 6}, "outputs": {"numnull": [0]}}]}, {"name": "awkward_ListArray_broadcast_tooffsets", "tests": [{"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16], "fromstarts": [0, 0, 0, 0, 0, 0, 4, 4, 4, 4], "fromstops": [2, 2, 2, 2, 2, 2, 5, 5, 5, 5], "lencontent": 5, "offsetslength": 11}, "outputs": {"tocarry": [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 4, 4, 4, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6, 8, 10], "fromstarts": [0, 0, 0, 3, 3], "fromstops": [2, 2, 2, 5, 5], "lencontent": 5, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 0, 1, 0, 1, 3, 4, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20], "fromstarts": [0, 0, 0, 3, 3, 5, 5, 5, 8, 8], "fromstops": [2, 2, 2, 5, 5, 7, 7, 7, 10, 10], "lencontent": 10, "offsetslength": 11}, "outputs": {"tocarry": [0, 1, 0, 1, 0, 1, 3, 4, 3, 4, 5, 6, 5, 6, 5, 6, 8, 9, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15, 18, 21], "fromstarts": [0, 0, 0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3, 3, 3], "lencontent": 3, "offsetslength": 8}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15, 18], "fromstarts": [0, 0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3, 3], "lencontent": 3, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15], "fromstarts": [0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3], "lencontent": 3, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9], "fromstarts": [0, 0, 0], "fromstops": [3, 3, 3], "lencontent": 3, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6], "fromstarts": [0, 0], "fromstops": [3, 3], "lencontent": 3, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3], "fromstarts": [0, 3], "fromstops": [3, 3], "lencontent": 20, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 8, 13, 18, 23, 28], "fromstarts": [0, 13, 3, 18, 8, 23], "fromstops": [3, 18, 8, 23, 13, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 13, 14, 15, 16, 17, 3, 4, 5, 6, 7, 18, 19, 20, 21, 22, 8, 9, 10, 11, 12, 23, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4], "fromstarts": [0, 2], "fromstops": [2, 4], "lencontent": 4, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 9, 13, 18, 23, 28], "fromstarts": [0, 13, 4, 18, 8, 23], "fromstops": [4, 18, 8, 23, 13, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 13, 14, 15, 16, 17, 4, 5, 6, 7, 18, 19, 20, 21, 22, 8, 9, 10, 11, 12, 23, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 9, 14, 19, 24, 29], "fromstarts": [0, 14, 4, 19, 9, 24], "fromstops": [4, 19, 9, 24, 14, 29], "lencontent": 29, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 14, 15, 16, 17, 18, 4, 5, 6, 7, 8, 19, 20, 21, 22, 23, 9, 10, 11, 12, 13, 24, 25, 26, 27, 28]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 18, 21, 24, 29], "fromstarts": [0, 0, 0, 8, 11, 11, 14], "fromstops": [5, 5, 5, 11, 14, 14, 19], "lencontent": 19, "offsetslength": 8}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 11, 12, 13, 14, 15, 16, 17, 18]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 4, 5], "fromstarts": [0, 3, 3, 4], "fromstops": [3, 3, 4, 5], "lencontent": 5, "offsetslength": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5], "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "lencontent": 10, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5], "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "lencontent": 5, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 5, 8], "fromstarts": [0, 3, 3, 10, 10], "fromstops": [3, 3, 5, 10, 13], "lencontent": 13, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 10, 11, 12]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20], "fromstarts": [0, 10, 15, 25], "fromstops": [5, 15, 20, 30], "lencontent": 30, "offsetslength": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 11, 12, 17, 22], "fromstarts": [0, 11, 5, 16, 6, 17], "fromstops": [5, 16, 6, 17, 11, 22], "lencontent": 22, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 11, 12, 13, 14, 15, 5, 16, 6, 7, 8, 9, 10, 17, 18, 19, 20, 21]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 14, 18, 23, 28], "fromstarts": [0, 14, 5, 19, 9, 23], "fromstops": [5, 19, 9, 23, 14, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 14, 15, 16, 17, 18, 5, 6, 7, 8, 19, 20, 21, 22, 9, 10, 11, 12, 13, 23, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 24, 28], "fromstarts": [0, 14, 5, 19, 10, 24], "fromstops": [5, 19, 10, 24, 14, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 14, 15, 16, 17, 18, 5, 6, 7, 8, 9, 19, 20, 21, 22, 23, 10, 11, 12, 13, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 6, 10], "fromstarts": [0, 3, 3, 15, 16], "fromstops": [3, 3, 5, 16, 20], "lencontent": 20, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20], "fromstarts": [0, 15, 10, 25], "fromstops": [5, 20, 15, 30], "lencontent": 30, "offsetslength": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 19, 24, 28], "fromstarts": [0, 15, 5, 20, 10, 24], "fromstops": [5, 20, 10, 24, 15, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 10, 11, 12, 13, 14, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 28], "fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 29], "fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 29], "lencontent": 29, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 25, 26, 27, 28]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 30], "lencontent": 30, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [0, 45, 5, 50, 10, 55], "fromstops": [5, 50, 10, 55, 15, 60], "lencontent": 60, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 45, 46, 47, 48, 49, 5, 6, 7, 8, 9, 50, 51, 52, 53, 54, 10, 11, 12, 13, 14, 55, 56, 57, 58, 59]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6], "fromstarts": [0, 3], "fromstops": [3, 6], "lencontent": 25, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6], "fromstarts": [0, 3], "fromstops": [3, 6], "lencontent": 6, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 10, 14, 17], "fromstarts": [0, 3, 10, 14, 18], "fromstops": [3, 6, 14, 18, 21], "lencontent": 21, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15], "fromstarts": [0, 3, 11, 14, 17], "fromstops": [3, 6, 14, 17, 20], "lencontent": 20, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15], "fromstarts": [0, 3, 11, 14, 17], "fromstops": [3, 6, 14, 17, 20], "lencontent": 25, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 10, 14, 17], "fromstarts": [0, 3, 11, 15, 19], "fromstops": [3, 6, 15, 19, 22], "lencontent": 22, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 4, 6, 7], "fromstarts": [0, 3, 3, 4, 6], "fromstops": [3, 3, 4, 6, 7], "lencontent": 7, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 7], "fromstarts": [0, 3, 3], "fromstops": [3, 3, 7], "lencontent": 7, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 7], "fromstarts": [0, 3], "fromstops": [3, 7], "lencontent": 7, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 6, 10], "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 10], "lencontent": 10, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 8, 8, 10], "fromstarts": [0, 3, 3, 5, 8, 8], "fromstops": [3, 3, 5, 8, 8, 10], "lencontent": 10, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10], "fromstarts": [0, 5], "fromstops": [5, 10], "lencontent": 10, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 7, 7, 9, 9, 11], "fromstarts": [0, 4, 7, 7, 9, 9], "fromstops": [4, 7, 7, 9, 9, 11], "lencontent": 11, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 8, 12, 16, 19], "fromstarts": [0, 3, 8, 12, 16], "fromstops": [3, 8, 12, 16, 19], "lencontent": 19, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 11, 15, 19, 22], "fromstarts": [0, 3, 6, 11, 15, 19], "fromstops": [3, 6, 11, 15, 19, 22], "lencontent": 22, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [0, 5, 10, 15, 20, 25], "fromstops": [5, 10, 15, 20, 25, 30], "lencontent": 30, "offsetslength": 7}, "outputs": {"tocarry": [0, 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]}}, {"error": false, "inputs": {"fromoffsets": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210], "fromstarts": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203], "fromstops": [7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210], "lencontent": 210, "offsetslength": 31}, "outputs": {"tocarry": [0, 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, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [0, 5, 10, 45, 50, 55], "fromstops": [5, 10, 15, 50, 55, 60], "lencontent": 60, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 11, 15, 19, 22], "fromstarts": [0, 3, 8, 13, 17, 21], "fromstops": [3, 6, 13, 17, 21, 24], "lencontent": 24, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 8, 11, 14, 19], "fromstarts": [0, 8, 11, 11, 14], "fromstops": [5, 11, 14, 14, 19], "lencontent": 19, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 11, 12, 13, 14, 15, 16, 17, 18]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 8, 9], "fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lencontent": 10, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 5, 6, 7, 7, 9], "fromstarts": [0, 4, 6, 3, 6, 7], "fromstops": [3, 6, 7, 4, 6, 9], "lencontent": 9, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 3, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 5, 6, 7, 9], "fromstarts": [0, 4, 6, 3, 7], "fromstops": [3, 6, 7, 4, 9], "lencontent": 9, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 3, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 3, 4, 5, 6, 8], "fromstarts": [0, 2, 4, 5, 6, 9], "fromstops": [2, 3, 5, 6, 7, 11], "lencontent": 11, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 9, 10]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 6, 8], "fromstarts": [0, 4, 4, 6, 9], "fromstops": [3, 4, 6, 7, 11], "lencontent": 11, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 9, 10]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5], "fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "lencontent": 7, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 7], "fromstarts": [0, 3, 5], "fromstops": [3, 3, 9], "lencontent": 9, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 7], "fromstarts": [0, 5], "fromstops": [3, 9], "lencontent": 9, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 5, 7, 8, 9, 10], "fromstarts": [0, 6, 3, 8, 5, 9], "fromstops": [3, 8, 5, 9, 6, 10], "lencontent": 10, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 6, 7, 3, 4, 8, 5, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 5, 5, 6, 8, 9], "fromstarts": [0, 6, 3, 8, 3, 5], "fromstops": [3, 8, 3, 9, 5, 6], "lencontent": 9, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 6, 7, 8, 3, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 7], "fromstarts": [0, 3, 6], "fromstops": [3, 3, 10], "lencontent": 10, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 5, 6, 6, 6], "fromstarts": [0, 3, 2, 5, 3, 6], "fromstops": [2, 5, 3, 6, 3, 6], "lencontent": 6, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 3, 4, 2, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 2, 4, 5, 6], "fromstarts": [0, 3, 3, 5, 8], "fromstops": [2, 3, 5, 6, 9], "lencontent": 9, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 3, 4, 5, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9], "fromstarts": [11, 14, 17], "fromstops": [14, 17, 20], "lencontent": 25, "offsetslength": 4}, "outputs": {"tocarry": [11, 12, 13, 14, 15, 16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [1, 16, 6, 21, 11, 26], "fromstops": [6, 21, 11, 26, 16, 31], "lencontent": 31, "offsetslength": 7}, "outputs": {"tocarry": [1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 6, 7, 8, 9, 10, 21, 22, 23, 24, 25, 11, 12, 13, 14, 15, 26, 27, 28, 29, 30]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5], "fromstarts": [1, 99, 5], "fromstops": [4, 99, 7], "lencontent": 7, "offsetslength": 4}, "outputs": {"tocarry": [1, 2, 3, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20], "fromstarts": [15, 10, 5, 0], "fromstops": [20, 15, 10, 5], "lencontent": 20, "offsetslength": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20], "fromstarts": [15, 5, 10, 0], "fromstops": [20, 10, 15, 5], "lencontent": 20, "offsetslength": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 4], "fromstarts": [16], "fromstops": [20], "lencontent": 20, "offsetslength": 2}, "outputs": {"tocarry": [16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 1, 3], "fromstarts": [2, 2, 3], "fromstops": [2, 3, 5], "lencontent": 5, "offsetslength": 4}, "outputs": {"tocarry": [2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 2, 3], "fromstarts": [2, 4, 5], "fromstops": [3, 5, 6], "lencontent": 6, "offsetslength": 4}, "outputs": {"tocarry": [2, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [25, 10, 20, 5, 15, 0], "fromstops": [30, 15, 25, 10, 20, 5], "lencontent": 30, "offsetslength": 7}, "outputs": {"tocarry": [25, 26, 27, 28, 29, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 5, 6, 7, 8, 9, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [25, 20, 15, 10, 5, 0], "fromstops": [30, 25, 20, 15, 10, 5], "lencontent": 30, "offsetslength": 7}, "outputs": {"tocarry": [25, 26, 27, 28, 29, 20, 21, 22, 23, 24, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 2, 2, 5, 7], "fromstarts": [3, 3, 3, 0, 4], "fromstops": [4, 4, 3, 3, 6], "lencontent": 6, "offsetslength": 6}, "outputs": {"tocarry": [3, 3, 0, 1, 2, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 2, 5, 6, 7, 11], "fromstarts": [3, 3, 0, 5, 5, 6], "fromstops": [5, 3, 3, 6, 6, 10], "lencontent": 10, "offsetslength": 7}, "outputs": {"tocarry": [3, 4, 0, 1, 2, 5, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 3], "fromstarts": [3, 15], "fromstops": [5, 16], "lencontent": 20, "offsetslength": 3}, "outputs": {"tocarry": [3, 4, 15]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 4, 7], "fromstarts": [3, 3, 3, 0], "fromstops": [5, 5, 3, 3], "lencontent": 5, "offsetslength": 5}, "outputs": {"tocarry": [3, 4, 3, 4, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 7, 7, 9, 9, 11], "fromstarts": [3, 0, 999, 2, 6, 10], "fromstops": [7, 3, 999, 4, 6, 12], "lencontent": 12, "offsetslength": 7}, "outputs": {"tocarry": [3, 4, 5, 6, 0, 1, 2, 2, 3, 10, 11]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 2, 2, 2, 6], "fromstarts": [3, 5, 5, 5, 5], "fromstops": [5, 5, 5, 5, 9], "lencontent": 9, "offsetslength": 6}, "outputs": {"tocarry": [3, 4, 5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 14, 16], "fromstarts": [3, 6, 17, 20, 11, 25], "fromstops": [6, 9, 20, 23, 13, 27], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [3, 4, 5, 6, 7, 8, 17, 18, 19, 20, 21, 22, 11, 12, 25, 26]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 8, 12, 16, 19], "fromstarts": [3, 6, 11, 15, 19], "fromstops": [6, 11, 15, 19, 22], "lencontent": 22, "offsetslength": 6}, "outputs": {"tocarry": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 2, 6], "fromstarts": [3, 3, 6], "fromstops": [3, 5, 10], "lencontent": 10, "offsetslength": 4}, "outputs": {"tocarry": [3, 4, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 6], "fromstarts": [3, 6], "fromstops": [5, 10], "lencontent": 10, "offsetslength": 3}, "outputs": {"tocarry": [3, 4, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 2], "fromstarts": [4, 4], "fromstops": [4, 6], "lencontent": 6, "offsetslength": 3}, "outputs": {"tocarry": [4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 2, 7], "fromstarts": [4, 4, 7], "fromstops": [4, 6, 12], "lencontent": 12, "offsetslength": 4}, "outputs": {"tocarry": [4, 5, 7, 8, 9, 10, 11]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 2, 5, 5, 7, 7, 11], "fromstarts": [5, 5, 0, 3, 3, 6, 6], "fromstops": [6, 6, 3, 3, 5, 6, 10], "lencontent": 10, "offsetslength": 8}, "outputs": {"tocarry": [5, 5, 0, 1, 2, 3, 4, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 1, 4], "fromstarts": [5, 5, 6], "fromstops": [5, 6, 9], "lencontent": 9, "offsetslength": 4}, "outputs": {"tocarry": [5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 1, 5], "fromstarts": [5, 6, 6], "fromstops": [6, 6, 10], "lencontent": 10, "offsetslength": 4}, "outputs": {"tocarry": [5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 5], "fromstarts": [5, 6], "fromstops": [6, 10], "lencontent": 10, "offsetslength": 3}, "outputs": {"tocarry": [5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 4, 6, 6, 9], "fromstarts": [6, 5, 3, 3, 0], "fromstops": [9, 6, 5, 3, 3], "lencontent": 9, "offsetslength": 6}, "outputs": {"tocarry": [6, 7, 8, 5, 3, 4, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 4, 7, 10], "fromstarts": [6, 5, 6, 0], "fromstops": [9, 6, 9, 3], "lencontent": 9, "offsetslength": 5}, "outputs": {"tocarry": [6, 7, 8, 5, 6, 7, 8, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 1, 6], "fromstarts": [6, 7, 7], "fromstops": [7, 7, 12], "lencontent": 12, "offsetslength": 4}, "outputs": {"tocarry": [6, 7, 8, 9, 10, 11]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 8, 11, 14, 19], "fromstarts": [6, 11, 14, 17, 20], "fromstops": [11, 14, 17, 20, 25], "lencontent": 25, "offsetslength": 6}, "outputs": {"tocarry": [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 5, 7, 10], "fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lencontent": 10, "offsetslength": 5}, "outputs": {"tocarry": [6, 7, 8, 9, 5, 3, 4, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 5, 7, 7, 10], "fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lencontent": 10, "offsetslength": 6}, "outputs": {"tocarry": [6, 7, 8, 9, 5, 3, 4, 0, 1, 2]}}]}, {"name": "awkward_ListArray_compact_offsets", "tests": [{"error": false, "inputs": {"fromstarts": [2, 2, 3], "fromstops": [2, 3, 5], "length": 3}, "outputs": {"tooffsets": [0, 0, 1, 3]}}, {"error": false, "inputs": {"fromstarts": [5, 5, 6], "fromstops": [5, 6, 9], "length": 3}, "outputs": {"tooffsets": [0, 0, 1, 4]}}, {"error": false, "inputs": {"fromstarts": [4, 4], "fromstops": [4, 6], "length": 2}, "outputs": {"tooffsets": [0, 0, 2]}}, {"error": false, "inputs": {"fromstarts": [3, 3, 6], "fromstops": [3, 5, 10], "length": 3}, "outputs": {"tooffsets": [0, 0, 2, 6]}}, {"error": false, "inputs": {"fromstarts": [4, 4, 7], "fromstops": [4, 6, 12], "length": 3}, "outputs": {"tooffsets": [0, 0, 2, 7]}}, {"error": false, "inputs": {"fromstarts": [5, 6, 6], "fromstops": [6, 6, 10], "length": 3}, "outputs": {"tooffsets": [0, 1, 1, 5]}}, {"error": false, "inputs": {"fromstarts": [6, 7, 7], "fromstops": [7, 7, 12], "length": 3}, "outputs": {"tooffsets": [0, 1, 1, 6]}}, {"error": false, "inputs": {"fromstarts": [3, 3, 3, 0, 4], "fromstops": [4, 4, 3, 3, 6], "length": 5}, "outputs": {"tooffsets": [0, 1, 2, 2, 5, 7]}}, {"error": false, "inputs": {"fromstarts": [2, 4, 5], "fromstops": [3, 5, 6], "length": 3}, "outputs": {"tooffsets": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromstarts": [5, 5, 0, 3, 3, 6, 6], "fromstops": [6, 6, 3, 3, 5, 6, 10], "length": 7}, "outputs": {"tooffsets": [0, 1, 2, 5, 5, 7, 7, 11]}}, {"error": false, "inputs": {"fromstarts": [3, 5, 5, 5, 5], "fromstops": [5, 5, 5, 5, 9], "length": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 2, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 5, 8], "fromstops": [2, 3, 5, 6, 9], "length": 5}, "outputs": {"tooffsets": [0, 2, 2, 4, 5, 6]}}, {"error": false, "inputs": {"fromstarts": [3, 3, 0, 5, 5, 6], "fromstops": [5, 3, 3, 6, 6, 10], "length": 6}, "outputs": {"tooffsets": [0, 2, 2, 5, 6, 7, 11]}}, {"error": false, "inputs": {"fromstarts": [3, 15], "fromstops": [5, 16], "length": 2}, "outputs": {"tooffsets": [0, 2, 3]}}, {"error": false, "inputs": {"fromstarts": [0, 2, 4, 5, 6, 9], "fromstops": [2, 3, 5, 6, 7, 11], "length": 6}, "outputs": {"tooffsets": [0, 2, 3, 4, 5, 6, 8]}}, {"error": false, "inputs": {"fromstarts": [0, 2], "fromstops": [2, 4], "length": 2}, "outputs": {"tooffsets": [0, 2, 4]}}, {"error": false, "inputs": {"fromstarts": [3, 3, 3, 0], "fromstops": [5, 5, 3, 3], "length": 4}, "outputs": {"tooffsets": [0, 2, 4, 4, 7]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 2, 5, 3, 6], "fromstops": [2, 5, 3, 6, 3, 6], "length": 6}, "outputs": {"tooffsets": [0, 2, 4, 5, 6, 6, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 3, 3], "fromstops": [2, 2, 2, 5, 5], "length": 5}, "outputs": {"tooffsets": [0, 2, 4, 6, 8, 10]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 0, 0, 0, 4, 4, 4, 4], "fromstops": [2, 2, 2, 2, 2, 2, 5, 5, 5, 5], "length": 10}, "outputs": {"tooffsets": [0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 3, 3, 5, 5, 5, 8, 8], "fromstops": [2, 2, 2, 5, 5, 7, 7, 7, 10, 10], "length": 10}, "outputs": {"tooffsets": [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]}}, {"error": false, "inputs": {"fromstarts": [3, 6], "fromstops": [5, 10], "length": 2}, "outputs": {"tooffsets": [0, 2, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 3], "fromstops": [3, 3], "length": 2}, "outputs": {"tooffsets": [0, 3, 3]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 4], "fromstops": [3, 3, 4, 5], "length": 4}, "outputs": {"tooffsets": [0, 3, 3, 4, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"fromstarts": [1, 99, 5], "fromstops": [4, 99, 7], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 10, 10], "fromstops": [3, 3, 5, 10, 13], "length": 5}, "outputs": {"tooffsets": [0, 3, 3, 5, 5, 8]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 15, 16], "fromstops": [3, 3, 5, 16, 20], "length": 5}, "outputs": {"tooffsets": [0, 3, 3, 5, 6, 10]}}, {"error": false, "inputs": {"fromstarts": [0, 4, 4, 6, 9], "fromstops": [3, 4, 6, 7, 11], "length": 5}, "outputs": {"tooffsets": [0, 3, 3, 5, 6, 8]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5}, "outputs": {"tooffsets": [0, 3, 3, 5, 8, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 9], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 7]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 6], "fromstops": [3, 3, 10], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 7]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [9, 6, 5, 3, 3], "length": 5}, "outputs": {"tooffsets": [0, 3, 4, 6, 6, 9]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 6, 0], "fromstops": [9, 6, 9, 3], "length": 4}, "outputs": {"tooffsets": [0, 3, 4, 7, 10]}}, {"error": false, "inputs": {"fromstarts": [0, 6, 3, 8, 3, 5], "fromstops": [3, 8, 3, 9, 5, 6], "length": 6}, "outputs": {"tooffsets": [0, 3, 5, 5, 6, 8, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 4, 6, 3, 6, 7], "fromstops": [3, 6, 7, 4, 6, 9], "length": 6}, "outputs": {"tooffsets": [0, 3, 5, 6, 7, 7, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 4, 6, 3, 7], "fromstops": [3, 6, 7, 4, 9], "length": 5}, "outputs": {"tooffsets": [0, 3, 5, 6, 7, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 6, 3, 8, 5, 9], "fromstops": [3, 8, 5, 9, 6, 10], "length": 6}, "outputs": {"tooffsets": [0, 3, 5, 7, 8, 9, 10]}}, {"error": false, "inputs": {"fromstarts": [0, 0], "fromstops": [3, 3], "length": 2}, "outputs": {"tooffsets": [0, 3, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 3], "fromstops": [3, 6], "length": 2}, "outputs": {"tooffsets": [0, 3, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 10, 14, 18], "fromstops": [3, 6, 14, 18, 21], "length": 5}, "outputs": {"tooffsets": [0, 3, 6, 10, 14, 17]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 6, 11, 15, 19], "fromstops": [3, 6, 11, 15, 19, 22], "length": 6}, "outputs": {"tooffsets": [0, 3, 6, 11, 15, 19, 22]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0], "fromstops": [3, 3, 3], "length": 3}, "outputs": {"tooffsets": [0, 3, 6, 9]}}, {"error": false, "inputs": {"fromstarts": [3, 6, 17, 20, 11, 25], "fromstops": [6, 9, 20, 23, 13, 27], "length": 6}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 14, 16]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3], "length": 5}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 11, 14, 17], "fromstops": [3, 6, 14, 17, 20], "length": 5}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3, 3], "length": 6}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 15, 18]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3, 3, 3], "length": 7}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 15, 18, 21]}}, {"error": false, "inputs": {"fromstarts": [0, 5], "fromstops": [3, 9], "length": 2}, "outputs": {"tooffsets": [0, 3, 7]}}, {"error": false, "inputs": {"fromstarts": [3, 6, 11, 15, 19], "fromstops": [6, 11, 15, 19, 22], "length": 5}, "outputs": {"tooffsets": [0, 3, 8, 12, 16, 19]}}, {"error": false, "inputs": {"fromstarts": [0, 13, 3, 18, 8, 23], "fromstops": [3, 18, 8, 23, 13, 28], "length": 6}, "outputs": {"tooffsets": [0, 3, 8, 13, 18, 23, 28]}}, {"error": false, "inputs": {"fromstarts": [16], "fromstops": [20], "length": 1}, "outputs": {"tooffsets": [0, 4]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "length": 4}, "outputs": {"tooffsets": [0, 4, 5, 7, 10]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "length": 5}, "outputs": {"tooffsets": [0, 4, 5, 7, 7, 10]}}, {"error": false, "inputs": {"fromstarts": [3, 0, 999, 2, 6, 10], "fromstops": [7, 3, 999, 4, 6, 12], "length": 6}, "outputs": {"tooffsets": [0, 4, 7, 7, 9, 9, 11]}}, {"error": false, "inputs": {"fromstarts": [0, 13, 4, 18, 8, 23], "fromstops": [4, 18, 8, 23, 13, 28], "length": 6}, "outputs": {"tooffsets": [0, 4, 9, 13, 18, 23, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 14, 4, 19, 9, 24], "fromstops": [4, 19, 9, 24, 14, 29], "length": 6}, "outputs": {"tooffsets": [0, 4, 9, 14, 19, 24, 29]}}, {"error": false, "inputs": {"fromstarts": [0, 11, 5, 16, 6, 17], "fromstops": [5, 16, 6, 17, 11, 22], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 11, 12, 17, 22]}}, {"error": false, "inputs": {"fromstarts": [0, 14, 5, 19, 9, 23], "fromstops": [5, 19, 9, 23, 14, 28], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 14, 18, 23, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 8, 11, 11, 14], "fromstops": [5, 5, 5, 11, 14, 14, 19], "length": 7}, "outputs": {"tooffsets": [0, 5, 10, 15, 18, 21, 24, 29]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 5, 20, 10, 24], "fromstops": [5, 20, 10, 24, 15, 28], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 19, 24, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 10, 15, 25], "fromstops": [5, 15, 20, 30], "length": 4}, "outputs": {"tooffsets": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 10, 25], "fromstops": [5, 20, 15, 30], "length": 4}, "outputs": {"tooffsets": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"fromstarts": [15, 10, 5, 0], "fromstops": [20, 15, 10, 5], "length": 4}, "outputs": {"tooffsets": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"fromstarts": [15, 5, 10, 0], "fromstops": [20, 10, 15, 5], "length": 4}, "outputs": {"tooffsets": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"fromstarts": [0, 14, 5, 19, 10, 24], "fromstops": [5, 19, 10, 24, 14, 28], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 24, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 28], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 29], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 29]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 30], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [0, 45, 5, 50, 10, 55], "fromstops": [5, 50, 10, 55, 15, 60], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [0, 5, 10, 15, 20, 25], "fromstops": [5, 10, 15, 20, 25, 30], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [0, 5, 10, 45, 50, 55], "fromstops": [5, 10, 15, 50, 55, 60], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [1, 16, 6, 21, 11, 26], "fromstops": [6, 21, 11, 26, 16, 31], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [25, 10, 20, 5, 15, 0], "fromstops": [30, 15, 25, 10, 20, 5], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [25, 20, 15, 10, 5, 0], "fromstops": [30, 25, 20, 15, 10, 5], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [0, 8, 11, 11, 14], "fromstops": [5, 11, 14, 14, 19], "length": 5}, "outputs": {"tooffsets": [0, 5, 8, 11, 14, 19]}}, {"error": false, "inputs": {"fromstarts": [6, 11, 14, 17, 20], "fromstops": [11, 14, 17, 20, 25], "length": 5}, "outputs": {"tooffsets": [0, 5, 8, 11, 14, 19]}}, {"error": false, "inputs": {"fromstarts": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203], "fromstops": [7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210], "length": 30}, "outputs": {"tooffsets": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210]}}]}, {"name": "awkward_RegularArray_localindex", "tests": [{"error": false, "inputs": {"length": 2, "size": 3}, "outputs": {"toindex": [0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"length": 6, "size": 5}, "outputs": {"toindex": [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]}}]}, {"name": "awkward_RegularArray_rpad_and_clip_axis1", "tests": [{"error": false, "inputs": {"length": 3, "size": 2, "target": 2}, "outputs": {"toindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 2, "size": 3, "target": 3}, "outputs": {"toindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 3, "size": 3, "target": 3}, "outputs": {"toindex": [0, 1, 2, 3, 4, 5, 6, 7, 8]}}, {"error": false, "inputs": {"length": 3, "size": 3, "target": 2}, "outputs": {"toindex": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"length": 6, "size": 5, "target": 2}, "outputs": {"toindex": [0, 1, 5, 6, 10, 11, 15, 16, 20, 21, 25, 26]}}, {"error": false, "inputs": {"length": 3, "size": 2, "target": 1}, "outputs": {"toindex": [0, 2, 4]}}, {"error": false, "inputs": {"length": 3, "size": 3, "target": 1}, "outputs": {"toindex": [0, 3, 6]}}]}, {"name": "awkward_RegularArray_compact_offsets", "tests": [{"error": false, "inputs": {"length": 1, "size": 1}, "outputs": {"tooffsets": [0, 1]}}, {"error": false, "inputs": {"length": 2, "size": 1}, "outputs": {"tooffsets": [0, 1, 2]}}, {"error": false, "inputs": {"length": 3, "size": 1}, "outputs": {"tooffsets": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 6, "size": 1}, "outputs": {"tooffsets": [0, 1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"length": 3, "size": 2}, "outputs": {"tooffsets": [0, 2, 4, 6]}}, {"error": false, "inputs": {"length": 1, "size": 3}, "outputs": {"tooffsets": [0, 3]}}, {"error": false, "inputs": {"length": 2, "size": 3}, "outputs": {"tooffsets": [0, 3, 6]}}, {"error": false, "inputs": {"length": 1, "size": 4}, "outputs": {"tooffsets": [0, 4]}}, {"error": false, "inputs": {"length": 6, "size": 5}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"length": 4, "size": 5}, "outputs": {"tooffsets": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"length": 1, "size": 5}, "outputs": {"tooffsets": [0, 5]}}, {"error": false, "inputs": {"length": 30, "size": 7}, "outputs": {"tooffsets": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210]}}]}, {"name": "awkward_RegularArray_getitem_carry", "tests": [{"error": false, "inputs": {"fromcarry": [0, 0], "lencarry": 2, "size": 1}, "outputs": {"tocarry": [0, 0]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 0, 1, 1, 1], "lencarry": 6, "size": 1}, "outputs": {"tocarry": [0, 0, 0, 1, 1, 1]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 0, 2, 2], "lencarry": 5, "size": 1}, "outputs": {"tocarry": [0, 0, 0, 2, 2]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 1, 1, 2, 2, 3, 3, 4, 4], "lencarry": 10, "size": 1}, "outputs": {"tocarry": [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 0, 1, 0, 1, 3, 4, 3, 4], "lencarry": 10, "size": 1}, "outputs": {"tocarry": [0, 1, 0, 1, 0, 1, 3, 4, 3, 4]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 1, 1], "lencarry": 4, "size": 2}, "outputs": {"tocarry": [0, 1, 0, 1, 2, 3, 2, 3]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 0, 0], "lencarry": 4, "size": 3}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 1, 2], "lencarry": 4, "size": 2}, "outputs": {"tocarry": [0, 1, 2, 3, 2, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [0, 0], "lencarry": 2, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 0, 1, 1, 1], "lencarry": 6, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromcarry": [0, 2, 3, 5], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [0, 2, 4], "lencarry": 3, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromcarry": [0, 3, 6, 9], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 30, 31, 32, 33, 34, 45, 46, 47, 48, 49]}}, {"error": false, "inputs": {"fromcarry": [0, 3, 1, 4, 2, 5], "lencarry": 6, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [0, 4, 8, 10], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44, 50, 51, 52, 53, 54]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 1, 1], "lencarry": 4, "size": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2], "lencarry": 12, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5], "lencarry": 12, "size": 5}, "outputs": {"tocarry": [0, 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, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [2, 0, 0, 1], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromcarry": [2, 2, 2, 2], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [10, 11, 12, 13, 14, 10, 11, 12, 13, 14, 10, 11, 12, 13, 14, 10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"fromcarry": [2], "lencarry": 1, "size": 5}, "outputs": {"tocarry": [10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"fromcarry": [2, 5, 8, 11], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [10, 11, 12, 13, 14, 25, 26, 27, 28, 29, 40, 41, 42, 43, 44, 55, 56, 57, 58, 59]}}, {"error": false, "inputs": {"fromcarry": [1], "lencarry": 1, "size": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"fromcarry": [3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5], "lencarry": 12, "size": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 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]}}, {"error": false, "inputs": {"fromcarry": [3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5], "lencarry": 12, "size": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [3, 4, 5], "lencarry": 3, "size": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [4, 4, 4, 4], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [20, 21, 22, 23, 24, 20, 21, 22, 23, 24, 20, 21, 22, 23, 24, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromcarry": [4], "lencarry": 1, "size": 5}, "outputs": {"tocarry": [20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromcarry": [2], "lencarry": 1, "size": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"fromcarry": [1, 0], "lencarry": 2, "size": 2}, "outputs": {"tocarry": [2, 3, 0, 1]}}, {"error": false, "inputs": {"fromcarry": [1], "lencarry": 1, "size": 2}, "outputs": {"tocarry": [2, 3]}}, {"error": false, "inputs": {"fromcarry": [1, 1, 0, 0], "lencarry": 4, "size": 2}, "outputs": {"tocarry": [2, 3, 2, 3, 0, 1, 0, 1]}}, {"error": false, "inputs": {"fromcarry": [1, 2], "lencarry": 2, "size": 2}, "outputs": {"tocarry": [2, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [1, 0, 0, 1], "lencarry": 4, "size": 3}, "outputs": {"tocarry": [3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [1], "lencarry": 1, "size": 3}, "outputs": {"tocarry": [3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [1, 1, 1, 1], "lencarry": 4, "size": 3}, "outputs": {"tocarry": [3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [2], "lencarry": 1, "size": 2}, "outputs": {"tocarry": [4, 5]}}, {"error": false, "inputs": {"fromcarry": [1, 2], "lencarry": 2, "size": 4}, "outputs": {"tocarry": [4, 5, 6, 7, 8, 9, 10, 11]}}, {"error": false, "inputs": {"fromcarry": [1, 2], "lencarry": 2, "size": 5}, "outputs": {"tocarry": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"fromcarry": [1, 2, 3, 4, 5], "lencarry": 5, "size": 5}, "outputs": {"tocarry": [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]}}, {"error": false, "inputs": {"fromcarry": [1], "lencarry": 1, "size": 5}, "outputs": {"tocarry": [5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromcarry": [1, 3, 6, 10], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [5, 6, 7, 8, 9, 15, 16, 17, 18, 19, 30, 31, 32, 33, 34, 50, 51, 52, 53, 54]}}, {"error": false, "inputs": {"fromcarry": [1, 4, 0, 5], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 0, 1, 2, 3, 4, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [2, 1, 1, 2], "lencarry": 4, "size": 4}, "outputs": {"tocarry": [8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11]}}]}, {"name": "awkward_RegularArray_getitem_jagged_expand", "tests": [{"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 0, 0, 0, 0]}, "outputs": {"multistarts": [0, 0, 0, 0], "multistops": [0, 0, 0, 0]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 0, 0, 0]}, "outputs": {"multistarts": [0, 0, 0], "multistops": [0, 0, 0]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 0, 1, 1, 1]}, "outputs": {"multistarts": [0, 0, 1, 1], "multistops": [0, 1, 1, 1]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 1, 1, 3]}, "outputs": {"multistarts": [0, 1, 1], "multistops": [1, 1, 3]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 1, 1, 3, 3, 5]}, "outputs": {"multistarts": [0, 1, 1, 3, 3], "multistops": [1, 1, 3, 3, 5]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 2, 2, 2, 2, 6]}, "outputs": {"multistarts": [0, 2, 2, 2, 2], "multistops": [2, 2, 2, 2, 6]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 2, 3]}, "outputs": {"multistarts": [0, 2, 2], "multistops": [2, 2, 3]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 2, 4]}, "outputs": {"multistarts": [0, 2, 2], "multistops": [2, 2, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 2, "singleoffsets": [0, 2, 4]}, "outputs": {"multistarts": [0, 2], "multistops": [2, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 7, "singleoffsets": [0, 2, 2, 4, 4, 5, 5, 8]}, "outputs": {"multistarts": [0, 2, 2, 4, 4, 5, 5], "multistops": [2, 2, 4, 4, 5, 5, 8]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 2, 2, 4, 5, 6]}, "outputs": {"multistarts": [0, 2, 2, 4, 5], "multistops": [2, 2, 4, 5, 6]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 2, 2, 4, 5, 8]}, "outputs": {"multistarts": [0, 2, 2, 4, 5], "multistops": [2, 2, 4, 5, 8]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 2, 2, 4, 5, 9]}, "outputs": {"multistarts": [0, 2, 2, 4, 5], "multistops": [2, 2, 4, 5, 9]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 3, 4]}, "outputs": {"multistarts": [0, 2, 3], "multistops": [2, 3, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 2, 3, 3, 5]}, "outputs": {"multistarts": [0, 2, 3, 3], "multistops": [2, 3, 3, 5]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 2, 3, 4, 7]}, "outputs": {"multistarts": [0, 2, 3, 4], "multistops": [2, 3, 4, 7]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 5, 7]}, "outputs": {"multistarts": [0, 2, 5], "multistops": [2, 5, 7]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 6, 8]}, "outputs": {"multistarts": [0, 2, 6], "multistops": [2, 6, 8]}}, {"error": false, "inputs": {"regularlength": 2, "regularsize": 2, "singleoffsets": [0, 3, 4]}, "outputs": {"multistarts": [0, 3, 0, 3], "multistops": [3, 4, 3, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 3, 3, 4]}, "outputs": {"multistarts": [0, 3, 3], "multistops": [3, 3, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 3, 3, 5]}, "outputs": {"multistarts": [0, 3, 3], "multistops": [3, 3, 5]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 3, 3, 3, 4, 7]}, "outputs": {"multistarts": [0, 3, 3, 3, 4], "multistops": [3, 3, 3, 4, 7]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 2, "singleoffsets": [0, 3, 4]}, "outputs": {"multistarts": [0, 3], "multistops": [3, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 3, 3, 4, 5]}, "outputs": {"multistarts": [0, 3, 3, 4], "multistops": [3, 3, 4, 5]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 3, 3, 4, 5, 8]}, "outputs": {"multistarts": [0, 3, 3, 4, 5], "multistops": [3, 3, 4, 5, 8]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 3, 3, 5, 6, 9]}, "outputs": {"multistarts": [0, 3, 3, 5, 6], "multistops": [3, 3, 5, 6, 9]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 2, "singleoffsets": [0, 3, 6]}, "outputs": {"multistarts": [0, 3], "multistops": [3, 6]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 4, 6, 6]}, "outputs": {"multistarts": [0, 4, 6], "multistops": [4, 6, 6]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 5, 5, 6, 8, 10]}, "outputs": {"multistarts": [0, 5, 5, 6, 8], "multistops": [5, 5, 6, 8, 10]}}]}, {"name": "awkward_RegularArray_getitem_next_array", "tests": [{"error": false, "inputs": {"fromarray": [0, 0, 0, 0], "lenarray": 4, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 0, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 0], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 0]}}, {"error": false, "inputs": {"fromarray": [0], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [0]}}, {"error": false, "inputs": {"fromarray": [0, 0, 1, 1, 1, 0], "lenarray": 6, "length": 1, "size": 4}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [0, 0, 1, 1, 1, 0]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 1, 1], "lenarray": 4, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2], "lenarray": 3, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2, 3], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 0, 1, 0, 1, 0, 1], "tocarry": [0, 1, 2, 3, 4, 5, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 2, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 1, 3]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 5], "lenarray": 5, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [0, 1, 3, 4, 5]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 5], "lenarray": 5, "length": 1, "size": 7}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [0, 1, 3, 4, 5]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 6, 7], "lenarray": 6, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 6, 7], "lenarray": 6, "length": 1, "size": 9}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 1, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4, 6, 7], "lenarray": 5, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [0, 1, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4, 6, 7], "lenarray": 5, "length": 1, "size": 9}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [0, 1, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 2], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 2]}}, {"error": false, "inputs": {"fromarray": [0, 2], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 2]}}, {"error": false, "inputs": {"fromarray": [0, 2, 1, 0], "lenarray": 4, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 2, 1, 0]}}, {"error": false, "inputs": {"fromarray": [0, 2, 3], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 2, 3]}}, {"error": false, "inputs": {"fromarray": [0, 2, 3, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 2, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 2, 4]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 3]}}, {"error": false, "inputs": {"fromarray": [0, 3, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "length": 2, "size": 4}, "outputs": {"toadvanced": [0, 1, 0, 1], "tocarry": [0, 3, 4, 7]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "length": 3, "size": 4}, "outputs": {"toadvanced": [0, 1, 0, 1, 0, 1], "tocarry": [0, 3, 4, 7, 8, 11]}}, {"error": false, "inputs": {"fromarray": [0, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 4]}}, {"error": false, "inputs": {"fromarray": [1, 0, 0, 1], "lenarray": 4, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0], "lenarray": 2, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 0]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1, 1, 1, 0], "lenarray": 6, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [1, 0, 1, 1, 1, 0]}}, {"error": false, "inputs": {"fromarray": [1], "lenarray": 1, "length": 1, "size": 2}, "outputs": {"toadvanced": [0], "tocarry": [1]}}, {"error": false, "inputs": {"fromarray": [1], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1], "lenarray": 3, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2], "tocarry": [1, 0, 1, 3, 2, 3, 5, 4, 5, 7, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 0], "lenarray": 2, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 0, 1, 0, 1, 0, 1], "tocarry": [1, 0, 3, 2, 5, 4, 7, 6]}}, {"error": false, "inputs": {"fromarray": [1, 1, 1, 1], "lenarray": 4, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [1, 2], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 2]}}, {"error": false, "inputs": {"fromarray": [1, 2], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 2]}}, {"error": false, "inputs": {"fromarray": [1, 2, 3], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [1, 2, 3]}}, {"error": false, "inputs": {"fromarray": [1, 2, 3, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [1, 2, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [1, 2, 4]}}, {"error": false, "inputs": {"fromarray": [1, 3], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 3]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [1, 3, 4]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4, 6, 7], "lenarray": 5, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4, 6, 7], "lenarray": 5, "length": 1, "size": 9}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 4]}}, {"error": false, "inputs": {"fromarray": [1, 4, 0, 5], "lenarray": 4, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 4, 0, 5]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 1], "lenarray": 4, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [2, 0], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 0]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 1, 4], "lenarray": 5, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [2, 0, 0, 1, 4]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 2], "lenarray": 4, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 0, 0, 2]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 0, 0, 4]}}, {"error": false, "inputs": {"fromarray": [2], "lenarray": 1, "length": 1, "size": 3}, "outputs": {"toadvanced": [0], "tocarry": [2]}}, {"error": false, "inputs": {"fromarray": [2], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [2]}}, {"error": false, "inputs": {"fromarray": [2, 1, 1, 2], "lenarray": 4, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 1, 1, 2]}}, {"error": false, "inputs": {"fromarray": [2, 1, 1, 3], "lenarray": 4, "length": 2, "size": 4}, "outputs": {"toadvanced": [0, 1, 2, 3, 0, 1, 2, 3], "tocarry": [2, 1, 1, 3, 6, 5, 5, 7]}}, {"error": false, "inputs": {"fromarray": [2, 1, 1, 3], "lenarray": 4, "length": 3, "size": 4}, "outputs": {"toadvanced": [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], "tocarry": [2, 1, 1, 3, 6, 5, 5, 7, 10, 9, 9, 11]}}, {"error": false, "inputs": {"fromarray": [2, 2], "lenarray": 2, "length": 1, "size": 4}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 2, 2, 2], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 2, 2, 2], "lenarray": 4, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 3], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromarray": [2, 3], "lenarray": 2, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromarray": [2, 3, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [2, 3, 4, 5, 6], "lenarray": 5, "length": 1, "size": 7}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromarray": [2, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 4]}}, {"error": false, "inputs": {"fromarray": [3], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [3]}}, {"error": false, "inputs": {"fromarray": [3, 1, 1, 7], "lenarray": 4, "length": 1, "size": 10}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 1, 1, 7]}}, {"error": false, "inputs": {"fromarray": [3, 2, 1, 0], "lenarray": 4, "length": 1, "size": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 2, 1, 0]}}, {"error": false, "inputs": {"fromarray": [3, 2, 1], "lenarray": 3, "length": 1, "size": 4}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [3, 2, 1]}}, {"error": false, "inputs": {"fromarray": [3, 3, 3], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [3, 3, 3]}}, {"error": false, "inputs": {"fromarray": [3, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [3, 4]}}, {"error": false, "inputs": {"fromarray": [3, 6, 8, 6], "lenarray": 4, "length": 1, "size": 10}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 6, 8, 6]}}, {"error": false, "inputs": {"fromarray": [4], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [4]}}, {"error": false, "inputs": {"fromarray": [4, 3, 2], "lenarray": 3, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [4, 3, 2]}}, {"error": false, "inputs": {"fromarray": [4, 3, 2, 1], "lenarray": 4, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 3, 2, 1]}}, {"error": false, "inputs": {"fromarray": [4, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [4, 4]}}, {"error": false, "inputs": {"fromarray": [4, 4, 4, 4], "lenarray": 4, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 4, 4, 4]}}, {"error": false, "inputs": {"fromarray": [4, 5], "lenarray": 2, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1], "tocarry": [4, 5]}}, {"error": false, "inputs": {"fromarray": [7, 3, 0, 2, 3, 7], "lenarray": 6, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [7, 3, 0, 2, 3, 7]}}, {"error": false, "inputs": {"fromarray": [7, 3, 2, 0, 2, 3, 7], "lenarray": 7, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5, 6], "tocarry": [7, 3, 2, 0, 2, 3, 7]}}, {"error": false, "inputs": {"fromarray": [7, 3, 2, 0, 3, 7], "lenarray": 6, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [7, 3, 2, 0, 3, 7]}}]}, {"name": "awkward_RegularArray_getitem_next_array_advanced", "tests": [{"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, 0, 1], "lenarray": 4, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 3, 4, 7]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "lenarray": 4, "length": 4, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 3, 6, 9]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, 2, 1], "lenarray": 4, "length": 4, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 4, 8, 10]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 5, 10, 15]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, 4, 1], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 6, 14, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 1, 0], "lenarray": 4, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 2, 5, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "lenarray": 4, "length": 4, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 3, 6, 10]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 5, 10, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 3, 0, 4], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 8, 10, 19]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 0, 0, 1], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 5, 10, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 2, 2, 2], "lenarray": 4, "length": 4, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 5, 8, 11]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 2, 2, 2], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 7, 12, 17]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [3, 3, 3, 3], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 8, 13, 18]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [4, 4, 4, 4], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 9, 14, 19]}}]}, {"name": "awkward_RegularArray_getitem_next_array_regularize", "tests": [{"error": false, "inputs": {"fromarray": [0, 0, 0, 0], "lenarray": 4, "size": 2}, "outputs": {"toarray": [0, 0, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 0, 0, 0], "lenarray": 4, "size": 3}, "outputs": {"toarray": [0, 0, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 0, 0, 0], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 0, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 0], "lenarray": 2, "size": 3}, "outputs": {"toarray": [0, 0]}}, {"error": false, "inputs": {"fromarray": [0], "lenarray": 1, "size": 5}, "outputs": {"toarray": [0]}}, {"error": false, "inputs": {"fromarray": [0, 1, 0, 1], "lenarray": 4, "size": 2}, "outputs": {"toarray": [0, 1, 0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "size": 2}, "outputs": {"toarray": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "size": 3}, "outputs": {"toarray": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "size": 5}, "outputs": {"toarray": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "size": 6}, "outputs": {"toarray": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 1, 1], "lenarray": 4, "size": 2}, "outputs": {"toarray": [0, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2], "lenarray": 3, "size": 3}, "outputs": {"toarray": [0, 1, 2]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 1, 2]}}, {"error": false, "inputs": {"fromarray": [0, 1, 1, 1], "lenarray": 4, "size": 3}, "outputs": {"toarray": [0, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2, 3], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2, 4], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 1, 2, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 1, 3]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 1, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 5], "lenarray": 5, "size": 6}, "outputs": {"toarray": [0, 1, 3, 4, 5]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 5], "lenarray": 5, "size": 7}, "outputs": {"toarray": [0, 1, 3, 4, 5]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 6, 7], "lenarray": 6, "size": 8}, "outputs": {"toarray": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 6, 7], "lenarray": 6, "size": 9}, "outputs": {"toarray": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 1, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4, 6, 7], "lenarray": 5, "size": 8}, "outputs": {"toarray": [0, 1, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4, 6, 7], "lenarray": 5, "size": 9}, "outputs": {"toarray": [0, 1, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 2], "lenarray": 2, "size": 3}, "outputs": {"toarray": [0, 2]}}, {"error": false, "inputs": {"fromarray": [0, 2], "lenarray": 2, "size": 5}, "outputs": {"toarray": [0, 2]}}, {"error": false, "inputs": {"fromarray": [0, 2, 1, 0], "lenarray": 4, "size": 3}, "outputs": {"toarray": [0, 2, 1, 0]}}, {"error": false, "inputs": {"fromarray": [0, 2, 3], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 2, 3]}}, {"error": false, "inputs": {"fromarray": [0, 2, 3, 4], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 2, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 2, 4]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "size": 4}, "outputs": {"toarray": [0, 3]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "size": 5}, "outputs": {"toarray": [0, 3]}}, {"error": false, "inputs": {"fromarray": [0, 3, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [0, 4]}}, {"error": false, "inputs": {"fromarray": [1, 0, 0, 1], "lenarray": 4, "size": 2}, "outputs": {"toarray": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 0, 1], "lenarray": 4, "size": 3}, "outputs": {"toarray": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 0, 1], "lenarray": 4, "size": 5}, "outputs": {"toarray": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1, 0], "lenarray": 4, "size": 2}, "outputs": {"toarray": [1, 0, 1, 0]}}, {"error": false, "inputs": {"fromarray": [1, 0], "lenarray": 2, "size": 2}, "outputs": {"toarray": [1, 0]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1], "lenarray": 3, "size": 2}, "outputs": {"toarray": [1, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1, 1, 1, 0], "lenarray": 6, "size": 2}, "outputs": {"toarray": [1, 0, 1, 1, 1, 0]}}, {"error": false, "inputs": {"fromarray": [1, 1, 1, 1], "lenarray": 4, "size": 2}, "outputs": {"toarray": [1, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [1], "lenarray": 1, "size": 2}, "outputs": {"toarray": [1]}}, {"error": false, "inputs": {"fromarray": [1], "lenarray": 1, "size": 5}, "outputs": {"toarray": [1]}}, {"error": false, "inputs": {"fromarray": [1, 2], "lenarray": 2, "size": 3}, "outputs": {"toarray": [1, 2]}}, {"error": false, "inputs": {"fromarray": [1, 2], "lenarray": 2, "size": 5}, "outputs": {"toarray": [1, 2]}}, {"error": false, "inputs": {"fromarray": [1, 2, 3], "lenarray": 3, "size": 5}, "outputs": {"toarray": [1, 2, 3]}}, {"error": false, "inputs": {"fromarray": [1, 2, 3, 4], "lenarray": 4, "size": 5}, "outputs": {"toarray": [1, 2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [1, 2, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [1, 2, 4]}}, {"error": false, "inputs": {"fromarray": [1, 3], "lenarray": 2, "size": 5}, "outputs": {"toarray": [1, 3]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [1, 3, 4]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4, 6, 7], "lenarray": 5, "size": 8}, "outputs": {"toarray": [1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4, 6, 7], "lenarray": 5, "size": 9}, "outputs": {"toarray": [1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [1, 4]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 1], "lenarray": 4, "size": 5}, "outputs": {"toarray": [2, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 1], "lenarray": 4, "size": 6}, "outputs": {"toarray": [2, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [2, 0], "lenarray": 2, "size": 3}, "outputs": {"toarray": [2, 0]}}, {"error": false, "inputs": {"fromarray": [2], "lenarray": 1, "size": 3}, "outputs": {"toarray": [2]}}, {"error": false, "inputs": {"fromarray": [2], "lenarray": 1, "size": 5}, "outputs": {"toarray": [2]}}, {"error": false, "inputs": {"fromarray": [2, 2, 2, 2], "lenarray": 4, "size": 5}, "outputs": {"toarray": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 2, 2, 2], "lenarray": 4, "size": 6}, "outputs": {"toarray": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 2], "lenarray": 2, "size": 4}, "outputs": {"toarray": [2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 3], "lenarray": 2, "size": 5}, "outputs": {"toarray": [2, 3]}}, {"error": false, "inputs": {"fromarray": [2, 3], "lenarray": 2, "size": 6}, "outputs": {"toarray": [2, 3]}}, {"error": false, "inputs": {"fromarray": [2, 3, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [2, 3, 4, 5, 6], "lenarray": 5, "size": 7}, "outputs": {"toarray": [2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromarray": [2, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [2, 4]}}, {"error": false, "inputs": {"fromarray": [3, 1, 1, 7], "lenarray": 4, "size": 10}, "outputs": {"toarray": [3, 1, 1, 7]}}, {"error": false, "inputs": {"fromarray": [3, 2, 1, 0], "lenarray": 4, "size": 4}, "outputs": {"toarray": [3, 2, 1, 0]}}, {"error": false, "inputs": {"fromarray": [3, 2, 1], "lenarray": 3, "size": 4}, "outputs": {"toarray": [3, 2, 1]}}, {"error": false, "inputs": {"fromarray": [3], "lenarray": 1, "size": 5}, "outputs": {"toarray": [3]}}, {"error": false, "inputs": {"fromarray": [3, 3, 3], "lenarray": 3, "size": 5}, "outputs": {"toarray": [3, 3, 3]}}, {"error": false, "inputs": {"fromarray": [3, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [3, 4]}}, {"error": false, "inputs": {"fromarray": [4, 3, 2, 1], "lenarray": 4, "size": 8}, "outputs": {"toarray": [4, 3, 2, 1]}}, {"error": false, "inputs": {"fromarray": [4, 3, 2], "lenarray": 3, "size": 8}, "outputs": {"toarray": [4, 3, 2]}}, {"error": false, "inputs": {"fromarray": [4], "lenarray": 1, "size": 5}, "outputs": {"toarray": [4]}}, {"error": false, "inputs": {"fromarray": [4, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [4, 4]}}, {"error": false, "inputs": {"fromarray": [4, 5], "lenarray": 2, "size": 6}, "outputs": {"toarray": [4, 5]}}]}, {"name": "awkward_RegularArray_getitem_next_at", "tests": [{"error": false, "inputs": {"at": 0, "length": 1, "size": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 1, "size": 2}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 1, "size": 3}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 1, "size": 5}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 1, "size": 6}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 2, "size": 5}, "outputs": {"tocarry": [0, 5]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 2}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 3}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 4}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 5}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 6}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 2, "size": 5}, "outputs": {"tocarry": [1, 6]}}, {"error": false, "inputs": {"at": 2, "length": 1, "size": 3}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 2, "length": 1, "size": 4}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 2, "length": 1, "size": 5}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 2, "length": 1, "size": 6}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 2, "length": 5, "size": 5}, "outputs": {"tocarry": [2, 7, 12, 17, 22]}}, {"error": false, "inputs": {"at": 3, "length": 1, "size": 4}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 3, "length": 1, "size": 5}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 4, "length": 1, "size": 5}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": 4, "length": 1, "size": 6}, "outputs": {"tocarry": [4]}}]}, {"name": "awkward_RegularArray_getitem_next_range", "tests": [{"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 1, "step": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 2, "step": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 3, "step": 3}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 5, "step": 3}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 2, "step": 1}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 3, "step": 1}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 0, "size": 3, "step": 1}, "outputs": {"tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 4, "regular_start": 0, "size": 4, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 2, "nextsize": 2, "regular_start": 0, "size": 2, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 5, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 5, "regular_start": 0, "size": 6, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 6, "regular_start": 0, "size": 6, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 1, "nextsize": 8, "regular_start": 0, "size": 8, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7]}}, {"error": false, "inputs": {"length": 1, "nextsize": 10, "regular_start": 0, "size": 10, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"length": 3, "nextsize": 5, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"length": 5, "nextsize": 5, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"length": 2, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 5, 6, 7, 8]}}, {"error": false, "inputs": {"length": 3, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13]}}, {"error": false, "inputs": {"length": 5, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23]}}, {"error": false, "inputs": {"length": 6, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23, 25, 26, 27, 28]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 3, "step": 2}, "outputs": {"tocarry": [0, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 5, "step": 2}, "outputs": {"tocarry": [0, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 0, "size": 5, "step": 2}, "outputs": {"tocarry": [0, 2, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 0, "size": 6, "step": 2}, "outputs": {"tocarry": [0, 2, 4]}}, {"error": false, "inputs": {"length": 5, "nextsize": 3, "regular_start": 0, "size": 5, "step": 2}, "outputs": {"tocarry": [0, 2, 4, 5, 7, 9, 10, 12, 14, 15, 17, 19, 20, 22, 24]}}, {"error": false, "inputs": {"length": 6, "nextsize": 3, "regular_start": 0, "size": 5, "step": 2}, "outputs": {"tocarry": [0, 2, 4, 5, 7, 9, 10, 12, 14, 15, 17, 19, 20, 22, 24, 25, 27, 29]}}, {"error": false, "inputs": {"length": 1, "nextsize": 4, "regular_start": 0, "size": 8, "step": 2}, "outputs": {"tocarry": [0, 2, 4, 6]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 5, "step": 3}, "outputs": {"tocarry": [0, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 1, "size": 2, "step": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 1, "size": 3, "step": 2}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 1, "size": 3, "step": 3}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 1, "size": 5, "step": 3}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 1, "size": 3, "step": 1}, "outputs": {"tocarry": [1, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 1, "size": 4, "step": 1}, "outputs": {"tocarry": [1, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 5, "regular_start": 1, "size": 6, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 3, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14]}}, {"error": false, "inputs": {"length": 5, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22, 23, 24]}}, {"error": false, "inputs": {"length": 6, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22, 23, 24, 26, 27, 28, 29]}}, {"error": false, "inputs": {"length": 2, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 6, 7, 8, 9]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 1, "size": 5, "step": 2}, "outputs": {"tocarry": [1, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 1, "size": 5, "step": 3}, "outputs": {"tocarry": [1, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 2, "size": 3, "step": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 2, "size": 3, "step": 2}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 2, "size": 3, "step": 3}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 2, "size": 5, "step": 3}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 2, "size": 5, "step": 1}, "outputs": {"tocarry": [2, 3, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 3, "size": 5, "step": 1}, "outputs": {"tocarry": [3, 4]}}]}, {"name": "awkward_RegularArray_getitem_next_range_spreadadvanced", "tests": [{"error": false, "inputs": {"fromadvanced": [0], "length": 1, "nextsize": 2}, "outputs": {"toadvanced": [0, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "length": 2, "nextsize": 2}, "outputs": {"toadvanced": [0, 0, 1, 1]}}]}, {"name": "awkward_RegularArray_broadcast_tooffsets", "tests": [{"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6], "offsetslength": 4, "size": 2}, "outputs": {}}, {"error": false, "inputs": {"fromoffsets": [0, 3], "offsetslength": 2, "size": 3}, "outputs": {}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6], "offsetslength": 3, "size": 3}, "outputs": {}}, {"error": false, "inputs": {"fromoffsets": [0, 4], "offsetslength": 2, "size": 4}, "outputs": {}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "offsetslength": 7, "size": 5}, "outputs": {}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20], "offsetslength": 5, "size": 5}, "outputs": {}}, {"error": false, "inputs": {"fromoffsets": [0, 5], "offsetslength": 2, "size": 5}, "outputs": {}}, {"error": false, "inputs": {"fromoffsets": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210], "offsetslength": 31, "size": 7}, "outputs": {}}]}, {"name": "awkward_RegularArray_broadcast_tooffsets_size1", "tests": [{"error": false, "inputs": {"fromoffsets": [0, 5, 10], "offsetslength": 3}, "outputs": {"tocarry": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "offsetslength": 7}, "outputs": {"tocarry": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 4], "offsetslength": 2}, "outputs": {"tocarry": [0, 0, 0, 0]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 7, 7, 9, 9, 11], "offsetslength": 7}, "outputs": {"tocarry": [0, 0, 0, 0, 1, 1, 1, 3, 3, 5, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3], "offsetslength": 3}, "outputs": {"tocarry": [0, 0, 0]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6], "offsetslength": 3}, "outputs": {"tocarry": [0, 0, 0, 1, 1, 1]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5], "offsetslength": 4}, "outputs": {"tocarry": [0, 0, 0, 2, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 8, 8, 10], "offsetslength": 7}, "outputs": {"tocarry": [0, 0, 0, 2, 2, 3, 3, 3, 5, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 6, 10], "offsetslength": 6}, "outputs": {"tocarry": [0, 0, 0, 2, 2, 3, 4, 4, 4, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 3], "offsetslength": 3}, "outputs": {"tocarry": [0, 0, 1]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6, 8, 10], "offsetslength": 6}, "outputs": {"tocarry": [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20], "offsetslength": 11}, "outputs": {"tocarry": [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16], "offsetslength": 11}, "outputs": {"tocarry": [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 1], "offsetslength": 2}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 2], "offsetslength": 3}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 5], "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 1, 1, 1]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 2, 3], "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 2, 3, 4, 5, 6], "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5]}}]}, {"name": "awkward_ListOffsetArray_compact_offsets", "tests": [{"error": false, "inputs": {"fromoffsets": [3, 3, 4, 6], "length": 3}, "outputs": {"tooffsets": [0, 0, 1, 3]}}, {"error": false, "inputs": {"fromoffsets": [3, 3, 5], "length": 2}, "outputs": {"tooffsets": [0, 0, 2]}}, {"error": false, "inputs": {"fromoffsets": [5, 6, 10], "length": 2}, "outputs": {"tooffsets": [0, 1, 5]}}, {"error": false, "inputs": {"fromoffsets": [3, 5, 5, 5, 5, 9], "length": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 2, 6]}}, {"error": false, "inputs": {"fromoffsets": [3, 5, 6], "length": 2}, "outputs": {"tooffsets": [0, 2, 3]}}, {"error": false, "inputs": {"fromoffsets": [1, 4, 4, 6], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"fromoffsets": [1, 4, 7], "length": 2}, "outputs": {"tooffsets": [0, 3, 6]}}, {"error": false, "inputs": {"fromoffsets": [11, 14, 17, 20], "length": 3}, "outputs": {"tooffsets": [0, 3, 6, 9]}}, {"error": false, "inputs": {"fromoffsets": [20, 25], "length": 1}, "outputs": {"tooffsets": [0, 5]}}]}, {"name": "awkward_ListOffsetArray_flatten_offsets", "tests": [{"error": false, "inputs": {"inneroffsets": [0], "inneroffsetslen": 1, "outeroffsets": [0, 0, 0, 0, 0], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 2, 3], "inneroffsetslen": 4, "outeroffsets": [0, 0, 0, 1, 3], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 0, 0, 1, 3]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 2, 3, 4, 5, 6], "inneroffsetslen": 7, "outeroffsets": [0, 0, 1, 3, 6], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 0, 1, 3, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 1, 5], "inneroffsetslen": 4, "outeroffsets": [0, 0, 1, 3], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 0, 1, 5]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 1, 6, 6], "inneroffsetslen": 5, "outeroffsets": [0, 0, 1, 4], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 0, 1, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 4, 8, 12, 14, 16], "inneroffsetslen": 6, "outeroffsets": [0, 3, 3, 5], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 12, 12, 16]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 2, 5, 5, 7, 7, 11], "inneroffsetslen": 8, "outeroffsets": [0, 1, 2, 2, 5, 7], "outeroffsetslen": 6}, "outputs": {"tooffsets": [0, 1, 2, 2, 7, 11]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 2, 3, 4, 5, 6], "inneroffsetslen": 7, "outeroffsets": [0, 1, 3, 6], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 1, 3, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 5, 10, 15, 20, 25, 30], "inneroffsetslen": 7, "outeroffsets": [0, 3, 6], "outeroffsetslen": 3}, "outputs": {"tooffsets": [0, 15, 30]}}, {"error": false, "inputs": {"inneroffsets": [0, 2, 6], "inneroffsetslen": 3, "outeroffsets": [0, 1, 1, 1, 2], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 0, 2, 6], "inneroffsetslen": 4, "outeroffsets": [0, 2, 2, 2, 3], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 0, 0, 2, 6], "inneroffsetslen": 5, "outeroffsets": [0, 3, 3, 3, 4], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 0, 0, 0, 2, 7, 7], "inneroffsetslen": 7, "outeroffsets": [0, 4, 4, 4, 6], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 7]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 5, 6, 6], "inneroffsetslen": 5, "outeroffsets": [0, 1, 2, 3, 4], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 3, 5, 6, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210], "inneroffsetslen": 31, "outeroffsets": [0, 5, 10, 15, 20, 25, 30], "outeroffsetslen": 7}, "outputs": {"tooffsets": [0, 35, 70, 105, 140, 175, 210]}}, {"error": false, "inputs": {"inneroffsets": [0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16], "inneroffsetslen": 11, "outeroffsets": [0, 2, 4, 6, 8, 10], "outeroffsetslen": 6}, "outputs": {"tooffsets": [0, 4, 8, 12, 14, 16]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 5, 6, 6, 10], "inneroffsetslen": 6, "outeroffsets": [0, 2, 2, 3, 5], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 5, 5, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 5, 6, 6, 10], "inneroffsetslen": 7, "outeroffsets": [0, 3, 3, 4, 6], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 5, 5, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 3, 5, 6, 6, 10], "inneroffsetslen": 8, "outeroffsets": [0, 4, 4, 5, 7], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 5, 5, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 5, 5, 8], "inneroffsetslen": 6, "outeroffsets": [0, 3, 3, 5], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 5, 5, 8]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 6, 9, 12, 14, 16], "inneroffsetslen": 7, "outeroffsets": [0, 2, 4, 5, 6, 6, 6], "outeroffsetslen": 7}, "outputs": {"tooffsets": [0, 6, 12, 14, 16, 16, 16]}}, {"error": false, "inputs": {"inneroffsets": [0, 2, 4, 6, 8, 10], "inneroffsetslen": 6, "outeroffsets": [0, 3, 3, 5], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 6, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20], "inneroffsetslen": 11, "outeroffsets": [0, 3, 3, 5, 8, 8, 10], "outeroffsetslen": 7}, "outputs": {"tooffsets": [0, 6, 6, 10, 16, 16, 20]}}, {"error": false, "inputs": {"inneroffsets": [0, 4, 4, 4, 4, 6, 7, 7, 12, 12], "inneroffsetslen": 10, "outeroffsets": [0, 5, 5, 6, 9], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 6, 6, 7, 12]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 6, 9, 11, 13, 14], "inneroffsetslen": 7, "outeroffsets": [0, 3, 5, 6], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 9, 13, 14]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 5, 6, 6], "inneroffsetslen": 5, "outeroffsets": [1, 2, 3, 4], "outeroffsetslen": 4}, "outputs": {"tooffsets": [3, 5, 6, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 5, 6, 6, 10], "inneroffsetslen": 7, "outeroffsets": [3, 3, 4, 6], "outeroffsetslen": 4}, "outputs": {"tooffsets": [5, 5, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 3, 5, 6, 6, 10], "inneroffsetslen": 8, "outeroffsets": [4, 4, 5, 7], "outeroffsetslen": 4}, "outputs": {"tooffsets": [5, 5, 6, 10]}}]}, {"name": "awkward_ListOffsetArray_toRegularArray", "tests": [{"error": false, "inputs": {"fromoffsets": [0, 1, 2, 3], "offsetslength": 4}, "outputs": {"size": [1]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4], "offsetslength": 3}, "outputs": {"size": [2]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6], "offsetslength": 4}, "outputs": {"size": [2]}}, {"error": false, "inputs": {"fromoffsets": [0, 4], "offsetslength": 2}, "outputs": {"size": [4]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10], "offsetslength": 3}, "outputs": {"size": [5]}}]}, {"name": "awkward_MaskedArray_getitem_next_jagged_project", "tests": [{"error": false, "inputs": {"index": [0, 1, 2, 3], "length": 4, "starts_in": [0, 2, 3, 3], "stops_in": [2, 3, 3, 3]}, "outputs": {"starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 3]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3], "length": 4, "starts_in": [0, 2, 3, 3], "stops_in": [2, 3, 3, 5]}, "outputs": {"starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 5]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3], "length": 4, "starts_in": [0, 2, 3, 3], "stops_in": [2, 3, 3, 6]}, "outputs": {"starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 6]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3], "length": 4, "starts_in": [0, 2, 3, 4], "stops_in": [2, 3, 4, 7]}, "outputs": {"starts_out": [0, 2, 3, 4], "stops_out": [2, 3, 4, 7]}}]}, {"name": "awkward_ListOffsetArray_reduce_nonlocal_maxcount_offsetscopy_64", "tests": [{"error": false, "inputs": {"length": 3, "offsets": [0, 2, 3, 5]}, "outputs": {"maxcount": [2], "offsetscopy": [0, 2, 3, 5]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 2, 4, 6]}, "outputs": {"maxcount": [2], "offsetscopy": [0, 2, 4, 6]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 3, 3, 5]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 3, 5]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 3, 5, 6, 8, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 3, 5, 6, 8, 9]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 3, 3, 5, 6, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 3, 5, 6, 9]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 5, 5, 6, 8, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 5, 5, 6, 8, 9]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 5, 6, 7, 7, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 5, 6, 7, 7, 9]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 3, 5, 6, 7, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 5, 6, 7, 9]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 5, 7, 8, 9, 10]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 5, 7, 8, 9, 10]}}, {"error": false, "inputs": {"length": 2, "offsets": [0, 3, 6]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 6]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 3, 6, 9, 12, 15]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"length": 9, "offsets": [0, 0, 1, 3, 6, 10, 13, 15, 16, 16]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 0, 1, 3, 6, 10, 13, 15, 16, 16]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 3, 3, 7]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 3, 3, 7]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 3, 6, 10]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 3, 6, 10]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 4, 4, 6]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 4, 4, 6]}}, {"error": false, "inputs": {"length": 2, "offsets": [0, 4, 6]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 4, 6]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 4, 8, 12]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 4, 8, 12]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 8, 13, 18, 23, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 3, 8, 13, 18, 23, 28]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 4, 9, 13, 18, 23, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 4, 9, 13, 18, 23, 28]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 4, 9, 14, 19, 24, 29]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 4, 9, 14, 19, 24, 29]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 11, 12, 17, 22]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 11, 12, 17, 22]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 14, 18, 23, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 14, 18, 23, 28]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 5, 10, 15]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 19, 24, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 19, 24, 28]}}, {"error": false, "inputs": {"length": 4, "offsets": [0, 5, 10, 15, 20]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 20, 24, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 24, 28]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 5, 10, 15, 20, 25]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 25]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 20, 25, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 25, 28]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 20, 25, 29]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 25, 29]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 20, 25, 30]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 6, 11, 16, 17, 22]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 6, 11, 16, 17, 22]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 5, 8, 11, 14, 17]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 8, 11, 14, 17]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 5, 9, 12]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 9, 12]}}]}, {"name": "awkward_ByteMaskedArray_overlay_mask", "tests": [{"error": false, "inputs": {"length": 2, "mymask": [0, 0], "theirmask": [0, 0], "validwhen": false}, "outputs": {"tomask": [0, 0]}}]}, {"name": "awkward_IndexedArray_flatten_none2empty", "tests": [{"error": false, "inputs": {"offsets": [0, 1, 1, 6], "offsetslength": 4, "outindex": [0, 1, 2, 1], "outindexlength": 4}, "outputs": {"outoffsets": [0, 1, 1, 6, 6]}}, {"error": false, "inputs": {"offsets": [0, 3, 3, 5], "offsetslength": 4, "outindex": [0, 1, 1, 1, 2], "outindexlength": 5}, "outputs": {"outoffsets": [0, 3, 3, 3, 3, 5]}}, {"error": false, "inputs": {"offsets": [0, 3, 3, 4, 7], "offsetslength": 5, "outindex": [0, 1, 2, 1, 3], "outindexlength": 5}, "outputs": {"outoffsets": [0, 3, 3, 4, 4, 7]}}, {"error": false, "inputs": {"offsets": [0, 3, 3, 5, 6, 6, 10], "offsetslength": 7, "outindex": [0, 1, 2, 3, 4, 1, 5], "outindexlength": 7}, "outputs": {"outoffsets": [0, 3, 3, 5, 6, 6, 6, 10]}}, {"error": false, "inputs": {"offsets": [0, 4, 4, 6], "offsetslength": 4, "outindex": [0, 1, 1, 1, 2, 1], "outindexlength": 6}, "outputs": {"outoffsets": [0, 4, 4, 4, 4, 6, 6]}}, {"error": false, "inputs": {"offsets": [0, 4, 4, 6, 7, 7, 12], "offsetslength": 7, "outindex": [0, 1, 1, 1, 2, 3, 4, 5, 1], "outindexlength": 9}, "outputs": {"outoffsets": [0, 4, 4, 4, 4, 6, 7, 7, 12, 12]}}, {"error": false, "inputs": {"offsets": [0, 5, 5, 6, 9], "offsetslength": 5, "outindex": [0, 1, 1, 2, 1, 3], "outindexlength": 6}, "outputs": {"outoffsets": [0, 5, 5, 5, 6, 6, 9]}}]}, {"name": "awkward_IndexedArray_reduce_next_64", "tests": [{"error": false, "inputs": {"index": [0, 1], "length": 2, "parents": [0, 0]}, "outputs": {"nextcarry": [0, 1], "nextparents": [0, 0], "outindex": [0, 1]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 4, 5, 6], "length": 7, "parents": [0, 0, 2, 2, 3, 4, 4]}, "outputs": {"nextcarry": [0, 1, 2, 3, 4, 5, 6], "nextparents": [0, 0, 2, 2, 3, 4, 4], "outindex": [0, 1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"index": [1, 2], "length": 2, "parents": [0, 0]}, "outputs": {"nextcarry": [1, 2], "nextparents": [0, 0], "outindex": [0, 1]}}, {"error": false, "inputs": {"index": [1, 2, 3], "length": 3, "parents": [0, 0, 0]}, "outputs": {"nextcarry": [1, 2, 3], "nextparents": [0, 0, 0], "outindex": [0, 1, 2]}}, {"error": false, "inputs": {"index": [1, 2, 3, 4], "length": 4, "parents": [0, 0, 0, 0]}, "outputs": {"nextcarry": [1, 2, 3, 4], "nextparents": [0, 0, 0, 0], "outindex": [0, 1, 2, 3]}}, {"error": false, "inputs": {"index": [2, 3], "length": 2, "parents": [0, 0]}, "outputs": {"nextcarry": [2, 3], "nextparents": [0, 0], "outindex": [0, 1]}}, {"error": false, "inputs": {"index": [2, 3, 4], "length": 3, "parents": [0, 0, 0]}, "outputs": {"nextcarry": [2, 3, 4], "nextparents": [0, 0, 0], "outindex": [0, 1, 2]}}, {"error": false, "inputs": {"index": [3, 4], "length": 2, "parents": [0, 0]}, "outputs": {"nextcarry": [3, 4], "nextparents": [0, 0], "outindex": [0, 1]}}, {"error": false, "inputs": {"index": [4, 3, 2, 1, 0], "length": 5, "parents": [0, 0, 0, 0, 0]}, "outputs": {"nextcarry": [4, 3, 2, 1, 0], "nextparents": [0, 0, 0, 0, 0], "outindex": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"index": [5, 2, 4, 1, 3, 0], "length": 6, "parents": [0, 0, 1, 1, 2, 2]}, "outputs": {"nextcarry": [5, 2, 4, 1, 3, 0], "nextparents": [0, 0, 1, 1, 2, 2], "outindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"index": [5, 4, 3, 2, 1, 0], "length": 6, "parents": [0, 0, 0, 1, 1, 1]}, "outputs": {"nextcarry": [5, 4, 3, 2, 1, 0], "nextparents": [0, 0, 0, 1, 1, 1], "outindex": [0, 1, 2, 3, 4, 5]}}]}, {"name": "awkward_IndexedArray_simplify", "tests": [{"error": false, "inputs": {"innerindex": [0, 1], "innerlength": 2, "outerindex": [0, 1], "outerlength": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2], "innerlength": 5, "outerindex": [0, 1, 2], "outerlength": 3}, "outputs": {"toindex": [0, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 4], "innerlength": 5, "outerindex": [0, 1, 2], "outerlength": 3}, "outputs": {"toindex": [0, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2], "innerlength": 3, "outerindex": [0, 1, 1, 1, 1, 2], "outerlength": 6}, "outputs": {"toindex": [0, 1, 1, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 1, 1], "innerlength": 5, "outerindex": [0, 1, 1, 1, 2], "outerlength": 5}, "outputs": {"toindex": [0, 1, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2], "innerlength": 5, "outerindex": [0, 1, 2, 3, 4, 1, 1], "outerlength": 7}, "outputs": {"toindex": [0, 1, 1, 1, 2, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 4], "innerlength": 5, "outerindex": [0, 1, 2, 3, 4, 1, 1], "outerlength": 7}, "outputs": {"toindex": [0, 1, 1, 1, 4, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 1], "innerlength": 4, "outerindex": [0, 1, 1, 2], "outerlength": 4}, "outputs": {"toindex": [0, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 2], "innerlength": 4, "outerindex": [0, 1, 1, 3], "outerlength": 4}, "outputs": {"toindex": [0, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 2], "innerlength": 4, "outerindex": [0, 1, 2, 3], "outerlength": 4}, "outputs": {"toindex": [0, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 3], "innerlength": 4, "outerindex": [0, 1, 1, 2, 3], "outerlength": 5}, "outputs": {"toindex": [0, 1, 1, 2, 3]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 3], "innerlength": 4, "outerindex": [0, 1, 1, 3], "outerlength": 4}, "outputs": {"toindex": [0, 1, 1, 3]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2], "innerlength": 3, "outerindex": [0, 1, 2], "outerlength": 3}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 3], "innerlength": 4, "outerindex": [0, 1, 2, 1, 3], "outerlength": 5}, "outputs": {"toindex": [0, 1, 2, 1, 3]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 1, 4], "innerlength": 5, "outerindex": [0, 1, 2, 3, 4], "outerlength": 5}, "outputs": {"toindex": [0, 1, 2, 1, 4]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 3, 4, 5, 6, 7, 1, 1], "innerlength": 10, "outerindex": [0, 1, 2, 3, 4, 1, 1, 1, 5, 6, 1, 1, 7, 8, 9, 1], "outerlength": 16}, "outputs": {"toindex": [0, 1, 2, 3, 4, 1, 1, 1, 5, 6, 1, 1, 7, 1, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 2, 1, 1, 3, 4], "innerlength": 8, "outerindex": [2, 2, 1, 6, 5], "outerlength": 5}, "outputs": {"toindex": [1, 1, 1, 3, 1]}}, {"error": false, "inputs": {"innerindex": [13, 9, 13, 4, 8, 3, 15, 1, 16, 2, 8], "innerlength": 11, "outerindex": [0, 3, 6], "outerlength": 3}, "outputs": {"toindex": [13, 4, 15]}}, {"error": false, "inputs": {"innerindex": [13, 9, 13, 4, 8, 3, 15, 1, 16, 2, 8], "innerlength": 11, "outerindex": [0, 1, 2, 3, 4, 5, 6, 7, 8], "outerlength": 9}, "outputs": {"toindex": [13, 9, 13, 4, 8, 3, 15, 1, 16]}}, {"error": false, "inputs": {"innerindex": [13, 9, 13, 4, 8, 3, 15, 1, 16, 2, 8], "innerlength": 11, "outerindex": [0, 1, 3, 4, 6, 7], "outerlength": 6}, "outputs": {"toindex": [13, 9, 4, 8, 15, 1]}}, {"error": false, "inputs": {"innerindex": [2, 1, 1, 0], "innerlength": 4, "outerindex": [0, 1, 2, 1, 3], "outerlength": 5}, "outputs": {"toindex": [2, 1, 1, 1, 0]}}, {"error": false, "inputs": {"innerindex": [3, 1, 1, 7], "innerlength": 4, "outerindex": [0, 1, 1, 2, 3], "outerlength": 5}, "outputs": {"toindex": [3, 1, 1, 1, 7]}}, {"error": false, "inputs": {"innerindex": [3, 1, 2, 1], "innerlength": 4, "outerindex": [0, 1, 2, 1, 3], "outerlength": 5}, "outputs": {"toindex": [3, 1, 2, 1, 1]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0], "outerlength": 1}, "outputs": {"toindex": [4]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0, 1], "outerlength": 2}, "outputs": {"toindex": [4, 3]}}, {"error": false, "inputs": {"innerindex": [4, 5, 6, 7, 3, 1, 2, 0, 1, 1], "innerlength": 10, "outerindex": [0, 4, 5, 7], "outerlength": 4}, "outputs": {"toindex": [4, 3, 1, 0]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0, 1, 2], "outerlength": 3}, "outputs": {"toindex": [4, 3, 2]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0, 1, 2, 3, 4], "outerlength": 5}, "outputs": {"toindex": [4, 3, 2, 1, 0]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0, 1, 2, 3], "outerlength": 4}, "outputs": {"toindex": [4, 3, 2, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2, 3, 4, 5, 6, 7], "innerlength": 10, "outerindex": [6, 7, 8, 9, 5, 1, 1, 1, 3, 4, 1, 1, 0, 1, 2, 1], "outerlength": 16}, "outputs": {"toindex": [4, 5, 6, 7, 3, 1, 1, 1, 1, 2, 1, 1, 0, 1, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2, 3, 4, 5, 6, 7], "innerlength": 10, "outerindex": [6, 7, 8, 9, 5, 1, 1, 3, 4, 1, 0, 1, 2], "outerlength": 13}, "outputs": {"toindex": [4, 5, 6, 7, 3, 1, 1, 1, 2, 1, 0, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2, 3, 4, 5, 6, 7], "innerlength": 10, "outerindex": [6, 7, 8, 9, 5, 3, 4, 0, 1, 2], "outerlength": 10}, "outputs": {"toindex": [4, 5, 6, 7, 3, 1, 2, 0, 1, 1]}}, {"error": false, "inputs": {"innerindex": [6, 5, 1, 3, 1, 1, 0], "innerlength": 7, "outerindex": [0, 2, 4, 6], "outerlength": 4}, "outputs": {"toindex": [6, 1, 1, 0]}}, {"error": false, "inputs": {"innerindex": [6, 5, 4, 3, 2, 1, 0], "innerlength": 7, "outerindex": [0, 2, 4, 6], "outerlength": 4}, "outputs": {"toindex": [6, 4, 2, 0]}}]}, {"name": "awkward_IndexedArray_validity", "tests": [{"error": false, "inputs": {"index": [0, 1, 1, 1, 1, 2], "isoption": true, "lencontent": 3, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 1], "isoption": true, "lencontent": 2, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2, 3, 4], "isoption": true, "lencontent": 5, "length": 7}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2, 3], "isoption": true, "lencontent": 4, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1], "isoption": true, "lencontent": 2, "length": 4}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 1, 3], "isoption": true, "lencontent": 4, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 1], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 1, 4, 5, 6], "isoption": true, "lencontent": 7, "length": 9}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 4, 1, 5], "isoption": true, "lencontent": 6, "length": 8}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 4, 5, 6, 7], "isoption": true, "lencontent": 8, "length": 9}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 4, 5], "isoption": true, "lencontent": 6, "length": 7}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3], "isoption": true, "lencontent": 4, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2], "isoption": true, "lencontent": 3, "length": 4}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1], "isoption": true, "lencontent": 2, "length": 3}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 1], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 3, 1, 4], "isoption": true, "lencontent": 5, "length": 7}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 3], "isoption": true, "lencontent": 4, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 1], "isoption": true, "lencontent": 3, "length": 4}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1, 4, 5, 6, 7, 8, 1, 9], "isoption": true, "lencontent": 10, "length": 12}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1, 4, 5, 6], "isoption": true, "lencontent": 7, "length": 8}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1, 4], "isoption": true, "lencontent": 5, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1], "isoption": true, "lencontent": 4, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 1], "isoption": true, "lencontent": 2, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 2], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 1, 3], "isoption": true, "lencontent": 4, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 1], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 3], "isoption": true, "lencontent": 4, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 2], "isoption": true, "lencontent": 3, "length": 4}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 1], "isoption": true, "lencontent": 2, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 2], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 1, 1, 0, 1], "isoption": true, "lencontent": 2, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 4, 4, 1, 0], "isoption": true, "lencontent": 10, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [2, 1, 4, 0, 8], "isoption": true, "lencontent": 10, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [2, 2, 0, 1, 4], "isoption": true, "lencontent": 5, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [2, 4, 4, 0, 8], "isoption": false, "lencontent": 10, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [6, 4, 4, 8, 0], "isoption": false, "lencontent": 10, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [6, 5, 4, 3, 2, 1, 0], "isoption": false, "lencontent": 7, "length": 7}, "outputs": {}}]}, {"name": "awkward_IndexedOptionArray_rpad_and_clip_mask_axis1", "tests": [{"error": false, "inputs": {"frommask": [0, 0, 0, 0], "length": 4}, "outputs": {"toindex": [0, 1, 2, 3]}}]}, {"name": "awkward_index_rpad_and_clip_axis1", "tests": [{"error": false, "inputs": {"length": 4, "target": 1}, "outputs": {"tostarts": [0, 1, 2, 3], "tostops": [1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 5, "target": 1}, "outputs": {"tostarts": [0, 1, 2, 3, 4], "tostops": [1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 6, "target": 1}, "outputs": {"tostarts": [0, 1, 2, 3, 4, 5], "tostops": [1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"length": 3, "target": 2}, "outputs": {"tostarts": [0, 2, 4], "tostops": [2, 4, 6]}}, {"error": false, "inputs": {"length": 7, "target": 2}, "outputs": {"tostarts": [0, 2, 4, 6, 8, 10, 12], "tostops": [2, 4, 6, 8, 10, 12, 14]}}, {"error": false, "inputs": {"length": 6, "target": 2}, "outputs": {"tostarts": [0, 2, 4, 6, 8, 10], "tostops": [2, 4, 6, 8, 10, 12]}}, {"error": false, "inputs": {"length": 5, "target": 2}, "outputs": {"tostarts": [0, 2, 4, 6, 8], "tostops": [2, 4, 6, 8, 10]}}, {"error": false, "inputs": {"length": 6, "target": 3}, "outputs": {"tostarts": [0, 3, 6, 9, 12, 15], "tostops": [3, 6, 9, 12, 15, 18]}}, {"error": false, "inputs": {"length": 5, "target": 3}, "outputs": {"tostarts": [0, 3, 6, 9, 12], "tostops": [3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"length": 6, "target": 4}, "outputs": {"tostarts": [0, 4, 8, 12, 16, 20], "tostops": [4, 8, 12, 16, 20, 24]}}, {"error": false, "inputs": {"length": 5, "target": 4}, "outputs": {"tostarts": [0, 4, 8, 12, 16], "tostops": [4, 8, 12, 16, 20]}}, {"error": false, "inputs": {"length": 6, "target": 5}, "outputs": {"tostarts": [0, 5, 10, 15, 20, 25], "tostops": [5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"length": 5, "target": 5}, "outputs": {"tostarts": [0, 5, 10, 15, 20], "tostops": [5, 10, 15, 20, 25]}}]}, {"name": "awkward_ListArray_combinations_length", "tests": [{"error": false, "inputs": {"length": 5, "n": 3, "replacement": false, "starts": [0, 4, 4, 7, 8], "stops": [4, 4, 7, 8, 13]}, "outputs": {"tooffsets": [0, 4, 4, 5, 5, 15], "totallen": [15]}}, {"error": false, "inputs": {"length": 5, "n": 2, "replacement": false, "starts": [0, 4, 4, 7, 8], "stops": [4, 4, 7, 8, 13]}, "outputs": {"tooffsets": [0, 6, 6, 9, 9, 19], "totallen": [19]}}, {"error": false, "inputs": {"length": 5, "n": 2, "replacement": true, "starts": [0, 4, 4, 7, 8], "stops": [4, 4, 7, 8, 13]}, "outputs": {"tooffsets": [0, 10, 10, 16, 17, 32], "totallen": [32]}}, {"error": false, "inputs": {"length": 3, "n": 2, "replacement": false, "starts": [0, 3, 3], "stops": [3, 3, 5]}, "outputs": {"tooffsets": [0, 3, 3, 4], "totallen": [4]}}, {"error": false, "inputs": {"length": 3, "n": 2, "replacement": false, "starts": [0, 3, 5], "stops": [3, 3, 7]}, "outputs": {"tooffsets": [0, 3, 3, 4], "totallen": [4]}}, {"error": false, "inputs": {"length": 5, "n": 3, "replacement": true, "starts": [0, 4, 4, 7, 8], "stops": [4, 4, 7, 8, 13]}, "outputs": {"tooffsets": [0, 20, 20, 30, 31, 66], "totallen": [66]}}, {"error": false, "inputs": {"length": 5, "n": 2, "replacement": false, "starts": [0, 3, 3, 10, 10], "stops": [3, 3, 5, 10, 13]}, "outputs": {"tooffsets": [0, 3, 3, 4, 4, 7], "totallen": [7]}}]}, {"name": "awkward_ListArray_getitem_jagged_carrylen", "tests": [{"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 0, 0, 0], "slicestops": [0, 0, 0, 0]}, "outputs": {"carrylen": [0]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 0, 0], "slicestops": [0, 0, 0]}, "outputs": {"carrylen": [0]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 0, 1, 1], "slicestops": [0, 1, 1, 1]}, "outputs": {"carrylen": [1]}}, {"error": false, "inputs": {"sliceouterlen": 6, "slicestarts": [0, 1, 3, 5, 6, 8], "slicestops": [1, 3, 5, 6, 8, 10]}, "outputs": {"carrylen": [10]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 5, 5, 6, 8], "slicestops": [5, 5, 6, 8, 10]}, "outputs": {"carrylen": [10]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 3, 4, 7], "slicestops": [3, 4, 7, 11]}, "outputs": {"carrylen": [11]}}, {"error": false, "inputs": {"sliceouterlen": 6, "slicestarts": [0, 1, 3, 6, 7, 9], "slicestops": [1, 3, 6, 7, 9, 12]}, "outputs": {"carrylen": [12]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 0, 0], "slicestops": [0, 0, 2]}, "outputs": {"carrylen": [2]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 2]}, "outputs": {"carrylen": [2]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 1, 1], "slicestops": [1, 1, 3]}, "outputs": {"carrylen": [3]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 1, 1, 2, 2], "slicestops": [1, 1, 2, 2, 3]}, "outputs": {"carrylen": [3]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"carrylen": [3]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 2, 3, 3], "slicestops": [2, 3, 3, 3]}, "outputs": {"carrylen": [3]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 2, 2, 2, 2], "slicestops": [2, 2, 2, 2, 4]}, "outputs": {"carrylen": [4]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 4]}, "outputs": {"carrylen": [4]}}, {"error": false, "inputs": {"sliceouterlen": 2, "slicestarts": [0, 3], "slicestops": [3, 4]}, "outputs": {"carrylen": [4]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 1, 1, 3, 3], "slicestops": [1, 1, 3, 3, 5]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 3], "slicestops": [2, 3, 5]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 2, 3, 3], "slicestops": [2, 3, 3, 5]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 3, 3], "slicestops": [3, 3, 5]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 4, 5], "slicestops": [4, 4, 6]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 1, 3, 4], "slicestops": [1, 3, 4, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 2, 2, 2, 2], "slicestops": [2, 2, 2, 2, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 2, "slicestarts": [0, 3], "slicestops": [3, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 4, 5], "slicestops": [4, 5, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 4, 6], "slicestops": [4, 6, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 5], "slicestops": [2, 5, 7]}, "outputs": {"carrylen": [7]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 3, 3, 3, 4], "slicestops": [3, 3, 3, 4, 7]}, "outputs": {"carrylen": [7]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 1, 4, 5], "slicestops": [1, 4, 5, 8]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 7, "slicestarts": [0, 2, 2, 4, 4, 5, 5], "slicestops": [2, 2, 4, 4, 5, 5, 8]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 2, 2, 4, 5], "slicestops": [2, 2, 4, 5, 8]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 3, 0, 3], "slicestops": [3, 4, 3, 4]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 3, 3, 4, 5], "slicestops": [3, 3, 4, 5, 8]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 2, 2, 4, 5], "slicestops": [2, 2, 4, 5, 9]}, "outputs": {"carrylen": [9]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 3, 3, 5, 6], "slicestops": [3, 3, 5, 6, 9]}, "outputs": {"carrylen": [9]}}]}, {"name": "awkward_ListArray_getitem_jagged_descend", "tests": [{"error": false, "inputs": {"fromstarts": [0, 2], "fromstops": [2, 4], "sliceouterlen": 2, "slicestarts": [0, 2], "slicestops": [2, 4]}, "outputs": {"tooffsets": [0, 2, 4]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 4], "fromstops": [3, 3, 4, 5], "sliceouterlen": 4, "slicestarts": [0, 3, 3, 4], "slicestops": [3, 3, 4, 5]}, "outputs": {"tooffsets": [0, 3, 3, 4, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceouterlen": 3, "slicestarts": [0, 3, 3], "slicestops": [3, 3, 5]}, "outputs": {"tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3], "fromstops": [3, 6], "sliceouterlen": 2, "slicestarts": [0, 3], "slicestops": [3, 6]}, "outputs": {"tooffsets": [0, 3, 6]}}]}, {"name": "awkward_ListArray_getitem_jagged_expand", "tests": [{"error": false, "inputs": {"fromstarts": [0, 2], "fromstops": [2, 4], "jaggedsize": 2, "length": 2, "singleoffsets": [0, 3, 4]}, "outputs": {"multistarts": [0, 3, 0, 3], "multistops": [3, 4, 3, 4], "tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromstarts": [2], "fromstops": [4], "jaggedsize": 2, "length": 1, "singleoffsets": [0, 3, 4]}, "outputs": {"multistarts": [0, 3], "multistops": [3, 4], "tocarry": [2, 3]}}]}, {"name": "awkward_ListArray_getitem_next_array", "tests": [{"error": false, "inputs": {"fromarray": [0, 0, 1, 1], "fromstarts": [0], "fromstops": [2], "lenarray": 4, "lencontent": 3, "lenstarts": 1}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 0, 1, 1]}}, {"error": false, "inputs": {"fromarray": [0, 3], "fromstarts": [0, 4, 8], "fromstops": [4, 8, 12], "lenarray": 2, "lencontent": 13, "lenstarts": 3}, "outputs": {"toadvanced": [0, 1, 0, 1, 0, 1], "tocarry": [0, 3, 4, 7, 8, 11]}}, {"error": false, "inputs": {"fromarray": [1, 1, 0, 0], "fromstarts": [0], "fromstops": [2], "lenarray": 4, "lencontent": 3, "lenstarts": 1}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 1, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 3], "fromstarts": [4, 8], "fromstops": [8, 12], "lenarray": 2, "lencontent": 13, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1, 0, 1], "tocarry": [4, 7, 8, 11]}}, {"error": false, "inputs": {"fromarray": [2, 1, 1, 0], "fromstarts": [6], "fromstops": [10], "lenarray": 4, "lencontent": 10, "lenstarts": 1}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [8, 7, 7, 6]}}]}, {"name": "awkward_ListArray_min_range", "tests": [{"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5}, "outputs": {"tomin": [0]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "lenstarts": 3}, "outputs": {"tomin": [0]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lenstarts": 5}, "outputs": {"tomin": [0]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lenstarts": 4}, "outputs": {"tomin": [1]}}]}, {"name": "awkward_ListArray_rpad_and_clip_length_axis1", "tests": [{"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5, "target": 1}, "outputs": {"tomin": [10]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lenstarts": 4, "target": 1}, "outputs": {"tomin": [10]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5, "target": 2}, "outputs": {"tomin": [12]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lenstarts": 4, "target": 3}, "outputs": {"tomin": [13]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lenstarts": 5, "target": 2}, "outputs": {"tomin": [13]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5, "target": 3}, "outputs": {"tomin": [15]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lenstarts": 4, "target": 4}, "outputs": {"tomin": [16]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lenstarts": 5, "target": 3}, "outputs": {"tomin": [16]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5, "target": 4}, "outputs": {"tomin": [20]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lenstarts": 5, "target": 4}, "outputs": {"tomin": [20]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "lenstarts": 3, "target": 3}, "outputs": {"tomin": [9]}}]}, {"name": "awkward_ListArray_validity", "tests": [{"error": false, "inputs": {"lencontent": 0, "length": 5, "starts": [0, 0, 0, 0, 0], "stops": [0, 0, 0, 0, 0]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 0, "length": 4, "starts": [0, 0, 0, 0], "stops": [0, 0, 0, 0]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 0, "length": 3, "starts": [0, 0, 0], "stops": [0, 0, 0]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 1, "length": 3, "starts": [0, 0, 1], "stops": [0, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 3, "starts": [0, 0, 1], "stops": [0, 1, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 1, "length": 4, "starts": [0, 0, 1, 1], "stops": [0, 1, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 4, "starts": [0, 0, 1, 3], "stops": [0, 1, 3, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 5, "starts": [0, 0, 1, 3, 6], "stops": [0, 1, 3, 6, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 19, "length": 8, "starts": [0, 0, 3, 3, 8, 12, 12, 16], "stops": [0, 3, 3, 8, 12, 12, 16, 19]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 19, "length": 9, "starts": [0, 0, 3, 3, 8, 12, 12, 16, 19], "stops": [0, 3, 3, 8, 12, 12, 16, 19, 19]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 3, "starts": [0, 1, 3], "stops": [1, 3, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 15, "length": 5, "starts": [0, 1, 3, 6, 10], "stops": [1, 3, 6, 10, 15]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 12, "length": 6, "starts": [0, 1, 3, 6, 7, 9], "stops": [1, 3, 6, 7, 9, 12]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 8, "length": 4, "starts": [0, 1, 4, 5], "stops": [1, 4, 5, 8]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 3, "length": 3, "starts": [0, 2, 2], "stops": [2, 2, 3]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 3, "starts": [0, 2, 2], "stops": [2, 2, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 3, "length": 2, "starts": [0, 2], "stops": [2, 3]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 2, "starts": [0, 2], "stops": [2, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 8, "length": 7, "starts": [0, 2, 2, 4, 4, 5, 5], "stops": [2, 2, 4, 4, 5, 5, 8]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 5, "starts": [0, 2, 2, 4, 5], "stops": [2, 2, 4, 5, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 5, "starts": [0, 2, 2, 4, 5], "stops": [2, 2, 4, 5, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 3, "length": 3, "starts": [0, 2, 3], "stops": [2, 3, 3]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 3, "starts": [0, 2, 3], "stops": [2, 3, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 5, "length": 3, "starts": [0, 2, 3], "stops": [2, 3, 5]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 3, "starts": [0, 2, 3], "stops": [2, 3, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 5, "length": 4, "starts": [0, 2, 3, 3], "stops": [2, 3, 3, 5]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 7, "length": 4, "starts": [0, 2, 3, 4], "stops": [2, 3, 4, 7]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 3, "starts": [0, 2, 4], "stops": [2, 4, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 7, "length": 3, "starts": [0, 2, 5], "stops": [2, 5, 7]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 8, "length": 3, "starts": [0, 2, 6], "stops": [2, 6, 8]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 5, "length": 3, "starts": [0, 3, 3], "stops": [3, 3, 5]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 7, "length": 3, "starts": [0, 3, 3], "stops": [3, 3, 7]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 8, "length": 3, "starts": [0, 3, 3], "stops": [3, 3, 8]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 2, "starts": [0, 3], "stops": [3, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 4, "starts": [0, 3, 3, 5], "stops": [3, 3, 5, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 11, "length": 6, "starts": [0, 3, 3, 5, 6, 10], "stops": [3, 3, 5, 6, 10, 11]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 5, "starts": [0, 3, 3, 5, 6], "stops": [3, 3, 5, 6, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 6, "starts": [0, 3, 3, 5, 6, 8], "stops": [3, 3, 5, 6, 8, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 2, "starts": [0, 3], "stops": [3, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 7, "length": 2, "starts": [0, 3], "stops": [3, 7]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 11, "length": 4, "starts": [0, 3, 4, 7], "stops": [3, 4, 7, 11]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 25, "length": 7, "starts": [0, 3, 6, 11, 14, 17, 20], "stops": [3, 6, 11, 14, 17, 20, 25]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 20, "length": 6, "starts": [0, 3, 6, 11, 14, 17], "stops": [3, 6, 11, 14, 17, 20]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 19, "length": 5, "starts": [0, 3, 6, 11, 15], "stops": [3, 6, 11, 15, 19]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 3, "starts": [0, 3, 6], "stops": [3, 6, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 11, "length": 3, "starts": [0, 3, 6], "stops": [3, 6, 11]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 21, "length": 9, "starts": [0, 3, 6, 6, 10, 14, 14, 18, 21], "stops": [3, 6, 6, 10, 14, 14, 18, 21, 21]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 21, "length": 8, "starts": [0, 3, 6, 6, 10, 14, 14, 18], "stops": [3, 6, 6, 10, 14, 14, 18, 21]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 22, "length": 9, "starts": [0, 3, 6, 6, 11, 15, 15, 19, 22], "stops": [3, 6, 6, 11, 15, 15, 19, 22, 22]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 22, "length": 8, "starts": [0, 3, 6, 6, 11, 15, 15, 19], "stops": [3, 6, 6, 11, 15, 15, 19, 22]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 24, "length": 9, "starts": [0, 3, 6, 8, 13, 17, 17, 21, 24], "stops": [3, 6, 8, 13, 17, 17, 21, 24, 24]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 24, "length": 8, "starts": [0, 3, 6, 8, 13, 17, 17, 21], "stops": [3, 6, 8, 13, 17, 17, 21, 24]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 3, "starts": [0, 3, 7], "stops": [3, 7, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 2, "starts": [0, 4], "stops": [4, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 3, "starts": [0, 4, 4], "stops": [4, 4, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 3, "starts": [0, 4, 6], "stops": [4, 6, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 14, "length": 4, "starts": [0, 4, 6, 9], "stops": [4, 6, 9, 14]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 11, "length": 6, "starts": [0, 4, 7, 7, 9, 9], "stops": [4, 7, 7, 9, 9, 11]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 12, "length": 3, "starts": [0, 4, 8], "stops": [4, 8, 12]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 30, "length": 6, "starts": [0, 5, 10, 15, 20, 25], "stops": [5, 10, 15, 20, 25, 30]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 2, "starts": [0, 5], "stops": [5, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 12, "length": 6, "starts": [3, 0, 999, 2, 6, 10], "stops": [7, 3, 999, 4, 6, 12]}, "outputs": {}}]}, {"name": "awkward_ListArray_getitem_jagged_apply", "tests": [{"error": false, "inputs": {"contentlen": 0, "fromstarts": [0, 0, 0, 0], "fromstops": [0, 0, 0, 0], "sliceindex": [], "sliceinnerlen": 0, "sliceouterlen": 4, "slicestarts": [0, 0, 0, 0], "slicestops": [0, 0, 0, 0]}, "outputs": {"tocarry": [], "tooffsets": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [], "sliceinnerlen": 0, "sliceouterlen": 3, "slicestarts": [0, 0, 0], "slicestops": [0, 0, 0]}, "outputs": {"tocarry": [], "tooffsets": [0, 0, 0, 0]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1], "sliceinnerlen": 2, "sliceouterlen": 3, "slicestarts": [0, 0, 0], "slicestops": [0, 0, 2]}, "outputs": {"tocarry": [3, 4], "tooffsets": [0, 0, 0, 2]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 0, 1], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 1, 1], "slicestops": [1, 1, 3]}, "outputs": {"tocarry": [0, 3, 4], "tooffsets": [0, 1, 1, 3]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [2, 0, 1], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 1, 1], "slicestops": [1, 1, 3]}, "outputs": {"tocarry": [2, 3, 4], "tooffsets": [0, 1, 1, 3]}}, {"error": false, "inputs": {"contentlen": 10, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 10], "sliceindex": [1, 0, 1, 0, 3], "sliceinnerlen": 5, "sliceouterlen": 5, "slicestarts": [0, 1, 1, 3, 3], "slicestops": [1, 1, 3, 3, 5]}, "outputs": {"tocarry": [1, 3, 4, 6, 9], "tooffsets": [0, 1, 1, 3, 3, 5]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1], "sliceinnerlen": 2, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 2]}, "outputs": {"tocarry": [0, 1], "tooffsets": [0, 2, 2, 2]}}, {"error": false, "inputs": {"contentlen": 4, "fromstarts": [0, 1, 1, 1, 1], "fromstops": [1, 1, 1, 1, 4], "sliceindex": [0, 0, 2, 1, 1, 2], "sliceinnerlen": 6, "sliceouterlen": 5, "slicestarts": [0, 2, 2, 2, 2], "slicestops": [2, 2, 2, 2, 6]}, "outputs": {"tocarry": [0, 0, 3, 2, 2, 3], "tooffsets": [0, 2, 2, 2, 2, 6]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1, 0], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"tocarry": [0, 1, 3], "tooffsets": [0, 2, 2, 3]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1, 1], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"tocarry": [0, 1, 4], "tooffsets": [0, 2, 2, 3]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [2, 0, 1], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"tocarry": [2, 0, 4], "tooffsets": [0, 2, 2, 3]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 2, 0, 1], "sliceinnerlen": 4, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 4]}, "outputs": {"tocarry": [0, 2, 3, 4], "tooffsets": [0, 2, 2, 4]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [0, 2, 0, 1, 0, 0, 1, 2], "sliceinnerlen": 8, "sliceouterlen": 5, "slicestarts": [0, 2, 2, 4, 5], "slicestops": [2, 2, 4, 5, 8]}, "outputs": {"tocarry": [0, 2, 3, 4, 5, 6, 7, 8], "tooffsets": [0, 2, 2, 4, 5, 8]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [1, 2, 0, 1, 0, 0, 1, 2], "sliceinnerlen": 8, "sliceouterlen": 5, "slicestarts": [0, 2, 2, 4, 5], "slicestops": [2, 2, 4, 5, 8]}, "outputs": {"tocarry": [1, 2, 3, 4, 5, 6, 7, 8], "tooffsets": [0, 2, 2, 4, 5, 8]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [0, 1, 2, 0, 0, 1, 2], "sliceinnerlen": 7, "sliceouterlen": 5, "slicestarts": [0, 3, 3, 3, 4], "slicestops": [3, 3, 3, 4, 7]}, "outputs": {"tocarry": [0, 1, 2, 5, 6, 7, 8], "tooffsets": [0, 3, 3, 3, 4, 7]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [0, 1, 2, 1, 0, 0, 1, 2], "sliceinnerlen": 8, "sliceouterlen": 5, "slicestarts": [0, 3, 3, 4, 5], "slicestops": [3, 3, 4, 5, 8]}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 7, 8], "tooffsets": [0, 3, 3, 4, 5, 8]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1, 2, 0, 1], "sliceinnerlen": 5, "sliceouterlen": 3, "slicestarts": [0, 3, 3], "slicestops": [3, 3, 5]}, "outputs": {"tocarry": [0, 1, 2, 3, 4], "tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [2, 1, 0, 0, 1], "sliceinnerlen": 5, "sliceouterlen": 3, "slicestarts": [0, 3, 3], "slicestops": [3, 3, 5]}, "outputs": {"tocarry": [2, 1, 0, 3, 4], "tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [0, 1, 2, 0, 1, 0, 0, 1, 2], "sliceinnerlen": 9, "sliceouterlen": 5, "slicestarts": [0, 3, 3, 5, 6], "slicestops": [3, 3, 5, 6, 9]}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8], "tooffsets": [0, 3, 3, 5, 6, 9]}}, {"error": false, "inputs": {"contentlen": 6, "fromstarts": [0, 3], "fromstops": [3, 6], "sliceindex": [2, 1, 0, 2, 1, 0], "sliceinnerlen": 6, "sliceouterlen": 2, "slicestarts": [0, 3], "slicestops": [3, 6]}, "outputs": {"tocarry": [2, 1, 0, 5, 4, 3], "tooffsets": [0, 3, 6]}}, {"error": false, "inputs": {"contentlen": 6, "fromstarts": [0, 3, 5], "fromstops": [3, 5, 6], "sliceindex": [2, 1, 1, 0, 1, 0], "sliceinnerlen": 6, "sliceouterlen": 3, "slicestarts": [0, 4, 5], "slicestops": [4, 4, 6]}, "outputs": {"tocarry": [2, 1, 1, 0, 5], "tooffsets": [0, 4, 4, 5]}}, {"error": false, "inputs": {"contentlen": 6, "fromstarts": [0, 3, 5], "fromstops": [3, 5, 6], "sliceindex": [2, 1, 1, 0, 1, 0], "sliceinnerlen": 6, "sliceouterlen": 3, "slicestarts": [0, 4, 5], "slicestops": [4, 5, 6]}, "outputs": {"tocarry": [2, 1, 1, 0, 4, 5], "tooffsets": [0, 4, 5, 6]}}, {"error": false, "inputs": {"contentlen": 8, "fromstarts": [0, 4, 7], "fromstops": [4, 7, 8], "sliceindex": [3, 2, 2, 1, 1, 2], "sliceinnerlen": 6, "sliceouterlen": 3, "slicestarts": [0, 4, 6], "slicestops": [4, 6, 6]}, "outputs": {"tocarry": [3, 2, 2, 1, 5, 6], "tooffsets": [0, 4, 6, 6]}}, {"error": false, "inputs": {"contentlen": 13, "fromstarts": [0, 4, 4, 7, 8], "fromstops": [4, 4, 7, 8, 13], "sliceindex": [3, 2, 1, 1, 0, 1, 0, 0, 1, 2], "sliceinnerlen": 10, "sliceouterlen": 5, "slicestarts": [0, 5, 5, 6, 8], "slicestops": [5, 5, 6, 8, 10]}, "outputs": {"tocarry": [3, 2, 1, 1, 0, 5, 7, 7, 9, 10], "tooffsets": [0, 5, 5, 6, 8, 10]}}]}, {"name": "awkward_UnionArray_regular_index", "tests": [{"error": false, "inputs": {"fromtags": [0, 1, 0, 1, 0, 1], "length": 6, "size": 2}, "outputs": {"current": [3, 3], "toindex": [0, 0, 1, 1, 2, 2]}}, {"error": false, "inputs": {"fromtags": [1, 0, 1, 1], "length": 4, "size": 2}, "outputs": {"current": [1, 3], "toindex": [0, 0, 1, 2]}}, {"error": false, "inputs": {"fromtags": [1, 1, 0, 0, 1, 0, 1, 1], "length": 8, "size": 2}, "outputs": {"current": [3, 5], "toindex": [0, 1, 0, 1, 2, 2, 3, 4]}}]}, {"name": "awkward_UnionArray_regular_index_getsize", "tests": [{"error": false, "inputs": {"fromtags": [0, 1, 0, 1, 0, 1], "length": 6}, "outputs": {"size": [2]}}, {"error": false, "inputs": {"fromtags": [1, 0, 1, 1], "length": 4}, "outputs": {"size": [2]}}, {"error": false, "inputs": {"fromtags": [1, 1, 0, 0, 1, 0, 1, 1], "length": 8}, "outputs": {"size": [2]}}]}, {"name": "awkward_IndexedArray_fill", "tests": [{"error": false, "inputs": {"base": 0, "fromindex": [0, 1, -1, -1, 4], "length": 5, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, -1, -1, 4]}}, {"error": false, "inputs": {"base": 0, "fromindex": [0, 1, 2, 3, -1], "length": 5, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2, 3, -1]}}, {"error": false, "inputs": {"base": 0, "fromindex": [0, 1, 2], "length": 3, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"base": 0, "fromindex": [-1, -1, 0, -1, 1, 2], "length": 6, "toindexoffset": 0}, "outputs": {"toindex": [-1, -1, 0, -1, 1, 2]}}, {"error": false, "inputs": {"base": 0, "fromindex": [2, 0, -1, 0, 1, 2], "length": 6, "toindexoffset": 0}, "outputs": {"toindex": [2, 0, -1, 0, 1, 2]}}]}, {"name": "awkward_ListArray_fill", "tests": [{"error": false, "inputs": {"base": 0, "fromstarts": [0, 0, 1], "fromstops": [0, 1, 3], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 0, 1], "tostops": [0, 1, 3]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 2, 2], "fromstops": [2, 2, 4], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 2, 2], "tostops": [2, 2, 4]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 2, 4], "fromstops": [2, 4, 6], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 2, 4], "tostops": [2, 4, 6]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 10], "length": 5, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 3, 3, 5, 6], "tostops": [3, 3, 5, 6, 10]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 3, 3], "tostops": [3, 3, 5]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 3, 6], "fromstops": [3, 6, 11], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 3, 6], "tostops": [3, 6, 11]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 5, 10], "fromstops": [5, 10, 15], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 5, 10], "tostops": [5, 10, 15]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 7], "fromstops": [7, 14], "length": 2, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 7], "tostops": [7, 14]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [1, 3, 3, 3], "fromstops": [3, 3, 3, 5], "length": 4, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [1, 3, 3, 3], "tostops": [3, 3, 3, 5]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [3, 5], "fromstops": [5, 5], "length": 2, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [3, 5], "tostops": [5, 5]}}]}, {"name": "awkward_UnionArray_fillindex", "tests": [{"error": false, "inputs": {"fromindex": [0, 0, 1, 1], "length": 4, "toindexoffset": 0}, "outputs": {"toindex": [0, 0, 1, 1]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 0, 1, 2], "length": 6, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2, 0, 1, 2]}}]}, {"name": "awkward_UnionArray_validity", "tests": [{"error": false, "inputs": {"index": [0, 1, 2, 3, 0, 1], "lencontents": [4, 2, 0, 945], "length": 6, "numcontents": 2, "tags": [0, 0, 0, 0, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 0, 1, 2, 3], "lencontents": [3, 4], "length": 7, "numcontents": 2, "tags": [0, 0, 0, 1, 1, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 0, 1, 2, 3], "lencontents": [2, 4, 32, 49, 0, 0], "length": 6, "numcontents": 2, "tags": [0, 0, 1, 1, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 0, 1, 1, 2, 3, 2, 4], "lencontents": [5, 3, 32, 33], "length": 8, "numcontents": 2, "tags": [0, 1, 1, 0, 0, 0, 1, 0]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 0, 1, 1, 2, 3, 2, 4], "lencontents": [5, 3, 32, 625, 0, 0, 0], "length": 8, "numcontents": 2, "tags": [0, 1, 1, 0, 0, 0, 1, 0]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 0, 1, 1, 2, 2, 3], "lencontents": [3, 4, 32, 177], "length": 7, "numcontents": 2, "tags": [0, 1, 1, 0, 0, 1, 1]}, "outputs": {}}]}, {"name": "awkward_ByteMaskedArray_reduce_next_nonlocal_nextshifts_64", "tests": [{"error": false, "inputs": {"length": 7, "mask": [0, 0, 0, 1, 1, 0, 0], "valid_when": false}, "outputs": {"nextshifts": [0, 0, 0, 2, 2]}}]}, {"name": "awkward_IndexedArray_index_of_nulls", "tests": [{"error": false, "inputs": {"fromindex": [-1, -1, 0, 1, 2, -1, -1, -1, 3, -1, 4, 5, -1, -1, 6, 7, 8], "lenindex": 17, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4], "starts": [0, 5, 8, 11, 14]}, "outputs": {"toindex": [0, 1, 0, 1, 2, 1, 1, 2]}}, {"error": false, "inputs": {"fromindex": [-1, -1, 3, 5, 6, -1, -1, -1, -1, 7, 0, -1, 4, -1, 8, 1, 2], "lenindex": 17, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4], "starts": [0, 5, 10, 15, 16]}, "outputs": {"toindex": [0, 1, 0, 1, 2, 3, 1, 3]}}, {"error": false, "inputs": {"fromindex": [-1, -1, 0, 1, 2], "lenindex": 5, "parents": [0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"fromindex": [0, -1, 3, 5, 6, 1, -1, 4, -1, 7, 2, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "lenindex": 25, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4], "starts": [0, 5, 10, 15, 20]}, "outputs": {"toindex": [1, 1, 3, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromindex": [0, -1, 1, 2, -1, 3, 4, 5], "lenindex": 8, "parents": [0, 0, 0, 0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [1, 4]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2], "lenindex": 4, "parents": [0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [2]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, -1, 4], "lenindex": 5, "parents": [0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [2, 3]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2, 3, -1], "lenindex": 6, "parents": [0, 0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [2, 5]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2, 3, -1, 4, 5, -1, 6, 7, -1], "lenindex": 12, "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"toindex": [2, 5, 2, 5]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, -1, -1, -1, -1, 7, 8], "lenindex": 9, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 1], "starts": [0, 4]}, "outputs": {"toindex": [3, 0, 1, 2]}}]}, {"name": "awkward_IndexedArray_reduce_next_fix_offsets_64", "tests": [{"error": false, "inputs": {"outindexlength": 6, "starts": [0, 1, 2, 5], "startslength": 4}, "outputs": {"outoffsets": [0, 1, 2, 5, 6]}}, {"error": false, "inputs": {"outindexlength": 2, "starts": [0], "startslength": 1}, "outputs": {"outoffsets": [0, 2]}}, {"error": false, "inputs": {"outindexlength": 9, "starts": [0, 3, 3, 5, 6], "startslength": 5}, "outputs": {"outoffsets": [0, 3, 3, 5, 6, 9]}}, {"error": false, "inputs": {"outindexlength": 6, "starts": [0, 3], "startslength": 2}, "outputs": {"outoffsets": [0, 3, 6]}}, {"error": false, "inputs": {"outindexlength": 4, "starts": [0], "startslength": 1}, "outputs": {"outoffsets": [0, 4]}}, {"error": false, "inputs": {"outindexlength": 5, "starts": [0], "startslength": 1}, "outputs": {"outoffsets": [0, 5]}}, {"error": false, "inputs": {"outindexlength": 8, "starts": [0], "startslength": 1}, "outputs": {"outoffsets": [0, 8]}}]}, {"name": "awkward_IndexedArray_reduce_next_nonlocal_nextshifts_64", "tests": [{"error": false, "inputs": {"index": [0, 1, 2, -1, 3, -1, 4], "length": 7}, "outputs": {"nextshifts": [0, 0, 0, 1, 2]}}, {"error": false, "inputs": {"index": [0, 1, 2, -1, -1, -1, -1, 7, 8], "length": 9}, "outputs": {"nextshifts": [0, 0, 0, 4, 4]}}, {"error": false, "inputs": {"index": [0, 1, -1, 2, 3, -1], "length": 6}, "outputs": {"nextshifts": [0, 0, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, -1, 2, 3, 4], "length": 6}, "outputs": {"nextshifts": [0, 0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, -1, 2, 3, -1, 4], "length": 7}, "outputs": {"nextshifts": [0, 0, 1, 1, 2]}}, {"error": false, "inputs": {"index": [0, 1, -1, 2, 3, -1, 4, 5, -1, 6, 7, -1], "length": 12}, "outputs": {"nextshifts": [0, 0, 1, 1, 2, 2, 3, 3]}}, {"error": false, "inputs": {"index": [0, 1, -1, -1, 4], "length": 5}, "outputs": {"nextshifts": [0, 0, 2]}}, {"error": false, "inputs": {"index": [4, 2, -1, -1, 1, 0, 1], "length": 7}, "outputs": {"nextshifts": [0, 0, 2, 2, 2]}}, {"error": false, "inputs": {"index": [-1, -1, 0, 1, 2], "length": 5}, "outputs": {"nextshifts": [2, 2, 2]}}, {"error": false, "inputs": {"index": [-1, -1, 0, 1, 2, -1, -1, -1, 3, -1, 4, 5, -1, -1, 6, 7, 8], "length": 17}, "outputs": {"nextshifts": [2, 2, 2, 5, 6, 6, 8, 8, 8]}}]}, {"name": "awkward_IndexedArray_reduce_next_nonlocal_nextshifts_fromshifts_64", "tests": [{"error": false, "inputs": {"index": [0, 3, 4, 1, -1, 5, 2], "length": 7, "shifts": [0, 0, 1, 0, 0, 1, 0]}, "outputs": {"nextshifts": [0, 0, 1, 0, 2, 1]}}, {"error": false, "inputs": {"index": [0, 3, 4, 1, -1, 5, 2], "length": 7, "shifts": [0, 1, 1, 0, 1, 1, 0]}, "outputs": {"nextshifts": [0, 1, 1, 0, 2, 1]}}, {"error": false, "inputs": {"index": [0, -1, 3, 5, 6, 1, -1, 4, -1, 7, 2, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "length": 25, "shifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"nextshifts": [0, 1, 1, 1, 1, 2, 3, 3, 6]}}, {"error": false, "inputs": {"index": [0, -1, 4, 1, 3, 5, 2], "length": 7, "shifts": [0, 1, 1, 0, 1, 1, 0]}, "outputs": {"nextshifts": [0, 2, 1, 2, 2, 1]}}, {"error": false, "inputs": {"index": [-1, -1, 3, 5, 6, -1, -1, -1, -1, 7, 0, -1, 4, -1, 8, 1, 2], "length": 17, "shifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"nextshifts": [2, 2, 2, 6, 6, 7, 8, 8, 8]}}]}, {"name": "awkward_ListArray_getitem_next_array_advanced", "tests": [{"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [0, 0], "fromstarts": [0, 0], "fromstops": [1, 1], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 0]}}, {"error": false, "inputs": {"fromadvanced": [0], "fromarray": [0], "fromstarts": [0], "fromstops": [2], "lenarray": 1, "lencontent": 4, "lenstarts": 1}, "outputs": {"toadvanced": [0], "tocarry": [0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [0, 0, 0, 0], "fromstops": [3, 3, 3, 3], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 2, 1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "fromstarts": [0, 3, 3, 3], "fromstops": [3, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 3, 3, 3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [1, 0], "fromstarts": [0, 0], "fromstops": [3, 3], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [0, 0, 0, 0], "fromstops": [3, 3, 3, 3], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [0, 0], "fromstarts": [1, 0], "fromstops": [3, 2], "lenarray": 2, "lencontent": 3, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [10, 11, 14, 11]}}, {"error": false, "inputs": {"fromadvanced": [0], "fromarray": [0], "fromstarts": [1], "fromstops": [3], "lenarray": 1, "lencontent": 3, "lenstarts": 1}, "outputs": {"toadvanced": [0], "tocarry": [1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [11, 10, 10, 11]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, -2, 0, -1], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [11, 13, 10, 14]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, -2, 0, -1], "fromstarts": [10, 0, 0, 5], "fromstops": [15, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [11, 3, 0, 9]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [0, 15, 15, 15], "fromstops": [5, 20, 20, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 15, 15, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [1, 2], "fromstarts": [0, 0], "fromstops": [3, 3], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 2]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 0, 0, 1], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [12, 10, 10, 11]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 2, 2, 2], "fromstarts": [10, 0, 0, 5], "fromstops": [15, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [12, 2, 2, 7]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-2, -2, -2, -2], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [13, 13, 13, 13]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-2, -2, -2, -2], "fromstarts": [10, 0, 0, 5], "fromstops": [15, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [13, 3, 3, 8]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [0, 3, 3, 3], "fromstops": [3, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 3, 3, 4]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [0, 5, 10, 5], "fromstops": [5, 10, 15, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 5, 10, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [15, 0, 0, 15], "fromstops": [20, 5, 5, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [15, 1, 4, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [15, 15, 15, 15], "fromstops": [20, 20, 20, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [15, 16, 19, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [15, 15, 15, 15], "fromstops": [20, 20, 20, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [16, 15, 15, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [15, 0, 0, 15], "fromstops": [20, 5, 5, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [19, 4, 4, 19]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [-1, 0], "fromstarts": [0, 0], "fromstops": [3, 3], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [0, 0, 0, 0], "fromstops": [3, 3, 3, 3], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [1, 2], "fromstarts": [1, 1], "fromstops": [4, 4], "lenarray": 2, "lencontent": 4, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [0, 3, 3, 3], "fromstops": [3, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 5, 5, 5]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "fromstarts": [3, 0, 0, 3], "fromstops": [6, 3, 3, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 0, 0, 3]}}, {"error": false, "inputs": {"fromadvanced": [0], "fromarray": [1], "fromstarts": [2], "fromstops": [5], "lenarray": 1, "lencontent": 5, "lenstarts": 1}, "outputs": {"toadvanced": [0], "tocarry": [3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [-1, 0], "fromstarts": [1, 1], "fromstops": [4, 4], "lenarray": 2, "lencontent": 4, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [3, 1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [3, 0, 0, 3], "fromstops": [6, 3, 3, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 1, 2, 4]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "fromstarts": [3, 3, 3, 3], "fromstops": [6, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 3, 3, 3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [3, 3, 3, 3], "fromstops": [6, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 4, 5, 4]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [1, 1], "fromstarts": [3, 0], "fromstops": [5, 3], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [4, 1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 1, 0, 0], "fromstarts": [3, 0, 0, 6], "fromstops": [5, 3, 3, 9], "lenarray": 4, "lencontent": 9, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 1, 0, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [0, 15, 15, 15], "fromstops": [5, 20, 20, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 19, 19, 19]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, -1, 0, 0], "fromstarts": [3, 0, 0, 3], "fromstops": [5, 3, 3, 5], "lenarray": 4, "lencontent": 5, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 2, 0, 3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [3, 3, 3, 3], "fromstops": [6, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 3, 3, 4]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [0, 5, 10, 5], "fromstops": [5, 10, 15, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 9, 14, 9]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3, 4, 5], "fromarray": [2, 0, 1, 1, 2, 0], "fromstarts": [3, 0, 3, 3, 3, 0], "fromstops": [6, 3, 6, 6, 6, 3], "lenarray": 6, "lencontent": 6, "lenstarts": 6}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [5, 0, 4, 4, 5, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [5, 0, 0, 5], "fromstops": [10, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [5, 1, 4, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [3, 0, 0, 3], "fromstops": [6, 3, 3, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [5, 2, 2, 5]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 1, 0, 0], "fromstarts": [6, 0, 0, 6], "fromstops": [9, 3, 3, 9], "lenarray": 4, "lencontent": 9, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [7, 1, 0, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [5, 0, 0, 5], "fromstops": [10, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [9, 4, 4, 9]}}]}, {"name": "awkward_ListArray_getitem_next_at", "tests": [{"error": false, "inputs": {"at": 0, "fromstarts": [], "fromstops": [], "lenstarts": 0}, "outputs": {"tocarry": []}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0], "fromstops": [1], "lenstarts": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0], "fromstops": [2], "lenstarts": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": -5, "fromstarts": [0], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 1], "fromstops": [1, 2], "lenstarts": 2}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 1, 2, 3], "fromstops": [1, 2, 3, 4], "lenstarts": 4}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 1, 2, 3, 4], "fromstops": [1, 2, 3, 4, 5], "lenstarts": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 2, 3], "fromstops": [2, 3, 5], "lenstarts": 3}, "outputs": {"tocarry": [0, 2, 3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 3, 5, 6], "fromstops": [3, 5, 6, 10], "lenstarts": 4}, "outputs": {"tocarry": [0, 3, 5, 6]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [10], "fromstops": [15], "lenstarts": 1}, "outputs": {"tocarry": [10]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0], "fromstops": [2], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [0], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [10], "fromstops": [15], "lenstarts": 1}, "outputs": {"tocarry": [11]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [1], "fromstops": [2], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [1], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [10], "fromstops": [15], "lenstarts": 1}, "outputs": {"tocarry": [13]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0, 3], "fromstops": [3, 5], "lenstarts": 2}, "outputs": {"tocarry": [1, 4]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0, 5], "fromstops": [5, 10], "lenstarts": 2}, "outputs": {"tocarry": [1, 6]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [15], "fromstops": [20], "lenstarts": 1}, "outputs": {"tocarry": [16]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [15], "fromstops": [20], "lenstarts": 1}, "outputs": {"tocarry": [18]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [15], "fromstops": [20], "lenstarts": 1}, "outputs": {"tocarry": [19]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [0], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [1], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [1], "fromstops": [4], "lenstarts": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [2], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [2], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [3], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [3], "fromstops": [6], "lenstarts": 1}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [3, 5, 6], "fromstops": [5, 6, 9], "lenstarts": 3}, "outputs": {"tocarry": [3, 5, 6]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [0], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": 4, "fromstarts": [0], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [3], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [3], "fromstops": [6], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [3], "fromstops": [6], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [3, 5, 6], "fromstops": [5, 6, 9], "lenstarts": 3}, "outputs": {"tocarry": [4, 5, 8]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [0, 5], "fromstops": [5, 10], "lenstarts": 2}, "outputs": {"tocarry": [4, 9]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [5, 10], "fromstops": [10, 15], "lenstarts": 2}, "outputs": {"tocarry": [5, 10]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [3], "fromstops": [6], "lenstarts": 1}, "outputs": {"tocarry": [5]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [5]}}, {"error": false, "inputs": {"at": -5, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [5]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [5, 10], "fromstops": [10, 15], "lenstarts": 2}, "outputs": {"tocarry": [6, 11]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [6]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [6], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [7]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [6], "fromstops": [9], "lenstarts": 1}, "outputs": {"tocarry": [7]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [8]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [5, 10], "fromstops": [10, 15], "lenstarts": 2}, "outputs": {"tocarry": [9, 14]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [9]}}, {"error": false, "inputs": {"at": 4, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [9]}}]}, {"name": "awkward_ListArray_getitem_next_range_counts", "tests": [{"error": false, "inputs": {"fromoffsets": [0, 2, 2, 4, 4, 5, 6, 7, 9, 9], "lenstarts": 9}, "outputs": {"total": [9]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 5, 6, 7, 9], "lenstarts": 6}, "outputs": {"total": [9]}}]}, {"name": "awkward_ListArray_localindex", "tests": [{"error": false, "inputs": {"length": 1, "offsets": [0, 1]}, "outputs": {"toindex": [0]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 2, 3, 5]}, "outputs": {"toindex": [0, 1, 0, 0, 1]}}, {"error": false, "inputs": {"length": 4, "offsets": [0, 2, 3, 3, 6]}, "outputs": {"toindex": [0, 1, 0, 0, 1, 2]}}, {"error": false, "inputs": {"length": 2, "offsets": [0, 2, 3]}, "outputs": {"toindex": [0, 1, 0]}}, {"error": false, "inputs": {"length": 1, "offsets": [0, 2]}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 4, "offsets": [0, 3, 3, 4, 5]}, "outputs": {"toindex": [0, 1, 2, 0, 0]}}, {"error": false, "inputs": {"length": 7, "offsets": [0, 3, 3, 5, 6, 10, 10, 13]}, "outputs": {"toindex": [0, 1, 2, 0, 1, 0, 0, 1, 2, 3, 0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 3, 3, 5, 6, 10]}, "outputs": {"toindex": [0, 1, 2, 0, 1, 0, 0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 3, 5, 6, 6, 10]}, "outputs": {"toindex": [0, 1, 2, 0, 1, 0, 0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 3, 3, 5]}, "outputs": {"toindex": [0, 1, 2, 0, 1]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 4, 4, 7, 8, 13]}, "outputs": {"toindex": [0, 1, 2, 3, 0, 1, 2, 0, 0, 1, 2, 3, 4]}}]}, {"name": "awkward_ListArray_rpad_axis1", "tests": [{"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5, "target": 4}, "outputs": {"toindex": [0, 1, 2, -1, -1, -1, -1, -1, 4, 5, -1, -1, 5, 6, 7, -1, 8, -1, -1, -1], "tostarts": [0, 4, 8, 12, 16], "tostops": [4, 8, 12, 16, 20]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5, "target": 3}, "outputs": {"toindex": [0, 1, 2, -1, -1, -1, 4, 5, -1, 5, 6, 7, 8, -1, -1], "tostarts": [0, 3, 6, 9, 12], "tostops": [3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "length": 3, "target": 3}, "outputs": {"toindex": [0, 1, 2, -1, -1, -1, 5, 6, -1], "tostarts": [0, 3, 6], "tostops": [3, 6, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5, "target": 2}, "outputs": {"toindex": [0, 1, 2, -1, -1, 4, 5, 5, 6, 7, 8, -1], "tostarts": [0, 3, 5, 7, 10], "tostops": [3, 5, 7, 10, 12]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5, "target": 1}, "outputs": {"toindex": [0, 1, 2, -1, 4, 5, 5, 6, 7, 8], "tostarts": [0, 3, 4, 6, 9], "tostops": [3, 4, 6, 9, 10]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "length": 4, "target": 4}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, -1, -1, 3, 4, -1, -1, 0, 1, 2, -1], "tostarts": [0, 4, 8, 12], "tostops": [4, 8, 12, 16]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "length": 5, "target": 4}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, -1, -1, 3, 4, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1], "tostarts": [0, 4, 8, 12, 16], "tostops": [4, 8, 12, 16, 20]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "length": 4, "target": 3}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, -1, 3, 4, -1, 0, 1, 2], "tostarts": [0, 4, 7, 10], "tostops": [4, 7, 10, 13]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "length": 5, "target": 3}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, -1, 3, 4, -1, -1, -1, -1, 0, 1, 2], "tostarts": [0, 4, 7, 10, 13], "tostops": [4, 7, 10, 13, 16]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "length": 5, "target": 2}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, 3, 4, -1, -1, 0, 1, 2], "tostarts": [0, 4, 6, 8, 10], "tostops": [4, 6, 8, 10, 13]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "length": 4, "target": 1}, "outputs": {"toindex": [6, 7, 8, 9, 5, 3, 4, 0, 1, 2], "tostarts": [0, 4, 5, 7], "tostops": [4, 5, 7, 10]}}]}, {"name": "awkward_ListOffsetArray_reduce_local_outoffsets_64", "tests": [{"error": false, "inputs": {"lenparents": 10, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 10]}}, {"error": false, "inputs": {"lenparents": 1, "outlength": 1, "parents": [0]}, "outputs": {"outoffsets": [0, 1]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 3, "parents": [0, 2, 2]}, "outputs": {"outoffsets": [0, 1, 1, 3]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 4, "parents": [0, 1, 3]}, "outputs": {"outoffsets": [0, 1, 2, 2, 3]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 3, "parents": [0, 1, 1]}, "outputs": {"outoffsets": [0, 1, 3, 3]}}, {"error": false, "inputs": {"lenparents": 4, "outlength": 3, "parents": [0, 1, 1, 2]}, "outputs": {"outoffsets": [0, 1, 3, 4]}}, {"error": false, "inputs": {"lenparents": 2, "outlength": 1, "parents": [0, 0]}, "outputs": {"outoffsets": [0, 2]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 5, "parents": [0, 0, 2, 2, 3, 4]}, "outputs": {"outoffsets": [0, 2, 2, 4, 5, 6]}}, {"error": false, "inputs": {"lenparents": 7, "outlength": 5, "parents": [0, 0, 2, 2, 3, 4, 4]}, "outputs": {"outoffsets": [0, 2, 2, 4, 5, 7]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 2, "parents": [0, 0, 1]}, "outputs": {"outoffsets": [0, 2, 3]}}, {"error": false, "inputs": {"lenparents": 4, "outlength": 2, "parents": [0, 0, 1, 1]}, "outputs": {"outoffsets": [0, 2, 4]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"outoffsets": [0, 3]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 2, "parents": [0, 0, 0, 1, 1, 1]}, "outputs": {"outoffsets": [0, 3, 6]}}, {"error": false, "inputs": {"lenparents": 4, "outlength": 1, "parents": [0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 4]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 0, 2, 2]}, "outputs": {"outoffsets": [0, 4, 4, 6]}}, {"error": false, "inputs": {"lenparents": 8, "outlength": 2, "parents": [0, 0, 0, 0, 1, 1, 1, 1]}, "outputs": {"outoffsets": [0, 4, 8]}}, {"error": false, "inputs": {"lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 5]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 6]}}, {"error": false, "inputs": {"lenparents": 7, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 7]}}, {"error": false, "inputs": {"lenparents": 8, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 8]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 9]}}]}, {"name": "awkward_ListOffsetArray_reduce_nonlocal_nextshifts_64", "tests": [{"error": false, "inputs": {"length": 3, "maxcount": 5, "nextcarry": [0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14], "nextlen": 15, "offsets": [0, 5, 10, 15], "parents": [0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nummissing": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"length": 2, "maxcount": 3, "nextcarry": [0, 3, 1, 4, 2, 5], "nextlen": 6, "offsets": [0, 3, 6], "parents": [0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0], "nummissing": [0, 0, 0]}}, {"error": false, "inputs": {"length": 3, "maxcount": 5, "nextcarry": [0, 5, 9, 1, 6, 10, 2, 7, 11, 3, 8, 4], "nextlen": 12, "offsets": [0, 5, 9, 12], "parents": [0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nummissing": [0, 0, 0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "maxcount": 5, "nextcarry": [0, 5, 8, 11, 14, 1, 6, 9, 12, 15, 2, 7, 10, 13, 16, 3, 4], "nextlen": 17, "offsets": [0, 5, 8, 11, 14, 17], "parents": [0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nummissing": [0, 0, 0, 4, 4]}}, {"error": false, "inputs": {"length": 4, "maxcount": 3, "nextcarry": [0, 2, 5, 7, 1, 3, 6, 8, 4], "nextlen": 9, "offsets": [0, 2, 5, 7, 9], "parents": [0, 0, 1, 1], "starts": [0, 2]}, "outputs": {"missing": [0, 0, 0, 0, 1, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 1], "nummissing": [0, 0, 2]}}, {"error": false, "inputs": {"length": 3, "maxcount": 4, "nextcarry": [0, 2, 3, 1, 4, 5, 6], "nextlen": 7, "offsets": [0, 2, 3, 7], "parents": [0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 1, 2, 2], "nextshifts": [0, 0, 0, 0, 1, 2, 2], "nummissing": [0, 1, 2, 2]}}, {"error": false, "inputs": {"length": 10, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2], "nummissing": [0, 2, 4]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 2, 2], "nummissing": [0, 2, 4]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 3, 2], "nummissing": [0, 2, 4]}}, {"error": false, "inputs": {"length": 3, "maxcount": 4, "nextcarry": [0, 3, 1, 4, 2, 5, 6], "nextlen": 7, "offsets": [0, 3, 3, 7], "parents": [0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 1, 1, 1, 2], "nextshifts": [0, 1, 0, 1, 0, 1, 2], "nummissing": [1, 1, 1, 2]}}, {"error": false, "inputs": {"length": 4, "maxcount": 3, "nextcarry": [0, 3, 5, 1, 4, 6, 2], "nextlen": 7, "offsets": [0, 3, 5, 5, 7], "parents": [0, 0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 1, 1], "nextshifts": [0, 0, 1, 0, 0, 1, 0], "nummissing": [1, 1, 3]}}, {"error": false, "inputs": {"length": 4, "maxcount": 3, "nextcarry": [0, 3, 5, 1, 4, 6, 2], "nextlen": 7, "offsets": [0, 3, 3, 5, 7], "parents": [0, 0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 1, 1, 1, 1], "nextshifts": [0, 1, 1, 0, 1, 1, 0], "nummissing": [1, 1, 3]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 18, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2, 0, 1, 1], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 15, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2, 1, 2, 1], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 1, 2, 3, 1, 2, 1], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 1, 1, 2, 1, 2, 3, 1, 2, 1], "nextshifts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 15, 17, 18, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 15, 17, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 1], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 15, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 0, 1, 2, 1, 2, 1], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 1, 2, 3, 1, 2, 1], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 3, 1, 2, 1], "nextshifts": [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 18, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 3, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 1], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 2, 2, 2, 1, 1, 1, 3, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 15, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 0, 1, 2, 1, 2, 1], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 2, 3, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 1, 2, 3, 1, 2, 1], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 2, 2, 2, 1, 2, 2, 3, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 1, 1, 2, 1, 2, 3, 1, 2, 1], "nextshifts": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 2, 2, 3, 2, 3, 4, 2, 3, 2], "nextshifts": [0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 2, 4], "nummissing": [2, 4, 6]}}, {"error": false, "inputs": {"length": 13, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 2, 2, 3, 2, 3, 4, 2, 3, 2], "nextshifts": [0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 3, 3, 3, 2, 4], "nummissing": [2, 4, 6]}}, {"error": false, "inputs": {"length": 13, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, 4, 2, 3, 2], "nextshifts": [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4], "nummissing": [2, 4, 6]}}, {"error": false, "inputs": {"length": 9, "maxcount": 4, "nextcarry": [0, 1, 3, 6, 10, 13, 15, 2, 4, 7, 11, 14, 5, 8, 12, 9], "nextlen": 16, "offsets": [0, 0, 1, 3, 6, 10, 13, 15, 16, 16], "parents": [0, 0, 0, 0, 0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 1, 2, 1], "nextshifts": [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4], "nummissing": [2, 4, 6, 8]}}]}, {"name": "awkward_ListOffsetArray_reduce_nonlocal_nextstarts_64", "tests": [{"error": false, "inputs": {"nextlen": 18, "nextparents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 2, 5]}, "outputs": {"nextstarts": [0, 10, 16, 5, 13, 17]}}, {"error": false, "inputs": {"nextlen": 21, "nextparents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 4, 2, 5, 5, 5]}, "outputs": {"nextstarts": [0, 10, 17, 5, 13, 18]}}, {"error": false, "inputs": {"nextlen": 3, "nextparents": [0, 1, 2]}, "outputs": {"nextstarts": [0, 1, 2]}}, {"error": false, "inputs": {"nextlen": 5, "nextparents": [0, 0, 1, 2, 3]}, "outputs": {"nextstarts": [0, 2, 3, 4]}}, {"error": false, "inputs": {"nextlen": 6, "nextparents": [0, 0, 1, 1, 2, 2]}, "outputs": {"nextstarts": [0, 2, 4]}}, {"error": false, "inputs": {"nextlen": 6, "nextparents": [0, 0, 1, 1, 2, 3]}, "outputs": {"nextstarts": [0, 2, 4, 5]}}, {"error": false, "inputs": {"nextlen": 8, "nextparents": [0, 0, 1, 1, 2, 2, 3, 3]}, "outputs": {"nextstarts": [0, 2, 4, 6]}}, {"error": false, "inputs": {"nextlen": 7, "nextparents": [0, 0, 1, 1, 2, 2, 3]}, "outputs": {"nextstarts": [0, 2, 4, 6]}}, {"error": false, "inputs": {"nextlen": 6, "nextparents": [0, 0, 0, 1, 1, 1]}, "outputs": {"nextstarts": [0, 3]}}, {"error": false, "inputs": {"nextlen": 5, "nextparents": [0, 0, 0, 1, 1]}, "outputs": {"nextstarts": [0, 3]}}, {"error": false, "inputs": {"nextlen": 7, "nextparents": [0, 0, 0, 1, 1, 2, 3]}, "outputs": {"nextstarts": [0, 3, 5, 6]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 0, 1, 1, 2, 2, 3, 4]}, "outputs": {"nextstarts": [0, 3, 5, 7, 8]}}, {"error": false, "inputs": {"nextlen": 7, "nextparents": [0, 0, 0, 1, 1, 1, 2]}, "outputs": {"nextstarts": [0, 3, 6]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 3]}, "outputs": {"nextstarts": [0, 3, 6, 8]}}, {"error": false, "inputs": {"nextlen": 10, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"nextstarts": [0, 3, 6, 9]}}, {"error": false, "inputs": {"nextlen": 12, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"nextstarts": [0, 3, 6, 9]}}, {"error": false, "inputs": {"nextlen": 12, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4]}, "outputs": {"nextstarts": [0, 3, 6, 9, 11]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"nextstarts": [0, 3, 6, 9, 12]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 5, 5, 1, 6, 6, 2, 7, 7, 3, 8, 8, 4, 9, 9]}, "outputs": {"nextstarts": [0, 3, 6, 9, 12, 1, 4, 7, 10, 13]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14]}, "outputs": {"nextstarts": [0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 0, 5, 1, 1, 6, 2, 2, 7, 3, 3, 8, 4, 4, 9]}, "outputs": {"nextstarts": [0, 3, 6, 9, 12, 2, 5, 8, 11, 14]}}, {"error": false, "inputs": {"nextlen": 6, "nextparents": [0, 0, 0, 0, 1, 1]}, "outputs": {"nextstarts": [0, 4]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 0, 0, 1, 1, 1, 2, 2]}, "outputs": {"nextstarts": [0, 4, 7]}}, {"error": false, "inputs": {"nextlen": 20, "nextparents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]}, "outputs": {"nextstarts": [0, 4, 8, 12, 16]}}, {"error": false, "inputs": {"nextlen": 20, "nextparents": [0, 0, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 3, 8, 8, 4, 4, 9, 9]}, "outputs": {"nextstarts": [0, 4, 8, 12, 16, 2, 6, 10, 14, 18]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 3, 3, 1, 1, 4, 4, 2]}, "outputs": {"nextstarts": [0, 4, 8, 2, 6]}}, {"error": false, "inputs": {"nextlen": 12, "nextparents": [0, 0, 3, 3, 1, 1, 4, 4, 2, 2, 5, 5]}, "outputs": {"nextstarts": [0, 4, 8, 2, 6, 10]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"nextstarts": [0, 5, 10]}}, {"error": false, "inputs": {"nextlen": 17, "nextparents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4]}, "outputs": {"nextstarts": [0, 5, 10, 15, 16]}}, {"error": false, "inputs": {"nextlen": 25, "nextparents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]}, "outputs": {"nextstarts": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 0, 3, 3, 1, 1, 4, 2]}, "outputs": {"nextstarts": [0, 5, 8, 3, 7]}}, {"error": false, "inputs": {"nextlen": 22, "nextparents": [0, 0, 0, 5, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 3, 8, 8, 4, 4, 9, 9]}, "outputs": {"nextstarts": [0, 6, 10, 14, 18, 3, 8, 12, 16, 20]}}, {"error": false, "inputs": {"nextlen": 16, "nextparents": [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"nextstarts": [0, 7, 12, 15]}}]}, {"name": "awkward_ListOffsetArray_reduce_nonlocal_outstartsstops_64", "tests": [{"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 5, 15]}}, {"error": false, "inputs": {"distincts": [0, 0], "lendistincts": 2, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [2]}}, {"error": false, "inputs": {"distincts": [0, 0, 0], "lendistincts": 3, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [3]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 1, 1, -1], "lendistincts": 6, "outlength": 2}, "outputs": {"outstarts": [0, 3], "outstops": [3, 5]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 1, 1, 1], "lendistincts": 6, "outlength": 2}, "outputs": {"outstarts": [0, 3], "outstops": [3, 6]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 1, 1, -1, 2, -1, -1], "lendistincts": 9, "outlength": 3}, "outputs": {"outstarts": [0, 3, 6], "outstops": [3, 5, 7]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 1, -1, -1, 2, 1, -1, 3, -1, -1], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [3, 4, 8, 10]}}, {"error": false, "inputs": {"distincts": [0, 0, -1, 1, -1, -1, -1, -1, -1, 2, 1, 0], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [2, 4, 6, 12]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0], "lendistincts": 4, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [4]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, -1, 1, 1, 1, 0], "lendistincts": 8, "outlength": 2}, "outputs": {"outstarts": [0, 4], "outstops": [3, 8]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0], "lendistincts": 5, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [5]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, -1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 10, 14]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 10, 15]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, -1, -1, -1, -1, 2, 1, 1, 1, 1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 6, 15]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, -1, 2, 2, 2, 2, 1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 9, 15]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 10, 10]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1], "lendistincts": 10, "outlength": 2}, "outputs": {"outstarts": [0, 5], "outstops": [5, 10]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, -1, -1, -1, 1, 1, -1], "lendistincts": 9, "outlength": 3}, "outputs": {"outstarts": [0, 3, 6], "outstops": [3, 3, 8]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, -1, -1, -1, 1, 1, 1], "lendistincts": 9, "outlength": 3}, "outputs": {"outstarts": [0, 3, 6], "outstops": [3, 3, 9]}}, {"error": false, "inputs": {"distincts": [0, 0, -1, -1, -1, -1, 1, -1, -1, 2, 1, 0], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [2, 3, 7, 12]}}, {"error": false, "inputs": {"distincts": [0, 0, -1, -1, -1, -1, -1, -1, -1, 1, 1, 0], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [2, 3, 6, 12]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, -1, -1, -1, -1, -1, -1, 1, 1, 1], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [3, 3, 6, 12]}}, {"error": false, "inputs": {"distincts": [], "lendistincts": 0, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [0]}}]}, {"name": "awkward_NumpyArray_reduce_mask_ByteMaskedArray_64", "tests": [{"error": false, "inputs": {"lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 18, "outlength": 6, "parents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 2, 5]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 21, "outlength": 6, "parents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 4, 2, 5, 5, 5]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 20, "outlength": 5, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 15, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 12, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 1, 2, 2, 3, 4]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [0, 0]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 7, "outlength": 4, "parents": [0, 0, 0, 1, 1, 2, 3]}, "outputs": {"toptr": [0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"toptr": [0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 5, "parents": [0, 0, 3, 3, 1, 1, 4, 4, 2]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 1, 1, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 0, 1, 1, 1, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 5, "outlength": 3, "parents": [0, 0, 1, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 22, "outlength": 8, "parents": [0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 1, 1, 1, 5, 5, 5, 5, 2, 6, 6, 6, 7]}, "outputs": {"toptr": [0, 0, 0, 1, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 2, 2, 4, 4, 4]}, "outputs": {"toptr": [0, 0, 0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [0, 0, 0, 1, 1, 1, 0, 0]}}, {"error": false, "inputs": {"lenparents": 12, "outlength": 9, "parents": [0, 0, 6, 6, 1, 1, 7, 7, 2, 2, 8, 8]}, "outputs": {"toptr": [0, 0, 0, 1, 1, 1, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 1, 1, 3]}, "outputs": {"toptr": [0, 0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 3, 3, 3]}, "outputs": {"toptr": [0, 0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [0, 1, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 4]}, "outputs": {"toptr": [0, 1, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 2, 2, 2]}, "outputs": {"toptr": [0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 3, "parents": [0, 0, 2]}, "outputs": {"toptr": [0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 7, "parents": [0, 0, 0, 2, 2, 3, 6, 6, 6]}, "outputs": {"toptr": [0, 1, 0, 0, 1, 1, 0]}}]}, {"name": "awkward_UnionArray_fillna", "tests": [{"error": false, "inputs": {"fromindex": [-1, -1, -1, -1, -1], "length": 5}, "outputs": {"toindex": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [-1, -1, 0, -1, 1, 2, 3, 4, 5, -1, -1, -1], "length": 12}, "outputs": {"toindex": [0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [-1, 0, 1, -1], "length": 4}, "outputs": {"toindex": [0, 0, 1, 0]}}, {"error": false, "inputs": {"fromindex": [0, -1, 1], "length": 3}, "outputs": {"toindex": [0, 0, 1]}}, {"error": false, "inputs": {"fromindex": [0, -1, 1, -1, 2], "length": 5}, "outputs": {"toindex": [0, 0, 1, 0, 2]}}, {"error": false, "inputs": {"fromindex": [0, -1, 1, 2], "length": 4}, "outputs": {"toindex": [0, 0, 1, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1], "length": 3}, "outputs": {"toindex": [0, 1, 0]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2], "length": 4}, "outputs": {"toindex": [0, 1, 0, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2, 3, -1, 4], "length": 7}, "outputs": {"toindex": [0, 1, 0, 2, 3, 0, 4]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, -1, -1, -1], "length": 6}, "outputs": {"toindex": [0, 1, 2, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, -1, -1, 3, 4, 5, -1, -1], "length": 10}, "outputs": {"toindex": [0, 1, 2, 0, 0, 3, 4, 5, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4, -1, -1], "length": 7}, "outputs": {"toindex": [0, 1, 2, 3, 4, 0, 0]}}, {"error": false, "inputs": {"fromindex": [13, 9, 13, 4, 8, 3, 15, -1, 16, 2, 8], "length": 11}, "outputs": {"toindex": [13, 9, 13, 4, 8, 3, 15, 0, 16, 2, 8]}}]}, {"name": "awkward_UnionArray_filltags", "tests": [{"error": false, "inputs": {"base": 0, "fromtags": [0, 0, 0, 1, 1, 1], "length": 6, "totagsoffset": 0}, "outputs": {"totags": [0, 0, 0, 1, 1, 1]}}]}, {"name": "awkward_UnionArray_project", "tests": [{"error": false, "inputs": {"fromindex": [], "fromtags": [], "length": 0, "which": 0}, "outputs": {"lenout": [0], "tocarry": []}}, {"error": false, "inputs": {"fromindex": [], "fromtags": [], "length": 0, "which": 1}, "outputs": {"lenout": [0], "tocarry": []}}, {"error": false, "inputs": {"fromindex": [1], "fromtags": [1], "length": 1, "which": 1}, "outputs": {"lenout": [1], "tocarry": [1]}}, {"error": false, "inputs": {"fromindex": [0, 0], "fromtags": [1, 1], "length": 2, "which": 1}, "outputs": {"lenout": [2], "tocarry": [0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 1], "fromtags": [0, 0], "length": 2, "which": 0}, "outputs": {"lenout": [2], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromindex": [0, 1], "fromtags": [1, 1], "length": 2, "which": 1}, "outputs": {"lenout": [2], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromindex": [2, 3], "fromtags": [0, 0], "length": 2, "which": 0}, "outputs": {"lenout": [2], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromindex": [2, 3], "fromtags": [1, 1], "length": 2, "which": 1}, "outputs": {"lenout": [2], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2], "fromtags": [0, 0, 0], "length": 3, "which": 0}, "outputs": {"lenout": [3], "tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2], "fromtags": [1, 1, 1], "length": 3, "which": 1}, "outputs": {"lenout": [3], "tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4], "fromtags": [0, 0, 0, 0, 0], "length": 5, "which": 0}, "outputs": {"lenout": [5], "tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4], "fromtags": [1, 1, 1, 1, 1], "length": 5, "which": 1}, "outputs": {"lenout": [5], "tocarry": [0, 1, 2, 3, 4]}}]}, {"name": "awkward_UnionArray_simplify_one", "tests": [{"error": false, "inputs": {"base": 0, "fromindex": [], "fromtags": [], "fromwhich": 0, "length": 0, "towhich": 0}, "outputs": {"toindex": [], "totags": []}}, {"error": false, "inputs": {"base": 0, "fromindex": [0, 0, 0, 0, 0], "fromtags": [1, 1, 1, 1, 1], "fromwhich": 1, "length": 5, "towhich": 0}, "outputs": {"toindex": [0, 0, 0, 0, 0], "totags": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"base": 9, "fromindex": [0, 1, 2, 3, 4, 5, 6, 7, 8], "fromtags": [1, 1, 1, 1, 1, 1, 1, 1, 1], "fromwhich": 1, "length": 9, "towhich": 0}, "outputs": {"toindex": [9, 10, 11, 12, 13, 14, 15, 16, 17], "totags": [0, 0, 0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"base": 0, "fromindex": [0, 1], "fromtags": [1, 1], "fromwhich": 1, "length": 2, "towhich": 0}, "outputs": {"toindex": [0, 1], "totags": [0, 0]}}, {"error": false, "inputs": {"base": 0, "fromindex": [0], "fromtags": [1], "fromwhich": 1, "length": 1, "towhich": 0}, "outputs": {"toindex": [0], "totags": [0]}}, {"error": false, "inputs": {"base": 0, "fromindex": [], "fromtags": [], "fromwhich": 1, "length": 0, "towhich": 0}, "outputs": {"toindex": [], "totags": []}}, {"error": false, "inputs": {"base": 0, "fromindex": [], "fromtags": [], "fromwhich": 1, "length": 0, "towhich": 1}, "outputs": {"toindex": [], "totags": []}}]}, {"name": "awkward_localindex", "tests": [{"error": false, "inputs": {"length": 0}, "outputs": {"toindex": []}}, {"error": false, "inputs": {"length": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 4}, "outputs": {"toindex": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 5}, "outputs": {"toindex": [0, 1, 2, 3, 4]}}]}, {"name": "awkward_BitMaskedArray_to_IndexedOptionArray", "tests": [{"error": false, "inputs": {"bitmasklength": 2, "frombitmask": [58, 59], "lsb_order": false, "validwhen": false}, "outputs": {"toindex": [0, 1, -1, -1, -1, 5, -1, 7, 8, 9, -1, -1, -1, 13, -1, -1]}}, {"error": false, "inputs": {"bitmasklength": 2, "frombitmask": [58, 59], "lsb_order": true, "validwhen": false}, "outputs": {"toindex": [0, -1, 2, -1, -1, -1, 6, 7, -1, -1, 10, -1, -1, -1, 14, 15]}}]}, {"name": "awkward_ListArray_getitem_jagged_shrink", "tests": [{"error": false, "inputs": {"length": 1, "missing": [0, 0, 0, 0], "slicestarts": [0, 1, 1, 1], "slicestops": [4]}, "outputs": {"tocarry": [0, 1, 2, 3], "tolargeoffsets": [0, 4], "tosmalloffsets": [0, 4]}}, {"error": false, "inputs": {"length": 2, "missing": [0, 0, 0, 0], "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"tocarry": [0, 1], "tolargeoffsets": [0, 2, 2], "tosmalloffsets": [0, 2, 2]}}, {"error": false, "inputs": {"length": 2, "missing": [0, 0, 0, 0], "slicestarts": [0, 2, 2], "slicestops": [2, 2, 4]}, "outputs": {"tocarry": [0, 1], "tolargeoffsets": [0, 2, 2], "tosmalloffsets": [0, 2, 2]}}, {"error": false, "inputs": {"length": 3, "missing": [0, 0, 0, 0], "slicestarts": [0, 2, 3, 3], "slicestops": [2, 3, 3, 4]}, "outputs": {"tocarry": [0, 1, 2], "tolargeoffsets": [0, 2, 3, 3], "tosmalloffsets": [0, 2, 3, 3]}}, {"error": false, "inputs": {"length": 3, "missing": [0, 0, 0, 0], "slicestarts": [0, 2, 3, 3], "slicestops": [2, 3, 3, 6]}, "outputs": {"tocarry": [0, 1, 2], "tolargeoffsets": [0, 2, 3, 3], "tosmalloffsets": [0, 2, 3, 3]}}]}, {"name": "awkward_Content_getitem_next_missing_jagged_getmaskstartstop", "tests": [{"error": false, "inputs": {"index_in": [0, -1], "length": 2, "offsets_in": [0, 1]}, "outputs": {"mask_out": [0, -1], "starts_out": [0, 1], "stops_out": [1, 1]}}, {"error": false, "inputs": {"index_in": [0, -1], "length": 2, "offsets_in": [0, 4]}, "outputs": {"mask_out": [0, -1], "starts_out": [0, 4], "stops_out": [4, 4]}}, {"error": false, "inputs": {"index_in": [0, -1, -1], "length": 3, "offsets_in": [0, 1]}, "outputs": {"mask_out": [0, -1, -1], "starts_out": [0, 1, 1], "stops_out": [1, 1, 1]}}, {"error": false, "inputs": {"index_in": [0, -1, 1], "length": 3, "offsets_in": [0, 1, 2]}, "outputs": {"mask_out": [0, -1, 2], "starts_out": [0, 1, 1], "stops_out": [1, 1, 2]}}, {"error": false, "inputs": {"index_in": [0, -1, 1], "length": 3, "offsets_in": [0, 2, 4]}, "outputs": {"mask_out": [0, -1, 2], "starts_out": [0, 2, 2], "stops_out": [2, 2, 4]}}, {"error": false, "inputs": {"index_in": [0, -1, -1, 1], "length": 4, "offsets_in": [0, 0, 0]}, "outputs": {"mask_out": [0, -1, -1, 3], "starts_out": [0, 0, 0, 0], "stops_out": [0, 0, 0, 0]}}, {"error": false, "inputs": {"index_in": [0, -1, -1, 1], "length": 4, "offsets_in": [0, 1, 2]}, "outputs": {"mask_out": [0, -1, -1, 3], "starts_out": [0, 1, 1, 1], "stops_out": [1, 1, 1, 2]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, -1], "length": 4, "offsets_in": [0, 2, 3]}, "outputs": {"mask_out": [0, -1, 2, -1], "starts_out": [0, 2, 2, 3], "stops_out": [2, 2, 3, 3]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, -1, 2], "length": 5, "offsets_in": [0, 2, 2, 4]}, "outputs": {"mask_out": [0, -1, 2, -1, 4], "starts_out": [0, 2, 2, 2, 2], "stops_out": [2, 2, 2, 2, 4]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 0, 0, 0]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 0, 0, 0], "stops_out": [0, 0, 0, 0]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 0, 1, 1]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 0, 1, 1], "stops_out": [0, 1, 1, 1]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2], "length": 4, "offsets_in": [0, 1, 2, 3]}, "outputs": {"mask_out": [0, -1, 2, 3], "starts_out": [0, 1, 1, 2], "stops_out": [1, 1, 2, 3]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 3, 3]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 3]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 3, 4]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 4]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 3, 5]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 5]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2], "length": 4, "offsets_in": [0, 2, 3, 5]}, "outputs": {"mask_out": [0, -1, 2, 3], "starts_out": [0, 2, 2, 3], "stops_out": [2, 2, 3, 5]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 3, 6]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 6]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 4, 5]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 4, 4], "stops_out": [2, 4, 4, 5]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2], "length": 4, "offsets_in": [0, 3, 3, 4]}, "outputs": {"mask_out": [0, -1, 2, 3], "starts_out": [0, 3, 3, 3], "stops_out": [3, 3, 3, 4]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 3, 3, 5]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 3, 3, 3], "stops_out": [3, 3, 3, 5]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 4, 5, 6]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 4, 5, 5], "stops_out": [4, 5, 5, 6]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2], "length": 4, "offsets_in": [0, 4, 5, 6]}, "outputs": {"mask_out": [0, -1, 2, 3], "starts_out": [0, 4, 4, 5], "stops_out": [4, 4, 5, 6]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2, -1, 3, 4, 5], "length": 8, "offsets_in": [0, 2, 4, 6, 8, 10, 12]}, "outputs": {"mask_out": [0, -1, 2, 3, -1, 5, 6, 7], "starts_out": [0, 2, 2, 4, 6, 6, 8, 10], "stops_out": [2, 2, 4, 6, 6, 8, 10, 12]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2, 3, 4, 5, 6], "length": 8, "offsets_in": [0, 1, 1, 1, 1, 1, 1, 1]}, "outputs": {"mask_out": [0, -1, 2, 3, 4, 5, 6, 7], "starts_out": [0, 1, 1, 1, 1, 1, 1, 1], "stops_out": [1, 1, 1, 1, 1, 1, 1, 1]}}]}, {"name": "awkward_reduce_sum_bool", "tests": [{"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 0, 1, 0, 0, 0], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 0, 1, 0, 0, 1, 0, 1, 1], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [1, 0, 0, 1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 0, 1, 0, 1, 0, 0, 1, 1], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [1, 0, 1, 0, 0, 0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [0, 1, 1, 0, 1, 0, 0, 0, 0, 0], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 0, 2, 0, 0, 0, 0, 0], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 0, 0, 2, 2, 0, 3, 0, 0, 0], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [1]}}]}, {"name": "awkward_reduce_prod_bool", "tests": [{"error": false, "inputs": {"fromptr": [1, 0, 1, 0, 1, 0, 0, 1, 1], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [0, 0, 1, 1, 1, 1, 0, 1]}}, {"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 1], "lenparents": 6, "outlength": 2, "parents": [0, 0, 0, 1, 1, 1]}, "outputs": {"toptr": [0, 1]}}, {"error": false, "inputs": {"fromptr": [1, 0, 1, 0, 0, 1, 0, 1, 1], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [0, 1, 0, 1, 0, 1]}}, {"error": false, "inputs": {"fromptr": [1, 0, 0, 1, 1, 1, 1, 0, 0, 1], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 0, 1]}}, {"error": false, "inputs": {"fromptr": [1, 0, 0, 2, 2, 2, 3, 0, 0, 4], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 0, 1]}}, {"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 1, 1, 1, 1, 1], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 25, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5]}, "outputs": {"toptr": [0, 1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], "lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [0, 1, 1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], "lenparents": 22, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5]}, "outputs": {"toptr": [1, 0, 0, 1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 0, 1, 0, 0, 1, 0, 1], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 0, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 19, "outlength": 5, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4]}, "outputs": {"toptr": [1, 0, 0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 0, 2, 0, 0, 2, 0, 4], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 0, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 0, 0, 0], "lenparents": 6, "outlength": 2, "parents": [0, 0, 0, 1, 1, 1]}, "outputs": {"toptr": [1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 0, 0, 0], "lenparents": 9, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1], "lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 11, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 17, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [1, 1, 1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 19, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [1, 1, 1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 22, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5]}, "outputs": {"toptr": [1, 1, 1, 1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [1]}}]}, {"name": "awkward_reduce_argmax", "tests": [{"error": false, "inputs": {"fromptr": [1, -1, 1, -1, 1, 21], "lenparents": 6, "outlength": 3, "parents": [0, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [0, 2, 5]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 6, 7], "lenparents": 6, "outlength": 3, "parents": [0, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [0, 2, 5]}}, {"error": false, "inputs": {"fromptr": [6, 1, 10, 33, -1, 21, 2, 45, 4], "lenparents": 9, "outlength": 5, "parents": [0, 0, 3, 3, 1, 1, 4, 4, 2]}, "outputs": {"toptr": [0, 5, 8, 3, 7]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 6], "lenparents": 5, "outlength": 3, "parents": [0, 0, 1, 2, 2]}, "outputs": {"toptr": [1, 2, 4]}}, {"error": false, "inputs": {"fromptr": [3, 4, 2, 1, 2, 3, 6, 1, -1, 1, 7, 4], "lenparents": 12, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4]}, "outputs": {"toptr": [1, 5, 6, 10, 11]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [2]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 6], "lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 1, 1, 2]}, "outputs": {"toptr": [2, 4, 5]}}, {"error": false, "inputs": {"fromptr": [3, 1, 6, 1, 4, 4, 2, 1, 7, 2, 3, -1], "lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [2, 8, 10]}}, {"error": false, "inputs": {"fromptr": [0, 0, 4, 4, 6], "lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [4]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 6], "lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [4]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [5]}}]}, {"name": "awkward_reduce_max", "tests": [{"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "identity": -9223372036854775808, "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [13, 11, 5, -9223372036854775808, -9223372036854775808, -9223372036854775808, 23, 19]}}, {"error": false, "inputs": {"fromptr": [0, 1, 3, 4, 5, 6], "identity": -9223372036854775808, "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 3, 3, 3]}, "outputs": {"toptr": [1, 3, -9223372036854775808, 6]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "identity": -9223372036854775808, "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [3]}}, {"error": false, "inputs": {"fromptr": [0, 4, 1, 3, 5, 6], "identity": -9223372036854775808, "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 1, 1, 3]}, "outputs": {"toptr": [4, 5, -9223372036854775808, 6]}}, {"error": false, "inputs": {"fromptr": [1, 2, 5, 3, 3, 5, 1, 4, 2], "identity": -9223372036854775808, "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 1, 2, 2, 3, 4]}, "outputs": {"toptr": [5, 3, 5, 4, 2]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 2, 3, 1, 5], "identity": 4, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [5, 4, 4, 5]}}, {"error": false, "inputs": {"fromptr": [1, 3, 6, 4, 2, 2, 3, 1, 6], "identity": 4, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [6, 4, 4, 6]}}, {"error": false, "inputs": {"fromptr": [1, 3, 2, 5, 3, 7, 3, 1, 5, 8, 1, 9, 4, 2, 7, 10, 2, 4, 7, 2], "identity": -9223372036854775808, "lenparents": 20, "outlength": 5, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]}, "outputs": {"toptr": [5, 7, 9, 10, 7]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 3, 7, 8, 2, 4, 2, 3, 1, 7, 7, 5, 1, 9, 10, 2], "identity": -9223372036854775808, "lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [5, 8, 7, 10]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "identity": -9223372036854775808, "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [5, -9223372036854775808, 11, 13, 19, 23]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 2, 3, 1, 5], "identity": -9223372036854775808, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [5, -9223372036854775808, 3, 5]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "identity": -9223372036854775808, "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [6]}}]}, {"name": "awkward_reduce_countnonzero", "tests": [{"error": false, "inputs": {"fromptr": [1, 0, 0, 2, 2, 2, 3, 0, 0, 4], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 3, 1, 1]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [3, 0, 2, 1, 2, 1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 0, 2, 0, 0, 2, 0, 4], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [3, 1, 2]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [3]}}, {"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [3, 2, 1, 0, 0, 0, 2, 1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [6]}}]}, {"name": "awkward_reduce_count_64", "tests": [{"error": false, "inputs": {"lenparents": 19, "outlength": 9, "parents": [1, 1, 1, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [0, 3, 0, 5, 4, 0, 4, 3, 0]}}, {"error": false, "inputs": {"lenparents": 19, "outlength": 8, "parents": [1, 1, 1, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [0, 3, 0, 5, 4, 0, 4, 3]}}, {"error": false, "inputs": {"lenparents": 1696, "outlength": 331, "parents": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]}, "outputs": {"toptr": [626, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 3, "parents": [0, 0, 2]}, "outputs": {"toptr": [2, 0, 1]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [3]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [3, 0, 2, 1, 2, 1]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [3, 2, 1, 0, 0, 0, 2, 1]}}, {"error": false, "inputs": {"lenparents": 21, "outlength": 9, "parents": [0, 0, 0, 1, 1, 1, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 0, 4, 4, 0, 4, 3, 0]}}, {"error": false, "inputs": {"lenparents": 21, "outlength": 8, "parents": [0, 0, 0, 1, 1, 1, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 0, 4, 4, 0, 4, 3]}}, {"error": false, "inputs": {"lenparents": 22, "outlength": 9, "parents": [0, 0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 0, 5, 4, 0, 4, 3, 0]}}, {"error": false, "inputs": {"lenparents": 22, "outlength": 8, "parents": [0, 0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 0, 5, 4, 0, 4, 3]}}, {"error": false, "inputs": {"lenparents": 24, "outlength": 9, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 2, 5, 4, 0, 4, 3, 0]}}, {"error": false, "inputs": {"lenparents": 24, "outlength": 8, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 2, 5, 4, 0, 4, 3]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [3, 3, 3, 1]}}, {"error": false, "inputs": {"lenparents": 18, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]}, "outputs": {"toptr": [3, 3, 3, 3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 21, "outlength": 7, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6]}, "outputs": {"toptr": [3, 3, 3, 3, 3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9]}, "outputs": {"toptr": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 23, "outlength": 7, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6]}, "outputs": {"toptr": [3, 3, 3, 3, 3, 5, 3]}}, {"error": false, "inputs": {"lenparents": 23, "outlength": 7, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6]}, "outputs": {"toptr": [3, 3, 3, 3, 5, 3, 3]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [3, 3, 4]}}, {"error": false, "inputs": {"lenparents": 43, "outlength": 10, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9]}, "outputs": {"toptr": [3, 3, 4, 2, 4, 5, 6, 4, 5, 7]}}, {"error": false, "inputs": {"lenparents": 39, "outlength": 10, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9]}, "outputs": {"toptr": [3, 3, 4, 3, 3, 5, 6, 4, 3, 5]}}, {"error": false, "inputs": {"lenparents": 11, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [3, 3, 5]}}, {"error": false, "inputs": {"lenparents": 20, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]}, "outputs": {"toptr": [3, 3, 5, 3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 25, "outlength": 7, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6]}, "outputs": {"toptr": [3, 3, 5, 3, 3, 3, 5]}}, {"error": false, "inputs": {"lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [5]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [5, 5]}}, {"error": false, "inputs": {"lenparents": 29, "outlength": 7, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6]}, "outputs": {"toptr": [5, 5, 5, 3, 3, 3, 5]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [6]}}]}, {"name": "awkward_reduce_sum", "tests": [{"error": false, "inputs": {"fromptr": [0], "lenparents": 1, "outlength": 1, "parents": [0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"fromptr": [0, 5, 20, 1, 6, 21, 2, 7, 22, 3, 8, 23, 4, 9, 24], "lenparents": 15, "outlength": 10, "parents": [0, 5, 5, 1, 6, 6, 2, 7, 7, 3, 8, 8, 4, 9, 9]}, "outputs": {"toptr": [0, 1, 2, 3, 4, 25, 27, 29, 31, 33]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [10, 0, 18, 13, 36, 23]}}, {"error": false, "inputs": {"fromptr": [1, 0, 0, 1, 0, 0], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [1, 0, 1, 0]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24], "lenparents": 15, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [10, 35, 110]}}, {"error": false, "inputs": {"fromptr": [0, 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], "lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [10, 35, 60, 85, 110, 135]}}, {"error": false, "inputs": {"fromptr": [0, 1, 3, 4, 5, 6], "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 3, 3, 3]}, "outputs": {"toptr": [1, 3, 0, 15]}}, {"error": false, "inputs": {"fromptr": [0, 5, 10, 15, 25, 1, 11, 16, 26, 2, 12, 17, 27, 8, 18, 28, 4, 9, 14, 29], "lenparents": 20, "outlength": 10, "parents": [0, 0, 0, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 8, 8, 4, 4, 4, 9]}, "outputs": {"toptr": [15, 12, 14, 8, 27, 40, 42, 44, 46, 29]}}, {"error": false, "inputs": {"fromptr": [15, 20, 25, 16, 21, 26, 17, 22, 27, 18, 23, 28, 19, 24, 29], "lenparents": 15, "outlength": 15, "parents": [0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14]}, "outputs": {"toptr": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromptr": [0, 15, 5, 10, 25, 1, 16, 11, 26, 2, 17, 12, 27, 18, 8, 28, 4, 9, 14, 29], "lenparents": 20, "outlength": 15, "parents": [0, 0, 5, 10, 10, 1, 1, 11, 11, 2, 2, 12, 12, 3, 8, 13, 4, 9, 14, 14]}, "outputs": {"toptr": [15, 17, 19, 18, 4, 5, 0, 0, 8, 9, 35, 37, 39, 28, 43]}}, {"error": false, "inputs": {"fromptr": [0, 15, 5, 20, 10, 25, 1, 16, 6, 21, 11, 26, 2, 17, 7, 22, 12, 27, 3, 18, 8, 23, 13, 28, 4, 19, 9, 24, 14, 29], "lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43]}}, {"error": false, "inputs": {"fromptr": [0, 5, 10, 15, 20, 25, 1, 6, 11, 16, 21, 26, 2, 7, 12, 17, 22, 27, 3, 8, 13, 18, 23, 28, 4, 9, 14, 19, 24, 29], "lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [15, 18, 21, 24, 27, 60, 63, 66, 69, 72]}}, {"error": false, "inputs": {"fromptr": [1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 0], "lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [15, 240, 0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 1, 2, 3, 4, 5], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [15, 15]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [21]}}, {"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [22, 14, 5, 0, 0, 0, 40, 19]}}, {"error": false, "inputs": {"fromptr": [1, 16, 0, 2, 32, 0, 4, 64, 0, 8, 128, 0], "lenparents": 12, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"toptr": [17, 34, 68, 136]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 5], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [3, 0, 7, 5]}}, {"error": false, "inputs": {"fromptr": [0, 4, 1, 3, 5, 6], "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 1, 1, 3]}, "outputs": {"toptr": [4, 9, 0, 6]}}, {"error": false, "inputs": {"fromptr": [1, 4, 9, 16, 25, 1, 4, 9, 16, 25], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [55, 55]}}, {"error": false, "inputs": {"fromptr": [1, 4, 9, 16, 26, 1, 4, 10, 16, 24], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [56, 55]}}, {"error": false, "inputs": {"fromptr": [0, 5, 20, 1, 6, 21, 2, 7, 22, 3, 8, 23, 4, 9, 24], "lenparents": 15, "outlength": 10, "parents": [0, 0, 5, 1, 1, 6, 2, 2, 7, 3, 3, 8, 4, 4, 9]}, "outputs": {"toptr": [5, 7, 9, 11, 13, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromptr": [15, 20, 25, 16, 21, 26, 17, 22, 27, 18, 23, 28, 19, 24, 29], "lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [60, 63, 66, 69, 72]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [6]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 4, 5, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 25, 26, 27, 28, 29], "lenparents": 20, "outlength": 6, "parents": [0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [7, 22, 47, 66, 0, 135]}}, {"error": false, "inputs": {"fromptr": [2, 2, 4, 5, 5], "lenparents": 5, "outlength": 3, "parents": [0, 0, 0, 2, 2]}, "outputs": {"toptr": [8, 0, 10]}}, {"error": false, "inputs": {"fromptr": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "lenparents": 15, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [85, 110, 135]}}, {"error": false, "inputs": {"fromptr": [4, 1, 0, 1, 4, 5, 1, 0, 1, 3], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [10, 10]}}, {"error": false, "inputs": {"fromptr": [4, 1, 0, 1, 4, 4, 1, 0, 1, 4], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [10, 10]}}]}, {"name": "awkward_reduce_prod", "tests": [{"error": false, "inputs": {"fromptr": [1, 0, 0, 1, 0, 0], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 0, 0]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 5], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 12, 5]}}, {"error": false, "inputs": {"fromptr": [2, 53, 31, 101, 3, 59, 37, 103, 5, 61, 41, 107, 7, 67, 43, 109, 11, 71, 47, 113], "lenparents": 20, "outlength": 15, "parents": [0, 0, 10, 10, 1, 1, 11, 11, 2, 2, 12, 12, 3, 3, 13, 13, 4, 4, 14, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 1, 1, 1, 1, 1, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 47, 113], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 14, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 1, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 11, 71, 29, 97, 47], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 4, 4, 9, 9, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 43, 47]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 29, 97], "lenparents": 28, "outlength": 14, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 29, 97, 47], "lenparents": 29, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 47]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 29, 97, 47, 113], "lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 29, 47], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 29, 3131, 3811, 4387, 4687, 47]}}, {"error": false, "inputs": {"fromptr": [0], "lenparents": 1, "outlength": 3, "parents": [2]}, "outputs": {"toptr": [1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [101, 103, 107, 109, 113, 53, 59, 61, 67, 71, 31, 37, 41, 43, 47, 2, 3, 5, 7, 11], "lenparents": 20, "outlength": 6, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [13710311357, 1, 907383479, 95041567, 1, 2310]}}, {"error": false, "inputs": {"fromptr": [101, 103, 107, 109, 113, 73, 79, 83, 89, 97, 53, 59, 61, 67, 71, 31, 37, 41, 43, 47, 13, 17, 19, 23, 29, 2, 3, 5, 7, 11], "lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [13710311357, 4132280413, 907383479, 95041567, 2800733, 2310]}}, {"error": false, "inputs": {"fromptr": [101, 103, 107, 109, 113, 53, 59, 61, 67, 71, 31, 37, 41, 43, 47, 2, 3, 5, 7, 11], "lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [13710311357, 907383479, 95041567, 2310]}}, {"error": false, "inputs": {"fromptr": [2, 7, 17, 29, 3, 11, 19, 31, 5, 13, 23, 37], "lenparents": 12, "outlength": 6, "parents": [0, 0, 3, 3, 1, 1, 4, 4, 2, 2, 5, 5]}, "outputs": {"toptr": [14, 33, 65, 493, 589, 851]}}, {"error": false, "inputs": {"fromptr": [3, 53, 13, 73, 31, 101, 5, 59, 17, 79, 37, 103, 7, 61, 19, 83, 41, 107, 67, 23, 89, 43, 109, 71, 29, 97, 47, 113], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 8, 8, 13, 13, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [159, 295, 427, 67, 71, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [3, 53, 13, 73, 31, 101, 5, 59, 17, 79, 37, 103, 7, 61, 19, 83, 41, 107, 11, 67, 23, 89, 43, 109, 71, 29, 97, 47, 113], "lenparents": 29, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [159, 295, 427, 737, 71, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [3, 53, 13, 73, 31, 101, 5, 59, 17, 79, 37, 103, 7, 61, 19, 83, 41, 107, 11, 67, 23, 89, 43, 109, 71, 97, 47, 113], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 9, 14, 14]}, "outputs": {"toptr": [159, 295, 427, 737, 71, 949, 1343, 1577, 2047, 97, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [182, 33, 5, 1, 1, 1, 391, 19]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37], "lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [210, 46189, 765049]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 101, 103, 107, 109, 113], "lenparents": 20, "outlength": 6, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [2310, 1, 95041567, 907383479, 1, 13710311357]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113], "lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [2310, 2800733, 95041567, 907383479, 4132280413, 13710311357]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 101, 103, 107, 109, 113], "lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [2310, 95041567, 907383479, 13710311357]}}, {"error": false, "inputs": {"fromptr": [2, 7, 3, 11, 5], "lenparents": 5, "outlength": 8, "parents": [0, 6, 1, 7, 2]}, "outputs": {"toptr": [2, 3, 5, 1, 1, 1, 7, 11]}}, {"error": false, "inputs": {"fromptr": [5, 53, 13, 73, 31, 101, 7, 59, 17, 79, 37, 103, 11, 61, 19, 83, 41, 107, 67, 23, 89, 43, 109, 71, 29, 97, 47, 113], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 8, 8, 13, 13, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [265, 413, 671, 67, 71, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37], "lenparents": 12, "outlength": 8, "parents": [0, 0, 0, 3, 3, 3, 4, 4, 4, 7, 7, 7]}, "outputs": {"toptr": [30, 1, 1, 1001, 7429, 1, 1, 33263]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [30, 1, 77, 13]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [30, 1, 77, 13, 323, 23]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19], "lenparents": 8, "outlength": 5, "parents": [0, 0, 0, 2, 2, 3, 4, 4]}, "outputs": {"toptr": [30, 1, 77, 13, 323]}}, {"error": false, "inputs": {"fromptr": [6, 5, 7, 11, 13, 17, 19], "lenparents": 7, "outlength": 5, "parents": [0, 0, 2, 2, 3, 4, 4]}, "outputs": {"toptr": [30, 1, 77, 13, 323]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11], "lenparents": 5, "outlength": 3, "parents": [0, 0, 0, 2, 2]}, "outputs": {"toptr": [30, 1, 77]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [30]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11], "lenparents": 5, "outlength": 4, "parents": [0, 0, 0, 1, 2]}, "outputs": {"toptr": [30, 7, 11, 1]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11], "lenparents": 5, "outlength": 3, "parents": [0, 0, 0, 1, 2]}, "outputs": {"toptr": [30, 7, 11]}}, {"error": false, "inputs": {"fromptr": [101, 31, 53, 2, 103, 37, 59, 3, 107, 41, 61, 5, 109, 43, 67, 7, 113, 47, 71, 11], "lenparents": 20, "outlength": 15, "parents": [0, 0, 10, 10, 1, 1, 11, 11, 2, 2, 12, 12, 3, 3, 13, 13, 4, 4, 14, 14]}, "outputs": {"toptr": [3131, 3811, 4387, 4687, 5311, 1, 1, 1, 1, 1, 106, 177, 305, 469, 781]}}, {"error": false, "inputs": {"fromptr": [101, 31, 73, 13, 53, 2, 103, 37, 79, 17, 59, 3, 107, 41, 83, 19, 61, 5, 109, 43, 89, 23, 67, 7, 113, 47, 97, 29, 71, 11], "lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [3131, 3811, 4387, 4687, 5311, 949, 1343, 1577, 2047, 2813, 106, 177, 305, 469, 781]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 11, "outlength": 12, "parents": [0, 0, 3, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, -1, 1, 1, 1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 11, "outlength": 12, "parents": [0, 0, 6, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, -1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 10, "outlength": 12, "parents": [0, 0, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, 1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 29, 3, 19, 31, 37], "lenparents": 8, "outlength": 12, "parents": [0, 0, 3, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, -1, 1, 1, 1, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 29, 3, 19, 31, 37], "lenparents": 8, "outlength": 12, "parents": [0, 0, 6, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, -1, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, 29, 3, 19, 31, 37], "lenparents": 7, "outlength": 12, "parents": [0, 0, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, 1, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 39, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 12, "outlength": 12, "parents": [0, 0, 6, 6, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, -39, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 39, 29, 3, 19, 31, 37], "lenparents": 9, "outlength": 12, "parents": [0, 0, 6, 6, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, -39, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, 7, 29, 3, 19, 11, 31, 5, 23, 13, 37], "lenparents": 12, "outlength": 12, "parents": [0, 0, 9, 9, 1, 1, 10, 10, 2, 2, 11, 11]}, "outputs": {"toptr": [34, 57, 115, 1, 1, 1, 1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 39, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 12, "outlength": 12, "parents": [0, 0, 3, 3, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, -39, 1, 1, 1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 39, 29, 3, 19, 31, 37], "lenparents": 9, "outlength": 12, "parents": [0, 0, 3, 3, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, -39, 1, 1, 1, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, 7, 23, 13, 29, 3, 19, 11, 5], "lenparents": 10, "outlength": 7, "parents": [0, 0, 3, 3, 6, 6, 1, 1, 4, 2]}, "outputs": {"toptr": [34, 57, 5, 161, 11, 1, 377]}}, {"error": false, "inputs": {"fromptr": [2, 17, 23, 7, 13, 3, 19, 11, 5], "lenparents": 9, "outlength": 10, "parents": [0, 0, 3, 6, 9, 1, 1, 7, 2]}, "outputs": {"toptr": [34, 57, 5, 23, 1, 1, 7, 11, 1, 13]}}, {"error": false, "inputs": {"fromptr": [2, 11, 17, 7, 19, 3, 13, 23, 5], "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 3, 3, 1, 1, 4, 2]}, "outputs": {"toptr": [374, 39, 5, 133, 23]}}, {"error": false, "inputs": {"fromptr": [101, 73, 53, 31, 13, 2, 103, 79, 59, 37, 17, 3, 107, 83, 61, 41, 19, 5, 109, 89, 67, 43, 23, 7, 113, 97, 71, 47, 29, 11], "lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [390769, 480083, 541741, 649967, 778231, 806, 1887, 3895, 6923, 14993]}}, {"error": false, "inputs": {"fromptr": [2, 11, 23, 3, 13, 29, 5, 17, 31, 7, 19, 37], "lenparents": 12, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"toptr": [506, 1131, 2635, 4921]}}, {"error": false, "inputs": {"fromptr": [101, 53, 31, 2, 103, 59, 37, 3, 107, 61, 41, 5, 109, 67, 43, 7, 113, 71, 47, 11], "lenparents": 20, "outlength": 10, "parents": [0, 0, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 3, 8, 8, 4, 4, 9, 9]}, "outputs": {"toptr": [5353, 6077, 6527, 7303, 8023, 62, 111, 205, 301, 517]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [6]}}, {"error": false, "inputs": {"fromptr": [2, 31, 53, 101, 3, 37, 59, 103, 5, 41, 61, 107, 7, 43, 67, 109, 11, 47, 71, 113], "lenparents": 20, "outlength": 10, "parents": [0, 0, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 3, 8, 8, 4, 4, 9, 9]}, "outputs": {"toptr": [62, 111, 205, 301, 517, 5353, 6077, 6527, 7303, 8023]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19], "lenparents": 8, "outlength": 7, "parents": [0, 0, 1, 2, 3, 4, 5, 6]}, "outputs": {"toptr": [6, 5, 7, 11, 13, 17, 19]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19], "lenparents": 8, "outlength": 6, "parents": [0, 0, 1, 2, 3, 4, 5, 5]}, "outputs": {"toptr": [6, 5, 7, 11, 13, 323]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [720]}}, {"error": false, "inputs": {"fromptr": [2, 13, 31, 53, 73, 101, 3, 17, 37, 59, 79, 103, 5, 19, 41, 61, 83, 107, 7, 23, 43, 67, 89, 109, 11, 29, 47, 71, 97, 113], "lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [806, 1887, 3895, 6923, 14993, 390769, 480083, 541741, 649967, 778231]}}]}, {"name": "awkward_reduce_min", "tests": [{"error": false, "inputs": {"fromptr": [0, 4, 1, 3, 5, 6], "identity": 9223372036854775807, "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 1, 1, 3]}, "outputs": {"toptr": [0, 1, 9223372036854775807, 6]}}, {"error": false, "inputs": {"fromptr": [0, 1, 3, 4, 5, 6], "identity": 9223372036854775807, "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 3, 3, 3]}, "outputs": {"toptr": [0, 3, 9223372036854775807, 4]}}, {"error": false, "inputs": {"fromptr": [1, 3, 2, 5, 3, 7, 3, 1, 5, 8, 1, 9, 4, 2, 7, 10, 2, 4, 7, 2], "identity": 9223372036854775807, "lenparents": 20, "outlength": 5, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]}, "outputs": {"toptr": [1, 1, 1, 2, 2]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "identity": 9223372036854775807, "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "identity": 9223372036854775807, "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [1]}}, {"error": false, "inputs": {"fromptr": [1, 3, 6, 4, 2, 2, 3, 1, 6], "identity": 4, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 4, 1, 4]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 3, 7, 8, 2, 4, 2, 3, 1, 7, 7, 5, 1, 9, 10, 2], "identity": 9223372036854775807, "lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [1, 2, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 4, 4, 2, 2, 5, 3, 3, 3, 6, 2, 4], "identity": 9223372036854775807, "lenparents": 12, "outlength": 9, "parents": [0, 0, 6, 6, 1, 1, 7, 7, 2, 2, 8, 8]}, "outputs": {"toptr": [1, 2, 3, 9223372036854775807, 9223372036854775807, 9223372036854775807, 2, 3, 2]}}, {"error": false, "inputs": {"fromptr": [1, 2, 5, 3, 3, 5, 1, 4, 2], "identity": 9223372036854775807, "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 1, 2, 2, 3, 4]}, "outputs": {"toptr": [1, 3, 1, 4, 2]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 2, 3, 1, 5], "identity": 4, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 4, 1, 4]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 2, 3, 1, 5], "identity": 9223372036854775807, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 9223372036854775807, 1, 5]}}, {"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "identity": 9223372036854775807, "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [2, 3, 5, 9223372036854775807, 9223372036854775807, 9223372036854775807, 17, 19]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "identity": 9223372036854775807, "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [2, 9223372036854775807, 7, 13, 17, 23]}}]}, {"name": "awkward_reduce_argmin", "tests": [{"error": false, "inputs": {"fromptr": [0, 0, 4, 4, 6], "lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 6], "lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 1, 1, 2]}, "outputs": {"toptr": [0, 3, 5]}}, {"error": false, "inputs": {"fromptr": [1, 4, 2, 6, 3, 0, -10], "lenparents": 7, "outlength": 4, "parents": [0, 0, 0, 1, 1, 2, 3]}, "outputs": {"toptr": [0, 4, 5, 6]}}, {"error": false, "inputs": {"fromptr": [2, 1, 3, 4, 6, 6, -4, -6, -7], "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 4]}, "outputs": {"toptr": [1, -1, 3, 5, 8]}}, {"error": false, "inputs": {"fromptr": [2, 1, 3, -4, -6, -7], "lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 2, 2, 2]}, "outputs": {"toptr": [1, -1, 5]}}, {"error": false, "inputs": {"fromptr": [2, 1, 3, 2, 1], "lenparents": 5, "outlength": 3, "parents": [0, 0, 1, 2, 2]}, "outputs": {"toptr": [1, 2, 4]}}, {"error": false, "inputs": {"fromptr": [2, 2, 1, 0, 1, 0], "lenparents": 6, "outlength": 3, "parents": [0, 0, 1, 1, 1, 2]}, "outputs": {"toptr": [0, 3, 5]}}, {"error": false, "inputs": {"fromptr": [2, 0, 2, 1, 1, 0], "lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 1, 1, 2]}, "outputs": {"toptr": [1, 3, 5]}}, {"error": false, "inputs": {"fromptr": [3, -3, 4, 4, 2, 2, 2, 2, 2, -2, 1, 1, 6, -6, 1, 1, 4, 4, 1, 1, 3, -3, 3, 3, 4, 4, 6, 6, 6, -6], "lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [1, 6, 13, 18, 24, 2, 9, 14, 21, 26, 4, 10, 16, 22, 29]}}, {"error": false, "inputs": {"fromptr": [3, 1, 6, 1, 4, 4, 2, 1, 7, 2, 3, -1], "lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [1, 7, 11]}}, {"error": false, "inputs": {"fromptr": [-4, -6, -7, 6, 4, 6, 2, 1, 3], "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 2, 2, 4, 4, 4]}, "outputs": {"toptr": [2, 3, 4, -1, 7]}}, {"error": false, "inputs": {"fromptr": [-4, -6, -7, 6, -4, -6, -7, 2, 1, 3], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"toptr": [2, 3, 6, 8]}}, {"error": false, "inputs": {"fromptr": [3, 4, 2, 1, 2, 3, 6, 1, -1, 1, 7, 4], "lenparents": 12, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4]}, "outputs": {"toptr": [2, 3, 8, 9, 11]}}, {"error": false, "inputs": {"fromptr": [3, 4, 2, 2, 2, 1, 6, 1, 4, 1, 3, 3, 4, 6, 6], "lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [2, 5, 7, 9, 12]}}, {"error": false, "inputs": {"fromptr": [3, 4, 2, -3, 4, 2, 2, 2, 1, 2, -2, 1, 6, 1, 4, -6, 1, 4, 1, 3, 3, 1, -3, 3, 4, 6, 6, 4, 6, -6], "lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [2, 8, 13, 18, 24, 3, 10, 15, 22, 29]}}, {"error": false, "inputs": {"fromptr": [6, 3, 2, 1, 2], "lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [3]}}, {"error": false, "inputs": {"fromptr": [3, 2, 6, 1, 4, 4, 2, 1, 3, 6, 2, 1, 4, 3, 6, -3, 2, -6, 1, 4, 4, -2, 1, -3, 6, 2, 1, 4, 3, -6], "lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [3, 7, 11, 17, 23, 29]}}, {"error": false, "inputs": {"fromptr": [3, 2, 6, 1, 4, 4, 2, 1, 3, 6, 2, 1, 4, 3, 6], "lenparents": 15, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [3, 7, 11]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 999, 1, 1, 1, 1, 999, 1, 2, 2, 2, 2, 2, 2, 3, 3], "lenparents": 18, "outlength": 6, "parents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 2, 5]}, "outputs": {"toptr": [0, 10, 16, 5, 13, 17]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 999, 1, 1, 1, 1, 999, 1, 2, 2, 2, 999, 2, 2, 2, 3, 999, 999, 3, 999], "lenparents": 22, "outlength": 8, "parents": [0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 1, 1, 1, 5, 5, 5, 5, 2, 6, 6, 6, 7]}, "outputs": {"toptr": [0, 10, 17, -1, 5, 14, 20, 21]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 999, 1, 1, 1, 1, 999, 1, 2, 2, 2, 999, 2, 2, 2, 3, 999, 999, 3], "lenparents": 21, "outlength": 6, "parents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 4, 2, 5, 5, 5]}, "outputs": {"toptr": [0, 10, 17, 5, 14, 20]}}]}, {"name": "awkward_UnionArray_fillindex_count", "tests": [{"error": false, "inputs": {"length": 3, "toindexoffset": 4}, "outputs": {"toindex": [123, 123, 123, 123, 0, 1, 2]}}, {"error": false, "inputs": {"length": 2, "toindexoffset": 2}, "outputs": {"toindex": [123, 123, 0, 1]}}, {"error": false, "inputs": {"length": 2, "toindexoffset": 0}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 3, "toindexoffset": 6}, "outputs": {"toindex": [123, 123, 123, 123, 123, 123, 0, 1, 2]}}, {"error": false, "inputs": {"length": 3, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "toindexoffset": 9}, "outputs": {"toindex": [123, 123, 123, 123, 123, 123, 123, 123, 123, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 4, "toindexoffset": 5}, "outputs": {"toindex": [123, 123, 123, 123, 123, 0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 5, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2, 3, 4]}}]}, {"name": "awkward_UnionArray_simplify", "tests": [{"error": false, "inputs": {"base": 0, "innerindex": [0, 0, 1, 1, 2, 3, 2], "innertags": [0, 1, 0, 1, 0, 0, 1], "innerwhich": 0, "length": 12, "outerindex": [0, 1, 0, 1, 2, 2, 3, 4, 5, 3, 6, 4], "outertags": [0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0], "outerwhich": 1, "towhich": 1}, "outputs": {"toindex": [123, 123, 0, 123, 1, 123, 123, 2, 3, 123, 123, 123], "totags": [123, 123, 1, 123, 1, 123, 123, 1, 1, 123, 123, 123]}}, {"error": false, "inputs": {"base": 5, "innerindex": [0, 0, 1, 1, 2, 3, 2], "innertags": [0, 1, 0, 1, 0, 0, 1], "innerwhich": 1, "length": 12, "outerindex": [0, 1, 0, 1, 2, 2, 3, 4, 5, 3, 6, 4], "outertags": [0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0], "outerwhich": 1, "towhich": 0}, "outputs": {"toindex": [123, 123, 123, 5, 123, 123, 6, 123, 123, 123, 7, 123], "totags": [123, 123, 123, 0, 123, 123, 0, 123, 123, 123, 0, 123]}}]}]} +{"tests": {"reducer": [], "ListArray": [{"ListArray-starts": [2, 0, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], "ListArray-starts-offset": 0, "ListArray-stops": [3, 2, 4, 5, 3, 4, 2, 5, 3, 4, 6, 11], "ListArray-stops-offset": 0, "ListArray-length": 3, "ListArray-at": 0}, {"ListArray-starts": [1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1], "ListArray-starts-offset": 1, "ListArray-stops": [8, 4, 5, 6, 5, 5, 7], "ListArray-stops-offset": 1, "ListArray-length": 10, "ListArray-at": 5}, {"ListArray-starts": [1, 4, 5, 6, 5, 5, 7, 1, 2, 1, 3, 1, 5, 3, 2], "ListArray-starts-offset": 1, "ListArray-stops": [1, 4, 5, 6, 5, 5, 7, 1, 2, 1, 3, 1, 5, 3, 2], "ListArray-stops-offset": 1, "ListArray-length": 5, "ListArray-at": 0}, {"ListArray-starts": [1, 7, 6, 1, 3, 4, 2, 5, 2, 3, 1, 2, 3, 4, 5, 6, 7, 1, 2], "ListArray-starts-offset": 2, "ListArray-stops": [1, 9, 6, 2, 4, 5, 3, 6, 3, 4, 2, 4, 5, 5, 7, 8, 2, 3], "ListArray-stops-offset": 2, "ListArray-length": 3, "ListArray-at": 2}, {"ListArray-starts": [0, 0, 0, 0, 0, 0, 0, 0], "ListArray-starts-offset": 0, "ListArray-stops": [1, 1, 1, 1, 1, 1, 1, 1], "ListArray-stops-offset": 0, "ListArray-length": 6, "ListArray-at": 1}], "ListOffsetArray": [{"ListOffsetArray-offsets": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "ListOffsetArray-offsets-offset": 0, "ListOffsetArray-length": 5, "ListOffsetArray-rawoffsets": [[1, 2, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4], [2, 1, 0, 3, 1, 2, 0, 3, 1, 2, 2, 2, 1, 2, 3, 1, 0, 2, 3, 0, 2, 1]]}, {"ListOffsetArray-offsets": [2, 3, 3, 4, 5, 5, 5, 5, 5, 6, 7, 8, 10, 11], "ListOffsetArray-offsets-offset": 1, "ListOffsetArray-length": 1, "ListOffsetArray-rawoffsets": [[1, 1, 1, 2, 2, 2, 1, 3, 1, 2, 3, 4, 1, 2, 4, 1, 2, 3, 4], [0, 1, 3, 3, 1, 0, 0, 3, 1, 2, 2, 2, 1, 2]]}, {"ListOffsetArray-offsets": [2, 1, 0, 1, 2, 0, 1, 2, 2, 2, 1, 2, 1, 0, 0, 0, 0], "ListOffsetArray-offsets-offset": 1, "ListOffsetArray-length": 6, "ListOffsetArray-rawoffsets": [[3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4], [2, 1, 2, 3, 1, 0, 2, 3, 0, 2, 1]]}, {"ListOffsetArray-offsets": [1, 0, 2, 3, 1, 2, 0, 0, 1, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "ListOffsetArray-offsets-offset": 2, "ListOffsetArray-length": 3, "ListOffsetArray-rawoffsets": [[1, 2, 3, 2, 3, 1, 3, 3, 3, 2, 3, 1, 2, 3, 4, 1, 2], [2, 1, 2, 1, 2, 1, 2, 3, 1, 2, 3, 1, 3, 2, 3]]}, {"ListOffsetArray-offsets": [0, 0, 0, 0, 0, 0, 0, 0], "ListOffsetArray-offsets-offset": 0, "ListOffsetArray-length": 6, "ListOffsetArray-rawoffsets": [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]}], "Identities": [{"Identities-array": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], "Identities-array-offset": 0}, {"Identities-array": [0, 2, 1, 1, 1, 1, 2, 0, 1, 2, 0, 1, 0, 2, 0, 1, 1, 1, 0, 2, 2, 2, 1, 2, 0, 1], "Identities-array-offset": 1}, {"Identities-array": [1, 4, 3, 1, 2, 4, 5, 2, 3, 4, 1, 7, 5, 4, 2, 3, 1, 4, 2, 7, 8, 4, 3, 3, 4, 1, 5, 9, 7, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "Identities-array-offset": 2}, {"Identities-array": [1, 3, 2, 3, 1, 2, 5, 4, 3, 2, 1, 4, 3, 5, 1, 2, 3, 5, 1, 4, 2, 3, 2, 1, 2, 3, 5, 4, 3, 2, 1, 4, 2, 3, 1, 5, 2, 3, 4, 1, 5, 1, 2, 1, 1, 1], "Identities-array-offset": 3}, {"Identities-array": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "Identities-array-offset": 0}], "RegularArray": [{"RegularArray-size": 3}, {"RegularArray-size": 2}, {"RegularArray-size": 1}, {"RegularArray-size": 2}, {"RegularArray-size": 0}], "IndexedArray": [{"IndexedArray-index": [1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1], "IndexedArray-index-offset": 0, "IndexedArray-length": 2, "IndexedArray-parents": [1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1], "IndexedArray-parents-offset": 1}, {"IndexedArray-index": [1, 2, 2, 3, 0, 2, 0, 2, 1, 1], "IndexedArray-index-offset": 0, "IndexedArray-length": 1, "IndexedArray-parents": [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1], "IndexedArray-parents-offset": 0}, {"IndexedArray-index": [1, 3, 0, 3, 5, 2, 0, 2, 1, 1], "IndexedArray-index-offset": 0, "IndexedArray-length": 1, "IndexedArray-parents": [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0], "IndexedArray-parents-offset": 1}, {"IndexedArray-index": [1, 4, 2, 3, 1, 2, 3, 1, 4, 3, 2, 1, 3, 2, 4, 5, 1, 2, 3, 4, 5], "IndexedArray-index-offset": 1, "IndexedArray-length": 2, "IndexedArray-parents": [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1], "IndexedArray-parents-offset": 2}, {"IndexedArray-index": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "IndexedArray-index-offset": 0, "IndexedArray-length": 5, "IndexedArray-parents": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "IndexedArray-parents-offset": 0}], "UnionArray": [{"UnionArray-tags": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "UnionArray-tags-offset": 1, "UnionArray-which": 0, "UnionArray-length": 3}, {"UnionArray-tags": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "UnionArray-tags-offset": 0, "UnionArray-which": 1, "UnionArray-length": 2}, {"UnionArray-tags": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "UnionArray-tags-offset": 1, "UnionArray-which": 2, "UnionArray-length": 3}, {"UnionArray-tags": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "UnionArray-tags-offset": 2, "UnionArray-which": 1, "UnionArray-length": 3}, {"UnionArray-tags": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "UnionArray-tags-offset": 0, "UnionArray-which": 0, "UnionArray-length": 10}], "NumpyArray": [{"NumpyArray-ptr": [1, 2, 4, 2, 3, 1, 4, 2, 2, 2, 1, 4, 3], "NumpyArray-ptr-offset": 0, "NumpyArray-length": 5}, {"NumpyArray-ptr": [-1, 2, 4, 0, -3], "NumpyArray-ptr-offset": 1, "NumpyArray-length": 3}, {"NumpyArray-ptr": [-1, -3, 2, 1, -5, 7, 8, 9, 2, 3, 4, -1, -5, -3, -7, 5], "NumpyArray-ptr-offset": 2, "NumpyArray-length": 4}, {"NumpyArray-ptr": [1.1, -8.1, 3.1, 9.1, 4.1, 7.1, 9.1], "NumpyArray-ptr-offset": 1, "NumpyArray-length": 2}, {"NumpyArray-ptr": [0, 0, 0, 0, 0, 0, 0], "NumpyArray-ptr-offset": 0, "NumpyArray-length": 5}], "ByteMaskedArray": [{"ByteMaskedArray-mask": [1, 1, 1, 1, 1], "ByteMaskedArray-mask-offset": 0, "ByteMaskedArray-valid_when": true, "ByteMaskedArray-length": 0}, {"ByteMaskedArray-mask": [0, 0, 0, 0, 0], "ByteMaskedArray-mask-offset": 0, "ByteMaskedArray-valid_when": false, "ByteMaskedArray-length": 5}, {"ByteMaskedArray-mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "ByteMaskedArray-mask-offset": 1, "ByteMaskedArray-valid_when": true, "ByteMaskedArray-length": 7}, {"ByteMaskedArray-mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "ByteMaskedArray-mask-offset": 1, "ByteMaskedArray-valid_when": true, "ByteMaskedArray-length": 7}, {"ByteMaskedArray-mask": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "ByteMaskedArray-mask-offset": 0, "ByteMaskedArray-valid_when": true, "ByteMaskedArray-length": 7}], "BitMaskedArray": [{"BitMaskedArray-mask": [1, 1, 1, 1, 1], "BitMaskedArray-mask-offset": 0, "BitMaskedArray-valid_when": true, "BitMaskedArray-lsb_order": true}, {"BitMaskedArray-mask": [0, 0, 0, 0, 0], "BitMaskedArray-mask-offset": 0, "BitMaskedArray-valid_when": false, "BitMaskedArray-lsb_order": false}, {"BitMaskedArray-mask": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "BitMaskedArray-mask-offset": 1, "BitMaskedArray-valid_when": true, "BitMaskedArray-lsb_order": false}, {"BitMaskedArray-mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "BitMaskedArray-mask-offset": 2, "BitMaskedArray-valid_when": true, "BitMaskedArray-lsb_order": true}, {"BitMaskedArray-mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "BitMaskedArray-mask-offset": 0, "BitMaskedArray-valid_when": false, "BitMaskedArray-lsb_order": false}], "num": 3}, "unit-tests": [{"name": "awkward_missing_repeat", "tests": [{"error": false, "inputs": {"index": [0], "indexlength": 1, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0]}}, {"error": false, "inputs": {"index": [0, 1], "indexlength": 2, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1], "indexlength": 3, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1], "indexlength": 3, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1], "indexlength": 4, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1], "indexlength": 4, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 1], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 1], "indexlength": 5, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1, 2]}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2, 3], "indexlength": 6, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 1, 2, 3]}}, {"error": false, "inputs": {"index": [0, 1, 1, 2], "indexlength": 4, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 2]}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 1], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 2, 1]}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3], "indexlength": 5, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 2, 3]}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 4, 5], "indexlength": 7, "regularsize": 6, "repetitions": 1}, "outputs": {"outindex": [0, 1, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"index": [0, 1, 2, 1], "indexlength": 4, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 1]}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 1], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 3], "indexlength": 5, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 1, 3]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1], "indexlength": 5, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 3, 1]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1, 4, 5], "indexlength": 7, "regularsize": 6, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 3, 1, 4, 5]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 4, 5], "indexlength": 6, "regularsize": 6, "repetitions": 1}, "outputs": {"outindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"index": [1, 0], "indexlength": 2, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 0]}}, {"error": false, "inputs": {"index": [1, 0, 1], "indexlength": 3, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1], "indexlength": 3, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1], "indexlength": 4, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1], "indexlength": 4, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 1], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 1], "indexlength": 5, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 2], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 1, 2]}}, {"error": false, "inputs": {"index": [1, 0, 1, 2], "indexlength": 4, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 2]}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 1], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 2, 1]}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 3], "indexlength": 5, "regularsize": 4, "repetitions": 1}, "outputs": {"outindex": [1, 0, 1, 2, 3]}}, {"error": false, "inputs": {"index": [1, 1, 0], "indexlength": 3, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1], "indexlength": 4, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1], "indexlength": 4, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 1], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 1], "indexlength": 5, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 2], "indexlength": 5, "regularsize": 3, "repetitions": 1}, "outputs": {"outindex": [1, 1, 0, 1, 2]}}, {"error": false, "inputs": {"index": [1, 1, 1, 0], "indexlength": 4, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 0]}}, {"error": false, "inputs": {"index": [1, 1, 1, 0, 1], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 0, 1]}}, {"error": false, "inputs": {"index": [1, 1, 1, 0, 1], "indexlength": 5, "regularsize": 2, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 0, 1]}}, {"error": false, "inputs": {"index": [1], "indexlength": 1, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1]}}, {"error": false, "inputs": {"index": [1, 1, 1, 1, 0], "indexlength": 5, "regularsize": 1, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 1, 0]}}, {"error": false, "inputs": {"index": [1, 1, 1, 1, 1], "indexlength": 5, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1, 1, 1], "indexlength": 4, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1, 1], "indexlength": 3, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1, 1, 1]}}, {"error": false, "inputs": {"index": [1, 1], "indexlength": 2, "regularsize": 0, "repetitions": 1}, "outputs": {"outindex": [1, 1]}}]}, {"name": "awkward_index_rpad_and_clip_axis0", "tests": [{"error": false, "inputs": {"length": 2, "target": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 3, "target": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 3, "target": 3}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "target": 4}, "outputs": {"toindex": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 5, "target": 5}, "outputs": {"toindex": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 6, "target": 6}, "outputs": {"toindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 5, "target": 3}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"length": 6, "target": 3}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "target": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 3, "target": 1}, "outputs": {"toindex": [0]}}, {"error": false, "inputs": {"length": 5, "target": 1}, "outputs": {"toindex": [0]}}, {"error": false, "inputs": {"length": 6, "target": 1}, "outputs": {"toindex": [0]}}]}, {"name": "awkward_BitMaskedArray_to_ByteMaskedArray", "tests": [{"error": false, "inputs": {"bitmasklength": 2, "frombitmask": [58, 59], "lsb_order": false, "validwhen": false}, "outputs": {"tobytemask": [0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"bitmasklength": 1, "frombitmask": [66], "lsb_order": true, "validwhen": false}, "outputs": {"tobytemask": [0, 1, 0, 0, 0, 0, 1, 0]}}, {"error": false, "inputs": {"bitmasklength": 2, "frombitmask": [58, 59], "lsb_order": true, "validwhen": false}, "outputs": {"tobytemask": [0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0]}}]}, {"name": "awkward_ByteMaskedArray_getitem_nextcarry", "tests": [{"error": false, "inputs": {"length": 2, "mask": [0, 0], "validwhen": false}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"length": 5, "mask": [0, 0, 1, 1, 0], "validwhen": false}, "outputs": {"tocarry": [0, 1, 4]}}]}, {"name": "awkward_ByteMaskedArray_getitem_nextcarry_outindex", "tests": [{"error": false, "inputs": {"length": 1, "mask": [0], "validwhen": true}, "outputs": {"outindex": [-1], "tocarry": [123]}}, {"error": false, "inputs": {"length": 4, "mask": [0, 0, 0, 0], "validwhen": true}, "outputs": {"outindex": [-1, -1, -1, -1], "tocarry": [123, 123, 123, 123]}}]}, {"name": "awkward_ByteMaskedArray_numnull", "tests": [{"error": false, "inputs": {"length": 4, "mask": [0, 0, 0, 0], "validwhen": false}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"length": 2, "mask": [0, 0], "validwhen": false}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"length": 1, "mask": [0], "validwhen": false}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"length": 30, "mask": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], "validwhen": false}, "outputs": {"numnull": [10]}}, {"error": false, "inputs": {"length": 30, "mask": [0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0], "validwhen": false}, "outputs": {"numnull": [10]}}, {"error": false, "inputs": {"length": 30, "mask": [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0], "validwhen": false}, "outputs": {"numnull": [10]}}, {"error": false, "inputs": {"length": 4, "mask": [0, 1, 0, 0], "validwhen": false}, "outputs": {"numnull": [1]}}, {"error": false, "inputs": {"length": 1, "mask": [0], "validwhen": true}, "outputs": {"numnull": [1]}}, {"error": false, "inputs": {"length": 3, "mask": [0, 1, 1], "validwhen": true}, "outputs": {"numnull": [1]}}, {"error": false, "inputs": {"length": 6, "mask": [0, 0, 1, 1, 0, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 5, "mask": [0, 0, 1, 1, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 9, "mask": [0, 1, 0, 0, 0, 0, 1, 0, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 6, "mask": [0, 1, 0, 0, 1, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 3, "mask": [0, 1, 0], "validwhen": true}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 3, "mask": [1, 1, 0], "validwhen": false}, "outputs": {"numnull": [2]}}, {"error": false, "inputs": {"length": 8, "mask": [0, 1, 0, 0, 1, 0, 1, 0], "validwhen": false}, "outputs": {"numnull": [3]}}, {"error": false, "inputs": {"length": 10, "mask": [0, 1, 1, 0, 1, 0, 0, 1, 1, 0], "validwhen": true}, "outputs": {"numnull": [5]}}]}, {"name": "awkward_ByteMaskedArray_toIndexedOptionArray", "tests": [{"error": false, "inputs": {"length": 2, "mask": [0, 0], "validwhen": false}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 4, "mask": [0, 0, 0, 0], "validwhen": false}, "outputs": {"toindex": [0, 1, 2, 3]}}]}, {"name": "awkward_IndexedArray_flatten_nextcarry", "tests": [{"error": false, "inputs": {"fromindex": [0, 1], "lencontent": 2, "lenindex": 2}, "outputs": {"tocarry": [0, 1]}}]}, {"name": "awkward_IndexedArray_getitem_nextcarry", "tests": [{"error": false, "inputs": {"fromindex": [0, 0, 0, 0, 0, 0, 0], "lencontent": 1, "lenindex": 7}, "outputs": {"tocarry": [0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0, 0, 0, 0], "lencontent": 1, "lenindex": 6}, "outputs": {"tocarry": [0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0, 0, 0], "lencontent": 1, "lenindex": 5}, "outputs": {"tocarry": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0], "lencontent": 1, "lenindex": 3}, "outputs": {"tocarry": [0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0], "lencontent": 1, "lenindex": 2}, "outputs": {"tocarry": [0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0, 1, 1, 1, 2, 2, 2], "lencontent": 3, "lenindex": 9}, "outputs": {"tocarry": [0, 0, 0, 1, 1, 1, 2, 2, 2]}}, {"error": false, "inputs": {"fromindex": [0, 0, 0, 2, 3, 3, 4], "lencontent": 5, "lenindex": 7}, "outputs": {"tocarry": [0, 0, 0, 2, 3, 3, 4]}}, {"error": false, "inputs": {"fromindex": [0, 1], "lencontent": 2, "lenindex": 2}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2], "lencontent": 3, "lenindex": 3}, "outputs": {"tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3], "lencontent": 4, "lenindex": 4}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4], "lencontent": 5, "lenindex": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromindex": [1, 1, 1], "lencontent": 6, "lenindex": 3}, "outputs": {"tocarry": [1, 1, 1]}}, {"error": false, "inputs": {"fromindex": [1], "lencontent": 5, "lenindex": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"fromindex": [1], "lencontent": 6, "lenindex": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"fromindex": [1, 2], "lencontent": 3, "lenindex": 2}, "outputs": {"tocarry": [1, 2]}}, {"error": false, "inputs": {"fromindex": [1, 3], "lencontent": 6, "lenindex": 2}, "outputs": {"tocarry": [1, 3]}}, {"error": false, "inputs": {"fromindex": [2, 1, 0, 3, 3, 4], "lencontent": 5, "lenindex": 6}, "outputs": {"tocarry": [2, 1, 0, 3, 3, 4]}}, {"error": false, "inputs": {"fromindex": [2, 2, 1, 0], "lencontent": 3, "lenindex": 4}, "outputs": {"tocarry": [2, 2, 1, 0]}}, {"error": false, "inputs": {"fromindex": [2, 2, 1, 0, 3], "lencontent": 4, "lenindex": 5}, "outputs": {"tocarry": [2, 2, 1, 0, 3]}}, {"error": false, "inputs": {"fromindex": [2], "lencontent": 3, "lenindex": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"fromindex": [2], "lencontent": 5, "lenindex": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"fromindex": [2, 4, 4, 0, 8], "lencontent": 10, "lenindex": 5}, "outputs": {"tocarry": [2, 4, 4, 0, 8]}}, {"error": false, "inputs": {"fromindex": [3, 2, 1, 0], "lencontent": 4, "lenindex": 4}, "outputs": {"tocarry": [3, 2, 1, 0]}}, {"error": false, "inputs": {"fromindex": [4, 3, 2, 1, 0], "lencontent": 5, "lenindex": 5}, "outputs": {"tocarry": [4, 3, 2, 1, 0]}}, {"error": false, "inputs": {"fromindex": [4], "lencontent": 5, "lenindex": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"fromindex": [6, 4, 4, 8, 0], "lencontent": 10, "lenindex": 5}, "outputs": {"tocarry": [6, 4, 4, 8, 0]}}, {"error": false, "inputs": {"fromindex": [6, 5, 4, 3, 2, 1, 0], "lencontent": 7, "lenindex": 7}, "outputs": {"tocarry": [6, 5, 4, 3, 2, 1, 0]}}]}, {"name": "awkward_IndexedArray_getitem_nextcarry_outindex", "tests": [{"error": false, "inputs": {"fromindex": [0, 1, 2, 3], "lencontent": 4, "lenindex": 4}, "outputs": {"tocarry": [0, 1, 2, 3], "toindex": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromindex": [3, 2, 1, 0], "lencontent": 4, "lenindex": 4}, "outputs": {"tocarry": [3, 2, 1, 0], "toindex": [0, 1, 2, 3]}}]}, {"name": "awkward_IndexedArray_numnull", "tests": [{"error": false, "inputs": {"fromindex": [0, 1], "lenindex": 2}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3], "lenindex": 4}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4, 5, 6], "lenindex": 7}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [1, 2], "lenindex": 2}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [1, 2, 3], "lenindex": 3}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [1, 2, 3, 4], "lenindex": 4}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [2, 3], "lenindex": 2}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [2, 3, 4], "lenindex": 3}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [3, 2, 1, 0], "lenindex": 4}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [3, 4], "lenindex": 2}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [4, 3, 2, 1, 0], "lenindex": 5}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [5, 2, 4, 1, 3, 0], "lenindex": 6}, "outputs": {"numnull": [0]}}, {"error": false, "inputs": {"fromindex": [5, 4, 3, 2, 1, 0], "lenindex": 6}, "outputs": {"numnull": [0]}}]}, {"name": "awkward_ListArray_broadcast_tooffsets", "tests": [{"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16], "fromstarts": [0, 0, 0, 0, 0, 0, 4, 4, 4, 4], "fromstops": [2, 2, 2, 2, 2, 2, 5, 5, 5, 5], "lencontent": 5, "offsetslength": 11}, "outputs": {"tocarry": [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 4, 4, 4, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6, 8, 10], "fromstarts": [0, 0, 0, 3, 3], "fromstops": [2, 2, 2, 5, 5], "lencontent": 5, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 0, 1, 0, 1, 3, 4, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20], "fromstarts": [0, 0, 0, 3, 3, 5, 5, 5, 8, 8], "fromstops": [2, 2, 2, 5, 5, 7, 7, 7, 10, 10], "lencontent": 10, "offsetslength": 11}, "outputs": {"tocarry": [0, 1, 0, 1, 0, 1, 3, 4, 3, 4, 5, 6, 5, 6, 5, 6, 8, 9, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15, 18, 21], "fromstarts": [0, 0, 0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3, 3, 3], "lencontent": 3, "offsetslength": 8}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15, 18], "fromstarts": [0, 0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3, 3], "lencontent": 3, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15], "fromstarts": [0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3], "lencontent": 3, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9], "fromstarts": [0, 0, 0], "fromstops": [3, 3, 3], "lencontent": 3, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6], "fromstarts": [0, 0], "fromstops": [3, 3], "lencontent": 3, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3], "fromstarts": [0, 3], "fromstops": [3, 3], "lencontent": 20, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 8, 13, 18, 23, 28], "fromstarts": [0, 13, 3, 18, 8, 23], "fromstops": [3, 18, 8, 23, 13, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 13, 14, 15, 16, 17, 3, 4, 5, 6, 7, 18, 19, 20, 21, 22, 8, 9, 10, 11, 12, 23, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4], "fromstarts": [0, 2], "fromstops": [2, 4], "lencontent": 4, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 9, 13, 18, 23, 28], "fromstarts": [0, 13, 4, 18, 8, 23], "fromstops": [4, 18, 8, 23, 13, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 13, 14, 15, 16, 17, 4, 5, 6, 7, 18, 19, 20, 21, 22, 8, 9, 10, 11, 12, 23, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 9, 14, 19, 24, 29], "fromstarts": [0, 14, 4, 19, 9, 24], "fromstops": [4, 19, 9, 24, 14, 29], "lencontent": 29, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 14, 15, 16, 17, 18, 4, 5, 6, 7, 8, 19, 20, 21, 22, 23, 9, 10, 11, 12, 13, 24, 25, 26, 27, 28]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 18, 21, 24, 29], "fromstarts": [0, 0, 0, 8, 11, 11, 14], "fromstops": [5, 5, 5, 11, 14, 14, 19], "lencontent": 19, "offsetslength": 8}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 11, 12, 13, 14, 15, 16, 17, 18]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 4, 5], "fromstarts": [0, 3, 3, 4], "fromstops": [3, 3, 4, 5], "lencontent": 5, "offsetslength": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5], "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "lencontent": 10, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5], "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "lencontent": 5, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 5, 8], "fromstarts": [0, 3, 3, 10, 10], "fromstops": [3, 3, 5, 10, 13], "lencontent": 13, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 10, 11, 12]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20], "fromstarts": [0, 10, 15, 25], "fromstops": [5, 15, 20, 30], "lencontent": 30, "offsetslength": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 11, 12, 17, 22], "fromstarts": [0, 11, 5, 16, 6, 17], "fromstops": [5, 16, 6, 17, 11, 22], "lencontent": 22, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 11, 12, 13, 14, 15, 5, 16, 6, 7, 8, 9, 10, 17, 18, 19, 20, 21]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 14, 18, 23, 28], "fromstarts": [0, 14, 5, 19, 9, 23], "fromstops": [5, 19, 9, 23, 14, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 14, 15, 16, 17, 18, 5, 6, 7, 8, 19, 20, 21, 22, 9, 10, 11, 12, 13, 23, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 24, 28], "fromstarts": [0, 14, 5, 19, 10, 24], "fromstops": [5, 19, 10, 24, 14, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 14, 15, 16, 17, 18, 5, 6, 7, 8, 9, 19, 20, 21, 22, 23, 10, 11, 12, 13, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 6, 10], "fromstarts": [0, 3, 3, 15, 16], "fromstops": [3, 3, 5, 16, 20], "lencontent": 20, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20], "fromstarts": [0, 15, 10, 25], "fromstops": [5, 20, 15, 30], "lencontent": 30, "offsetslength": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 19, 24, 28], "fromstarts": [0, 15, 5, 20, 10, 24], "fromstops": [5, 20, 10, 24, 15, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 10, 11, 12, 13, 14, 24, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 28], "fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 28], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 25, 26, 27]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 29], "fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 29], "lencontent": 29, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 25, 26, 27, 28]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 30], "lencontent": 30, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [0, 45, 5, 50, 10, 55], "fromstops": [5, 50, 10, 55, 15, 60], "lencontent": 60, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 45, 46, 47, 48, 49, 5, 6, 7, 8, 9, 50, 51, 52, 53, 54, 10, 11, 12, 13, 14, 55, 56, 57, 58, 59]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6], "fromstarts": [0, 3], "fromstops": [3, 6], "lencontent": 25, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6], "fromstarts": [0, 3], "fromstops": [3, 6], "lencontent": 6, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 10, 14, 17], "fromstarts": [0, 3, 10, 14, 18], "fromstops": [3, 6, 14, 18, 21], "lencontent": 21, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15], "fromstarts": [0, 3, 11, 14, 17], "fromstops": [3, 6, 14, 17, 20], "lencontent": 20, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 15], "fromstarts": [0, 3, 11, 14, 17], "fromstops": [3, 6, 14, 17, 20], "lencontent": 25, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 10, 14, 17], "fromstarts": [0, 3, 11, 15, 19], "fromstops": [3, 6, 15, 19, 22], "lencontent": 22, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 4, 6, 7], "fromstarts": [0, 3, 3, 4, 6], "fromstops": [3, 3, 4, 6, 7], "lencontent": 7, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 7], "fromstarts": [0, 3, 3], "fromstops": [3, 3, 7], "lencontent": 7, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 7], "fromstarts": [0, 3], "fromstops": [3, 7], "lencontent": 7, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 6, 10], "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 10], "lencontent": 10, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 8, 8, 10], "fromstarts": [0, 3, 3, 5, 8, 8], "fromstops": [3, 3, 5, 8, 8, 10], "lencontent": 10, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10], "fromstarts": [0, 5], "fromstops": [5, 10], "lencontent": 10, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 7, 7, 9, 9, 11], "fromstarts": [0, 4, 7, 7, 9, 9], "fromstops": [4, 7, 7, 9, 9, 11], "lencontent": 11, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 8, 12, 16, 19], "fromstarts": [0, 3, 8, 12, 16], "fromstops": [3, 8, 12, 16, 19], "lencontent": 19, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 11, 15, 19, 22], "fromstarts": [0, 3, 6, 11, 15, 19], "fromstops": [3, 6, 11, 15, 19, 22], "lencontent": 22, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [0, 5, 10, 15, 20, 25], "fromstops": [5, 10, 15, 20, 25, 30], "lencontent": 30, "offsetslength": 7}, "outputs": {"tocarry": [0, 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]}}, {"error": false, "inputs": {"fromoffsets": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210], "fromstarts": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203], "fromstops": [7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210], "lencontent": 210, "offsetslength": 31}, "outputs": {"tocarry": [0, 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, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [0, 5, 10, 45, 50, 55], "fromstops": [5, 10, 15, 50, 55, 60], "lencontent": 60, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 11, 15, 19, 22], "fromstarts": [0, 3, 8, 13, 17, 21], "fromstops": [3, 6, 13, 17, 21, 24], "lencontent": 24, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 8, 11, 14, 19], "fromstarts": [0, 8, 11, 11, 14], "fromstops": [5, 11, 14, 14, 19], "lencontent": 19, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 11, 12, 13, 14, 15, 16, 17, 18]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 8, 9], "fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lencontent": 10, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 5, 6, 7, 7, 9], "fromstarts": [0, 4, 6, 3, 6, 7], "fromstops": [3, 6, 7, 4, 6, 9], "lencontent": 9, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 3, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 5, 6, 7, 9], "fromstarts": [0, 4, 6, 3, 7], "fromstops": [3, 6, 7, 4, 9], "lencontent": 9, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 3, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 3, 4, 5, 6, 8], "fromstarts": [0, 2, 4, 5, 6, 9], "fromstops": [2, 3, 5, 6, 7, 11], "lencontent": 11, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 9, 10]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5, 6, 8], "fromstarts": [0, 4, 4, 6, 9], "fromstops": [3, 4, 6, 7, 11], "lencontent": 11, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 9, 10]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5], "fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "lencontent": 7, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 7], "fromstarts": [0, 3, 5], "fromstops": [3, 3, 9], "lencontent": 9, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 7], "fromstarts": [0, 5], "fromstops": [3, 9], "lencontent": 9, "offsetslength": 3}, "outputs": {"tocarry": [0, 1, 2, 5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 5, 7, 8, 9, 10], "fromstarts": [0, 6, 3, 8, 5, 9], "fromstops": [3, 8, 5, 9, 6, 10], "lencontent": 10, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 6, 7, 3, 4, 8, 5, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 5, 5, 6, 8, 9], "fromstarts": [0, 6, 3, 8, 3, 5], "fromstops": [3, 8, 3, 9, 5, 6], "lencontent": 9, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 2, 6, 7, 8, 3, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 7], "fromstarts": [0, 3, 6], "fromstops": [3, 3, 10], "lencontent": 10, "offsetslength": 4}, "outputs": {"tocarry": [0, 1, 2, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 5, 6, 6, 6], "fromstarts": [0, 3, 2, 5, 3, 6], "fromstops": [2, 5, 3, 6, 3, 6], "lencontent": 6, "offsetslength": 7}, "outputs": {"tocarry": [0, 1, 3, 4, 2, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 2, 4, 5, 6], "fromstarts": [0, 3, 3, 5, 8], "fromstops": [2, 3, 5, 6, 9], "lencontent": 9, "offsetslength": 6}, "outputs": {"tocarry": [0, 1, 3, 4, 5, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9], "fromstarts": [11, 14, 17], "fromstops": [14, 17, 20], "lencontent": 25, "offsetslength": 4}, "outputs": {"tocarry": [11, 12, 13, 14, 15, 16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [1, 16, 6, 21, 11, 26], "fromstops": [6, 21, 11, 26, 16, 31], "lencontent": 31, "offsetslength": 7}, "outputs": {"tocarry": [1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 6, 7, 8, 9, 10, 21, 22, 23, 24, 25, 11, 12, 13, 14, 15, 26, 27, 28, 29, 30]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 3, 5], "fromstarts": [1, 99, 5], "fromstops": [4, 99, 7], "lencontent": 7, "offsetslength": 4}, "outputs": {"tocarry": [1, 2, 3, 5, 6]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20], "fromstarts": [15, 10, 5, 0], "fromstops": [20, 15, 10, 5], "lencontent": 20, "offsetslength": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20], "fromstarts": [15, 5, 10, 0], "fromstops": [20, 10, 15, 5], "lencontent": 20, "offsetslength": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 4], "fromstarts": [16], "fromstops": [20], "lencontent": 20, "offsetslength": 2}, "outputs": {"tocarry": [16, 17, 18, 19]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 1, 3], "fromstarts": [2, 2, 3], "fromstops": [2, 3, 5], "lencontent": 5, "offsetslength": 4}, "outputs": {"tocarry": [2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 2, 3], "fromstarts": [2, 4, 5], "fromstops": [3, 5, 6], "lencontent": 6, "offsetslength": 4}, "outputs": {"tocarry": [2, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [25, 10, 20, 5, 15, 0], "fromstops": [30, 15, 25, 10, 20, 5], "lencontent": 30, "offsetslength": 7}, "outputs": {"tocarry": [25, 26, 27, 28, 29, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 5, 6, 7, 8, 9, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10, 15, 20, 25, 30], "fromstarts": [25, 20, 15, 10, 5, 0], "fromstops": [30, 25, 20, 15, 10, 5], "lencontent": 30, "offsetslength": 7}, "outputs": {"tocarry": [25, 26, 27, 28, 29, 20, 21, 22, 23, 24, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 2, 2, 5, 7], "fromstarts": [3, 3, 3, 0, 4], "fromstops": [4, 4, 3, 3, 6], "lencontent": 6, "offsetslength": 6}, "outputs": {"tocarry": [3, 3, 0, 1, 2, 4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 2, 5, 6, 7, 11], "fromstarts": [3, 3, 0, 5, 5, 6], "fromstops": [5, 3, 3, 6, 6, 10], "lencontent": 10, "offsetslength": 7}, "outputs": {"tocarry": [3, 4, 0, 1, 2, 5, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 3], "fromstarts": [3, 15], "fromstops": [5, 16], "lencontent": 20, "offsetslength": 3}, "outputs": {"tocarry": [3, 4, 15]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 4, 7], "fromstarts": [3, 3, 3, 0], "fromstops": [5, 5, 3, 3], "lencontent": 5, "offsetslength": 5}, "outputs": {"tocarry": [3, 4, 3, 4, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 7, 7, 9, 9, 11], "fromstarts": [3, 0, 999, 2, 6, 10], "fromstops": [7, 3, 999, 4, 6, 12], "lencontent": 12, "offsetslength": 7}, "outputs": {"tocarry": [3, 4, 5, 6, 0, 1, 2, 2, 3, 10, 11]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 2, 2, 2, 6], "fromstarts": [3, 5, 5, 5, 5], "fromstops": [5, 5, 5, 5, 9], "lencontent": 9, "offsetslength": 6}, "outputs": {"tocarry": [3, 4, 5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 6, 9, 12, 14, 16], "fromstarts": [3, 6, 17, 20, 11, 25], "fromstops": [6, 9, 20, 23, 13, 27], "lencontent": 28, "offsetslength": 7}, "outputs": {"tocarry": [3, 4, 5, 6, 7, 8, 17, 18, 19, 20, 21, 22, 11, 12, 25, 26]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 8, 12, 16, 19], "fromstarts": [3, 6, 11, 15, 19], "fromstops": [6, 11, 15, 19, 22], "lencontent": 22, "offsetslength": 6}, "outputs": {"tocarry": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 2, 6], "fromstarts": [3, 3, 6], "fromstops": [3, 5, 10], "lencontent": 10, "offsetslength": 4}, "outputs": {"tocarry": [3, 4, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 6], "fromstarts": [3, 6], "fromstops": [5, 10], "lencontent": 10, "offsetslength": 3}, "outputs": {"tocarry": [3, 4, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 2], "fromstarts": [4, 4], "fromstops": [4, 6], "lencontent": 6, "offsetslength": 3}, "outputs": {"tocarry": [4, 5]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 2, 7], "fromstarts": [4, 4, 7], "fromstops": [4, 6, 12], "lencontent": 12, "offsetslength": 4}, "outputs": {"tocarry": [4, 5, 7, 8, 9, 10, 11]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 2, 5, 5, 7, 7, 11], "fromstarts": [5, 5, 0, 3, 3, 6, 6], "fromstops": [6, 6, 3, 3, 5, 6, 10], "lencontent": 10, "offsetslength": 8}, "outputs": {"tocarry": [5, 5, 0, 1, 2, 3, 4, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 0, 1, 4], "fromstarts": [5, 5, 6], "fromstops": [5, 6, 9], "lencontent": 9, "offsetslength": 4}, "outputs": {"tocarry": [5, 6, 7, 8]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 1, 5], "fromstarts": [5, 6, 6], "fromstops": [6, 6, 10], "lencontent": 10, "offsetslength": 4}, "outputs": {"tocarry": [5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 5], "fromstarts": [5, 6], "fromstops": [6, 10], "lencontent": 10, "offsetslength": 3}, "outputs": {"tocarry": [5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 4, 6, 6, 9], "fromstarts": [6, 5, 3, 3, 0], "fromstops": [9, 6, 5, 3, 3], "lencontent": 9, "offsetslength": 6}, "outputs": {"tocarry": [6, 7, 8, 5, 3, 4, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 3, 4, 7, 10], "fromstarts": [6, 5, 6, 0], "fromstops": [9, 6, 9, 3], "lencontent": 9, "offsetslength": 5}, "outputs": {"tocarry": [6, 7, 8, 5, 6, 7, 8, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 1, 1, 6], "fromstarts": [6, 7, 7], "fromstops": [7, 7, 12], "lencontent": 12, "offsetslength": 4}, "outputs": {"tocarry": [6, 7, 8, 9, 10, 11]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 8, 11, 14, 19], "fromstarts": [6, 11, 14, 17, 20], "fromstops": [11, 14, 17, 20, 25], "lencontent": 25, "offsetslength": 6}, "outputs": {"tocarry": [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 5, 7, 10], "fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lencontent": 10, "offsetslength": 5}, "outputs": {"tocarry": [6, 7, 8, 9, 5, 3, 4, 0, 1, 2]}}, {"error": false, "inputs": {"fromoffsets": [0, 4, 5, 7, 7, 10], "fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lencontent": 10, "offsetslength": 6}, "outputs": {"tocarry": [6, 7, 8, 9, 5, 3, 4, 0, 1, 2]}}]}, {"name": "awkward_ListArray_compact_offsets", "tests": [{"error": false, "inputs": {"fromstarts": [2, 2, 3], "fromstops": [2, 3, 5], "length": 3}, "outputs": {"tooffsets": [0, 0, 1, 3]}}, {"error": false, "inputs": {"fromstarts": [5, 5, 6], "fromstops": [5, 6, 9], "length": 3}, "outputs": {"tooffsets": [0, 0, 1, 4]}}, {"error": false, "inputs": {"fromstarts": [4, 4], "fromstops": [4, 6], "length": 2}, "outputs": {"tooffsets": [0, 0, 2]}}, {"error": false, "inputs": {"fromstarts": [3, 3, 6], "fromstops": [3, 5, 10], "length": 3}, "outputs": {"tooffsets": [0, 0, 2, 6]}}, {"error": false, "inputs": {"fromstarts": [4, 4, 7], "fromstops": [4, 6, 12], "length": 3}, "outputs": {"tooffsets": [0, 0, 2, 7]}}, {"error": false, "inputs": {"fromstarts": [5, 6, 6], "fromstops": [6, 6, 10], "length": 3}, "outputs": {"tooffsets": [0, 1, 1, 5]}}, {"error": false, "inputs": {"fromstarts": [6, 7, 7], "fromstops": [7, 7, 12], "length": 3}, "outputs": {"tooffsets": [0, 1, 1, 6]}}, {"error": false, "inputs": {"fromstarts": [3, 3, 3, 0, 4], "fromstops": [4, 4, 3, 3, 6], "length": 5}, "outputs": {"tooffsets": [0, 1, 2, 2, 5, 7]}}, {"error": false, "inputs": {"fromstarts": [2, 4, 5], "fromstops": [3, 5, 6], "length": 3}, "outputs": {"tooffsets": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromstarts": [5, 5, 0, 3, 3, 6, 6], "fromstops": [6, 6, 3, 3, 5, 6, 10], "length": 7}, "outputs": {"tooffsets": [0, 1, 2, 5, 5, 7, 7, 11]}}, {"error": false, "inputs": {"fromstarts": [3, 5, 5, 5, 5], "fromstops": [5, 5, 5, 5, 9], "length": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 2, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 5, 8], "fromstops": [2, 3, 5, 6, 9], "length": 5}, "outputs": {"tooffsets": [0, 2, 2, 4, 5, 6]}}, {"error": false, "inputs": {"fromstarts": [3, 3, 0, 5, 5, 6], "fromstops": [5, 3, 3, 6, 6, 10], "length": 6}, "outputs": {"tooffsets": [0, 2, 2, 5, 6, 7, 11]}}, {"error": false, "inputs": {"fromstarts": [3, 15], "fromstops": [5, 16], "length": 2}, "outputs": {"tooffsets": [0, 2, 3]}}, {"error": false, "inputs": {"fromstarts": [0, 2, 4, 5, 6, 9], "fromstops": [2, 3, 5, 6, 7, 11], "length": 6}, "outputs": {"tooffsets": [0, 2, 3, 4, 5, 6, 8]}}, {"error": false, "inputs": {"fromstarts": [0, 2], "fromstops": [2, 4], "length": 2}, "outputs": {"tooffsets": [0, 2, 4]}}, {"error": false, "inputs": {"fromstarts": [3, 3, 3, 0], "fromstops": [5, 5, 3, 3], "length": 4}, "outputs": {"tooffsets": [0, 2, 4, 4, 7]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 2, 5, 3, 6], "fromstops": [2, 5, 3, 6, 3, 6], "length": 6}, "outputs": {"tooffsets": [0, 2, 4, 5, 6, 6, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 3, 3], "fromstops": [2, 2, 2, 5, 5], "length": 5}, "outputs": {"tooffsets": [0, 2, 4, 6, 8, 10]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 0, 0, 0, 4, 4, 4, 4], "fromstops": [2, 2, 2, 2, 2, 2, 5, 5, 5, 5], "length": 10}, "outputs": {"tooffsets": [0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 3, 3, 5, 5, 5, 8, 8], "fromstops": [2, 2, 2, 5, 5, 7, 7, 7, 10, 10], "length": 10}, "outputs": {"tooffsets": [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]}}, {"error": false, "inputs": {"fromstarts": [3, 6], "fromstops": [5, 10], "length": 2}, "outputs": {"tooffsets": [0, 2, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 3], "fromstops": [3, 3], "length": 2}, "outputs": {"tooffsets": [0, 3, 3]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 4], "fromstops": [3, 3, 4, 5], "length": 4}, "outputs": {"tooffsets": [0, 3, 3, 4, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"fromstarts": [1, 99, 5], "fromstops": [4, 99, 7], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 10, 10], "fromstops": [3, 3, 5, 10, 13], "length": 5}, "outputs": {"tooffsets": [0, 3, 3, 5, 5, 8]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 15, 16], "fromstops": [3, 3, 5, 16, 20], "length": 5}, "outputs": {"tooffsets": [0, 3, 3, 5, 6, 10]}}, {"error": false, "inputs": {"fromstarts": [0, 4, 4, 6, 9], "fromstops": [3, 4, 6, 7, 11], "length": 5}, "outputs": {"tooffsets": [0, 3, 3, 5, 6, 8]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5}, "outputs": {"tooffsets": [0, 3, 3, 5, 8, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 9], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 7]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 6], "fromstops": [3, 3, 10], "length": 3}, "outputs": {"tooffsets": [0, 3, 3, 7]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [9, 6, 5, 3, 3], "length": 5}, "outputs": {"tooffsets": [0, 3, 4, 6, 6, 9]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 6, 0], "fromstops": [9, 6, 9, 3], "length": 4}, "outputs": {"tooffsets": [0, 3, 4, 7, 10]}}, {"error": false, "inputs": {"fromstarts": [0, 6, 3, 8, 3, 5], "fromstops": [3, 8, 3, 9, 5, 6], "length": 6}, "outputs": {"tooffsets": [0, 3, 5, 5, 6, 8, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 4, 6, 3, 6, 7], "fromstops": [3, 6, 7, 4, 6, 9], "length": 6}, "outputs": {"tooffsets": [0, 3, 5, 6, 7, 7, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 4, 6, 3, 7], "fromstops": [3, 6, 7, 4, 9], "length": 5}, "outputs": {"tooffsets": [0, 3, 5, 6, 7, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 6, 3, 8, 5, 9], "fromstops": [3, 8, 5, 9, 6, 10], "length": 6}, "outputs": {"tooffsets": [0, 3, 5, 7, 8, 9, 10]}}, {"error": false, "inputs": {"fromstarts": [0, 0], "fromstops": [3, 3], "length": 2}, "outputs": {"tooffsets": [0, 3, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 3], "fromstops": [3, 6], "length": 2}, "outputs": {"tooffsets": [0, 3, 6]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 10, 14, 18], "fromstops": [3, 6, 14, 18, 21], "length": 5}, "outputs": {"tooffsets": [0, 3, 6, 10, 14, 17]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 6, 11, 15, 19], "fromstops": [3, 6, 11, 15, 19, 22], "length": 6}, "outputs": {"tooffsets": [0, 3, 6, 11, 15, 19, 22]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0], "fromstops": [3, 3, 3], "length": 3}, "outputs": {"tooffsets": [0, 3, 6, 9]}}, {"error": false, "inputs": {"fromstarts": [3, 6, 17, 20, 11, 25], "fromstops": [6, 9, 20, 23, 13, 27], "length": 6}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 14, 16]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3], "length": 5}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 11, 14, 17], "fromstops": [3, 6, 14, 17, 20], "length": 5}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3, 3], "length": 6}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 15, 18]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 0, 0, 0, 0], "fromstops": [3, 3, 3, 3, 3, 3, 3], "length": 7}, "outputs": {"tooffsets": [0, 3, 6, 9, 12, 15, 18, 21]}}, {"error": false, "inputs": {"fromstarts": [0, 5], "fromstops": [3, 9], "length": 2}, "outputs": {"tooffsets": [0, 3, 7]}}, {"error": false, "inputs": {"fromstarts": [3, 6, 11, 15, 19], "fromstops": [6, 11, 15, 19, 22], "length": 5}, "outputs": {"tooffsets": [0, 3, 8, 12, 16, 19]}}, {"error": false, "inputs": {"fromstarts": [0, 13, 3, 18, 8, 23], "fromstops": [3, 18, 8, 23, 13, 28], "length": 6}, "outputs": {"tooffsets": [0, 3, 8, 13, 18, 23, 28]}}, {"error": false, "inputs": {"fromstarts": [16], "fromstops": [20], "length": 1}, "outputs": {"tooffsets": [0, 4]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "length": 4}, "outputs": {"tooffsets": [0, 4, 5, 7, 10]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "length": 5}, "outputs": {"tooffsets": [0, 4, 5, 7, 7, 10]}}, {"error": false, "inputs": {"fromstarts": [3, 0, 999, 2, 6, 10], "fromstops": [7, 3, 999, 4, 6, 12], "length": 6}, "outputs": {"tooffsets": [0, 4, 7, 7, 9, 9, 11]}}, {"error": false, "inputs": {"fromstarts": [0, 13, 4, 18, 8, 23], "fromstops": [4, 18, 8, 23, 13, 28], "length": 6}, "outputs": {"tooffsets": [0, 4, 9, 13, 18, 23, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 14, 4, 19, 9, 24], "fromstops": [4, 19, 9, 24, 14, 29], "length": 6}, "outputs": {"tooffsets": [0, 4, 9, 14, 19, 24, 29]}}, {"error": false, "inputs": {"fromstarts": [0, 11, 5, 16, 6, 17], "fromstops": [5, 16, 6, 17, 11, 22], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 11, 12, 17, 22]}}, {"error": false, "inputs": {"fromstarts": [0, 14, 5, 19, 9, 23], "fromstops": [5, 19, 9, 23, 14, 28], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 14, 18, 23, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 0, 0, 8, 11, 11, 14], "fromstops": [5, 5, 5, 11, 14, 14, 19], "length": 7}, "outputs": {"tooffsets": [0, 5, 10, 15, 18, 21, 24, 29]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 5, 20, 10, 24], "fromstops": [5, 20, 10, 24, 15, 28], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 19, 24, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 10, 15, 25], "fromstops": [5, 15, 20, 30], "length": 4}, "outputs": {"tooffsets": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 10, 25], "fromstops": [5, 20, 15, 30], "length": 4}, "outputs": {"tooffsets": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"fromstarts": [15, 10, 5, 0], "fromstops": [20, 15, 10, 5], "length": 4}, "outputs": {"tooffsets": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"fromstarts": [15, 5, 10, 0], "fromstops": [20, 10, 15, 5], "length": 4}, "outputs": {"tooffsets": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"fromstarts": [0, 14, 5, 19, 10, 24], "fromstops": [5, 19, 10, 24, 14, 28], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 24, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 28], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 28]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 29], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 29]}}, {"error": false, "inputs": {"fromstarts": [0, 15, 5, 20, 10, 25], "fromstops": [5, 20, 10, 25, 15, 30], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [0, 45, 5, 50, 10, 55], "fromstops": [5, 50, 10, 55, 15, 60], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [0, 5, 10, 15, 20, 25], "fromstops": [5, 10, 15, 20, 25, 30], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [0, 5, 10, 45, 50, 55], "fromstops": [5, 10, 15, 50, 55, 60], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [1, 16, 6, 21, 11, 26], "fromstops": [6, 21, 11, 26, 16, 31], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [25, 10, 20, 5, 15, 0], "fromstops": [30, 15, 25, 10, 20, 5], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [25, 20, 15, 10, 5, 0], "fromstops": [30, 25, 20, 15, 10, 5], "length": 6}, "outputs": {"tooffsets": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"fromstarts": [0, 8, 11, 11, 14], "fromstops": [5, 11, 14, 14, 19], "length": 5}, "outputs": {"tooffsets": [0, 5, 8, 11, 14, 19]}}, {"error": false, "inputs": {"fromstarts": [6, 11, 14, 17, 20], "fromstops": [11, 14, 17, 20, 25], "length": 5}, "outputs": {"tooffsets": [0, 5, 8, 11, 14, 19]}}, {"error": false, "inputs": {"fromstarts": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203], "fromstops": [7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210], "length": 30}, "outputs": {"tooffsets": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210]}}]}, {"name": "awkward_RegularArray_localindex", "tests": [{"error": false, "inputs": {"length": 2, "size": 3}, "outputs": {"toindex": [0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"length": 6, "size": 5}, "outputs": {"toindex": [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]}}]}, {"name": "awkward_RegularArray_rpad_and_clip_axis1", "tests": [{"error": false, "inputs": {"length": 3, "size": 2, "target": 2}, "outputs": {"toindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 2, "size": 3, "target": 3}, "outputs": {"toindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 3, "size": 3, "target": 3}, "outputs": {"toindex": [0, 1, 2, 3, 4, 5, 6, 7, 8]}}, {"error": false, "inputs": {"length": 3, "size": 3, "target": 2}, "outputs": {"toindex": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"length": 6, "size": 5, "target": 2}, "outputs": {"toindex": [0, 1, 5, 6, 10, 11, 15, 16, 20, 21, 25, 26]}}, {"error": false, "inputs": {"length": 3, "size": 2, "target": 1}, "outputs": {"toindex": [0, 2, 4]}}, {"error": false, "inputs": {"length": 3, "size": 3, "target": 1}, "outputs": {"toindex": [0, 3, 6]}}]}, {"name": "awkward_RegularArray_getitem_carry", "tests": [{"error": false, "inputs": {"fromcarry": [0, 0], "lencarry": 2, "size": 1}, "outputs": {"tocarry": [0, 0]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 0, 1, 1, 1], "lencarry": 6, "size": 1}, "outputs": {"tocarry": [0, 0, 0, 1, 1, 1]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 0, 2, 2], "lencarry": 5, "size": 1}, "outputs": {"tocarry": [0, 0, 0, 2, 2]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 1, 1, 2, 2, 3, 3, 4, 4], "lencarry": 10, "size": 1}, "outputs": {"tocarry": [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 0, 1, 0, 1, 3, 4, 3, 4], "lencarry": 10, "size": 1}, "outputs": {"tocarry": [0, 1, 0, 1, 0, 1, 3, 4, 3, 4]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 1, 1], "lencarry": 4, "size": 2}, "outputs": {"tocarry": [0, 1, 0, 1, 2, 3, 2, 3]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 0, 0], "lencarry": 4, "size": 3}, "outputs": {"tocarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 1, 2], "lencarry": 4, "size": 2}, "outputs": {"tocarry": [0, 1, 2, 3, 2, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [0, 0], "lencarry": 2, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromcarry": [0, 0, 0, 1, 1, 1], "lencarry": 6, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromcarry": [0, 2, 3, 5], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [0, 2, 4], "lencarry": 3, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromcarry": [0, 3, 6, 9], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 30, 31, 32, 33, 34, 45, 46, 47, 48, 49]}}, {"error": false, "inputs": {"fromcarry": [0, 3, 1, 4, 2, 5], "lencarry": 6, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 10, 11, 12, 13, 14, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [0, 4, 8, 10], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44, 50, 51, 52, 53, 54]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 1, 1], "lencarry": 4, "size": 3}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2], "lencarry": 12, "size": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"fromcarry": [0, 1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5], "lencarry": 12, "size": 5}, "outputs": {"tocarry": [0, 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, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [2, 0, 0, 1], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromcarry": [2, 2, 2, 2], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [10, 11, 12, 13, 14, 10, 11, 12, 13, 14, 10, 11, 12, 13, 14, 10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"fromcarry": [2], "lencarry": 1, "size": 5}, "outputs": {"tocarry": [10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"fromcarry": [2, 5, 8, 11], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [10, 11, 12, 13, 14, 25, 26, 27, 28, 29, 40, 41, 42, 43, 44, 55, 56, 57, 58, 59]}}, {"error": false, "inputs": {"fromcarry": [1], "lencarry": 1, "size": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"fromcarry": [3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5], "lencarry": 12, "size": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 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]}}, {"error": false, "inputs": {"fromcarry": [3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5], "lencarry": 12, "size": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [3, 4, 5], "lencarry": 3, "size": 5}, "outputs": {"tocarry": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [4, 4, 4, 4], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [20, 21, 22, 23, 24, 20, 21, 22, 23, 24, 20, 21, 22, 23, 24, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromcarry": [4], "lencarry": 1, "size": 5}, "outputs": {"tocarry": [20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromcarry": [2], "lencarry": 1, "size": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"fromcarry": [1, 0], "lencarry": 2, "size": 2}, "outputs": {"tocarry": [2, 3, 0, 1]}}, {"error": false, "inputs": {"fromcarry": [1], "lencarry": 1, "size": 2}, "outputs": {"tocarry": [2, 3]}}, {"error": false, "inputs": {"fromcarry": [1, 1, 0, 0], "lencarry": 4, "size": 2}, "outputs": {"tocarry": [2, 3, 2, 3, 0, 1, 0, 1]}}, {"error": false, "inputs": {"fromcarry": [1, 2], "lencarry": 2, "size": 2}, "outputs": {"tocarry": [2, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [1, 0, 0, 1], "lencarry": 4, "size": 3}, "outputs": {"tocarry": [3, 4, 5, 0, 1, 2, 0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [1], "lencarry": 1, "size": 3}, "outputs": {"tocarry": [3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [1, 1, 1, 1], "lencarry": 4, "size": 3}, "outputs": {"tocarry": [3, 4, 5, 3, 4, 5, 3, 4, 5, 3, 4, 5]}}, {"error": false, "inputs": {"fromcarry": [2], "lencarry": 1, "size": 2}, "outputs": {"tocarry": [4, 5]}}, {"error": false, "inputs": {"fromcarry": [1, 2], "lencarry": 2, "size": 4}, "outputs": {"tocarry": [4, 5, 6, 7, 8, 9, 10, 11]}}, {"error": false, "inputs": {"fromcarry": [1, 2], "lencarry": 2, "size": 5}, "outputs": {"tocarry": [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"fromcarry": [1, 2, 3, 4, 5], "lencarry": 5, "size": 5}, "outputs": {"tocarry": [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]}}, {"error": false, "inputs": {"fromcarry": [1], "lencarry": 1, "size": 5}, "outputs": {"tocarry": [5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"fromcarry": [1, 3, 6, 10], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [5, 6, 7, 8, 9, 15, 16, 17, 18, 19, 30, 31, 32, 33, 34, 50, 51, 52, 53, 54]}}, {"error": false, "inputs": {"fromcarry": [1, 4, 0, 5], "lencarry": 4, "size": 5}, "outputs": {"tocarry": [5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 0, 1, 2, 3, 4, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromcarry": [2, 1, 1, 2], "lencarry": 4, "size": 4}, "outputs": {"tocarry": [8, 9, 10, 11, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11]}}]}, {"name": "awkward_RegularArray_getitem_jagged_expand", "tests": [{"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 0, 0, 0, 0]}, "outputs": {"multistarts": [0, 0, 0, 0], "multistops": [0, 0, 0, 0]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 0, 0, 0]}, "outputs": {"multistarts": [0, 0, 0], "multistops": [0, 0, 0]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 0, 1, 1, 1]}, "outputs": {"multistarts": [0, 0, 1, 1], "multistops": [0, 1, 1, 1]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 1, 1, 3]}, "outputs": {"multistarts": [0, 1, 1], "multistops": [1, 1, 3]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 1, 1, 3, 3, 5]}, "outputs": {"multistarts": [0, 1, 1, 3, 3], "multistops": [1, 1, 3, 3, 5]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 2, 2, 2, 2, 6]}, "outputs": {"multistarts": [0, 2, 2, 2, 2], "multistops": [2, 2, 2, 2, 6]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 2, 3]}, "outputs": {"multistarts": [0, 2, 2], "multistops": [2, 2, 3]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 2, 4]}, "outputs": {"multistarts": [0, 2, 2], "multistops": [2, 2, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 2, "singleoffsets": [0, 2, 4]}, "outputs": {"multistarts": [0, 2], "multistops": [2, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 7, "singleoffsets": [0, 2, 2, 4, 4, 5, 5, 8]}, "outputs": {"multistarts": [0, 2, 2, 4, 4, 5, 5], "multistops": [2, 2, 4, 4, 5, 5, 8]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 2, 2, 4, 5, 6]}, "outputs": {"multistarts": [0, 2, 2, 4, 5], "multistops": [2, 2, 4, 5, 6]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 2, 2, 4, 5, 8]}, "outputs": {"multistarts": [0, 2, 2, 4, 5], "multistops": [2, 2, 4, 5, 8]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 2, 2, 4, 5, 9]}, "outputs": {"multistarts": [0, 2, 2, 4, 5], "multistops": [2, 2, 4, 5, 9]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 3, 4]}, "outputs": {"multistarts": [0, 2, 3], "multistops": [2, 3, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 2, 3, 3, 5]}, "outputs": {"multistarts": [0, 2, 3, 3], "multistops": [2, 3, 3, 5]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 2, 3, 4, 7]}, "outputs": {"multistarts": [0, 2, 3, 4], "multistops": [2, 3, 4, 7]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 5, 7]}, "outputs": {"multistarts": [0, 2, 5], "multistops": [2, 5, 7]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 2, 6, 8]}, "outputs": {"multistarts": [0, 2, 6], "multistops": [2, 6, 8]}}, {"error": false, "inputs": {"regularlength": 2, "regularsize": 2, "singleoffsets": [0, 3, 4]}, "outputs": {"multistarts": [0, 3, 0, 3], "multistops": [3, 4, 3, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 3, 3, 4]}, "outputs": {"multistarts": [0, 3, 3], "multistops": [3, 3, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 3, 3, 5]}, "outputs": {"multistarts": [0, 3, 3], "multistops": [3, 3, 5]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 3, 3, 3, 4, 7]}, "outputs": {"multistarts": [0, 3, 3, 3, 4], "multistops": [3, 3, 3, 4, 7]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 2, "singleoffsets": [0, 3, 4]}, "outputs": {"multistarts": [0, 3], "multistops": [3, 4]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 4, "singleoffsets": [0, 3, 3, 4, 5]}, "outputs": {"multistarts": [0, 3, 3, 4], "multistops": [3, 3, 4, 5]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 3, 3, 4, 5, 8]}, "outputs": {"multistarts": [0, 3, 3, 4, 5], "multistops": [3, 3, 4, 5, 8]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 3, 3, 5, 6, 9]}, "outputs": {"multistarts": [0, 3, 3, 5, 6], "multistops": [3, 3, 5, 6, 9]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 2, "singleoffsets": [0, 3, 6]}, "outputs": {"multistarts": [0, 3], "multistops": [3, 6]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 3, "singleoffsets": [0, 4, 6, 6]}, "outputs": {"multistarts": [0, 4, 6], "multistops": [4, 6, 6]}}, {"error": false, "inputs": {"regularlength": 1, "regularsize": 5, "singleoffsets": [0, 5, 5, 6, 8, 10]}, "outputs": {"multistarts": [0, 5, 5, 6, 8], "multistops": [5, 5, 6, 8, 10]}}]}, {"name": "awkward_RegularArray_getitem_next_array", "tests": [{"error": false, "inputs": {"fromarray": [0, 0, 0, 0], "lenarray": 4, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 0, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 0], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 0]}}, {"error": false, "inputs": {"fromarray": [0], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [0]}}, {"error": false, "inputs": {"fromarray": [0, 0, 1, 1, 1, 0], "lenarray": 6, "length": 1, "size": 4}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [0, 0, 1, 1, 1, 0]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 1, 1], "lenarray": 4, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2], "lenarray": 3, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2, 3], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 0, 1, 0, 1, 0, 1], "tocarry": [0, 1, 2, 3, 4, 5, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 2, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 1, 3]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 5], "lenarray": 5, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [0, 1, 3, 4, 5]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 5], "lenarray": 5, "length": 1, "size": 7}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [0, 1, 3, 4, 5]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 6, 7], "lenarray": 6, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 6, 7], "lenarray": 6, "length": 1, "size": 9}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 1, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4, 6, 7], "lenarray": 5, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [0, 1, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4, 6, 7], "lenarray": 5, "length": 1, "size": 9}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [0, 1, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 2], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 2]}}, {"error": false, "inputs": {"fromarray": [0, 2], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 2]}}, {"error": false, "inputs": {"fromarray": [0, 2, 1, 0], "lenarray": 4, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 2, 1, 0]}}, {"error": false, "inputs": {"fromarray": [0, 2, 3], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 2, 3]}}, {"error": false, "inputs": {"fromarray": [0, 2, 3, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 2, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 2, 4]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 3]}}, {"error": false, "inputs": {"fromarray": [0, 3, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [0, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "length": 2, "size": 4}, "outputs": {"toadvanced": [0, 1, 0, 1], "tocarry": [0, 3, 4, 7]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "length": 3, "size": 4}, "outputs": {"toadvanced": [0, 1, 0, 1, 0, 1], "tocarry": [0, 3, 4, 7, 8, 11]}}, {"error": false, "inputs": {"fromarray": [0, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 4]}}, {"error": false, "inputs": {"fromarray": [1, 0, 0, 1], "lenarray": 4, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0], "lenarray": 2, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 0]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1, 1, 1, 0], "lenarray": 6, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [1, 0, 1, 1, 1, 0]}}, {"error": false, "inputs": {"fromarray": [1], "lenarray": 1, "length": 1, "size": 2}, "outputs": {"toadvanced": [0], "tocarry": [1]}}, {"error": false, "inputs": {"fromarray": [1], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1], "lenarray": 3, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2], "tocarry": [1, 0, 1, 3, 2, 3, 5, 4, 5, 7, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 0], "lenarray": 2, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 0, 1, 0, 1, 0, 1], "tocarry": [1, 0, 3, 2, 5, 4, 7, 6]}}, {"error": false, "inputs": {"fromarray": [1, 1, 1, 1], "lenarray": 4, "length": 1, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [1, 2], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 2]}}, {"error": false, "inputs": {"fromarray": [1, 2], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 2]}}, {"error": false, "inputs": {"fromarray": [1, 2, 3], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [1, 2, 3]}}, {"error": false, "inputs": {"fromarray": [1, 2, 3, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [1, 2, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [1, 2, 4]}}, {"error": false, "inputs": {"fromarray": [1, 3], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 3]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [1, 3, 4]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4, 6, 7], "lenarray": 5, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4, 6, 7], "lenarray": 5, "length": 1, "size": 9}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 4]}}, {"error": false, "inputs": {"fromarray": [1, 4, 0, 5], "lenarray": 4, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 4, 0, 5]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 1], "lenarray": 4, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [2, 0], "lenarray": 2, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 0]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 1, 4], "lenarray": 5, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [2, 0, 0, 1, 4]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 2], "lenarray": 4, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 0, 0, 2]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 4], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 0, 0, 4]}}, {"error": false, "inputs": {"fromarray": [2], "lenarray": 1, "length": 1, "size": 3}, "outputs": {"toadvanced": [0], "tocarry": [2]}}, {"error": false, "inputs": {"fromarray": [2], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [2]}}, {"error": false, "inputs": {"fromarray": [2, 1, 1, 2], "lenarray": 4, "length": 1, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 1, 1, 2]}}, {"error": false, "inputs": {"fromarray": [2, 1, 1, 3], "lenarray": 4, "length": 2, "size": 4}, "outputs": {"toadvanced": [0, 1, 2, 3, 0, 1, 2, 3], "tocarry": [2, 1, 1, 3, 6, 5, 5, 7]}}, {"error": false, "inputs": {"fromarray": [2, 1, 1, 3], "lenarray": 4, "length": 3, "size": 4}, "outputs": {"toadvanced": [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], "tocarry": [2, 1, 1, 3, 6, 5, 5, 7, 10, 9, 9, 11]}}, {"error": false, "inputs": {"fromarray": [2, 2], "lenarray": 2, "length": 1, "size": 4}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 2, 2, 2], "lenarray": 4, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 2, 2, 2], "lenarray": 4, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 3], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromarray": [2, 3], "lenarray": 2, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromarray": [2, 3, 4], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [2, 3, 4, 5, 6], "lenarray": 5, "length": 1, "size": 7}, "outputs": {"toadvanced": [0, 1, 2, 3, 4], "tocarry": [2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromarray": [2, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 4]}}, {"error": false, "inputs": {"fromarray": [3], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [3]}}, {"error": false, "inputs": {"fromarray": [3, 1, 1, 7], "lenarray": 4, "length": 1, "size": 10}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 1, 1, 7]}}, {"error": false, "inputs": {"fromarray": [3, 2, 1, 0], "lenarray": 4, "length": 1, "size": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 2, 1, 0]}}, {"error": false, "inputs": {"fromarray": [3, 2, 1], "lenarray": 3, "length": 1, "size": 4}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [3, 2, 1]}}, {"error": false, "inputs": {"fromarray": [3, 3, 3], "lenarray": 3, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [3, 3, 3]}}, {"error": false, "inputs": {"fromarray": [3, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [3, 4]}}, {"error": false, "inputs": {"fromarray": [3, 6, 8, 6], "lenarray": 4, "length": 1, "size": 10}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 6, 8, 6]}}, {"error": false, "inputs": {"fromarray": [4], "lenarray": 1, "length": 1, "size": 5}, "outputs": {"toadvanced": [0], "tocarry": [4]}}, {"error": false, "inputs": {"fromarray": [4, 3, 2], "lenarray": 3, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2], "tocarry": [4, 3, 2]}}, {"error": false, "inputs": {"fromarray": [4, 3, 2, 1], "lenarray": 4, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 3, 2, 1]}}, {"error": false, "inputs": {"fromarray": [4, 4], "lenarray": 2, "length": 1, "size": 5}, "outputs": {"toadvanced": [0, 1], "tocarry": [4, 4]}}, {"error": false, "inputs": {"fromarray": [4, 4, 4, 4], "lenarray": 4, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 4, 4, 4]}}, {"error": false, "inputs": {"fromarray": [4, 5], "lenarray": 2, "length": 1, "size": 6}, "outputs": {"toadvanced": [0, 1], "tocarry": [4, 5]}}, {"error": false, "inputs": {"fromarray": [7, 3, 0, 2, 3, 7], "lenarray": 6, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [7, 3, 0, 2, 3, 7]}}, {"error": false, "inputs": {"fromarray": [7, 3, 2, 0, 2, 3, 7], "lenarray": 7, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5, 6], "tocarry": [7, 3, 2, 0, 2, 3, 7]}}, {"error": false, "inputs": {"fromarray": [7, 3, 2, 0, 3, 7], "lenarray": 6, "length": 1, "size": 8}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [7, 3, 2, 0, 3, 7]}}]}, {"name": "awkward_RegularArray_getitem_next_array_advanced", "tests": [{"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, 0, 1], "lenarray": 4, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 3, 4, 7]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "lenarray": 4, "length": 4, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 3, 6, 9]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, 2, 1], "lenarray": 4, "length": 4, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 4, 8, 10]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 5, 10, 15]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, 4, 1], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 6, 14, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 1, 0], "lenarray": 4, "length": 4, "size": 2}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 2, 5, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "lenarray": 4, "length": 4, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 3, 6, 10]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 5, 10, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 3, 0, 4], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 8, 10, 19]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 0, 0, 1], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 5, 10, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 2, 2, 2], "lenarray": 4, "length": 4, "size": 3}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 5, 8, 11]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 2, 2, 2], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 7, 12, 17]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [3, 3, 3, 3], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 8, 13, 18]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [4, 4, 4, 4], "lenarray": 4, "length": 4, "size": 5}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 9, 14, 19]}}]}, {"name": "awkward_RegularArray_getitem_next_array_regularize", "tests": [{"error": false, "inputs": {"fromarray": [0, 0, 0, 0], "lenarray": 4, "size": 2}, "outputs": {"toarray": [0, 0, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 0, 0, 0], "lenarray": 4, "size": 3}, "outputs": {"toarray": [0, 0, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 0, 0, 0], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 0, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 0], "lenarray": 2, "size": 3}, "outputs": {"toarray": [0, 0]}}, {"error": false, "inputs": {"fromarray": [0], "lenarray": 1, "size": 5}, "outputs": {"toarray": [0]}}, {"error": false, "inputs": {"fromarray": [0, 1, 0, 1], "lenarray": 4, "size": 2}, "outputs": {"toarray": [0, 1, 0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "size": 2}, "outputs": {"toarray": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "size": 3}, "outputs": {"toarray": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "size": 5}, "outputs": {"toarray": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1], "lenarray": 2, "size": 6}, "outputs": {"toarray": [0, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 1, 1], "lenarray": 4, "size": 2}, "outputs": {"toarray": [0, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2], "lenarray": 3, "size": 3}, "outputs": {"toarray": [0, 1, 2]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 1, 2]}}, {"error": false, "inputs": {"fromarray": [0, 1, 1, 1], "lenarray": 4, "size": 3}, "outputs": {"toarray": [0, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2, 3], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromarray": [0, 1, 2, 4], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 1, 2, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 1, 3]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 1, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 5], "lenarray": 5, "size": 6}, "outputs": {"toarray": [0, 1, 3, 4, 5]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 5], "lenarray": 5, "size": 7}, "outputs": {"toarray": [0, 1, 3, 4, 5]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 6, 7], "lenarray": 6, "size": 8}, "outputs": {"toarray": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 3, 4, 6, 7], "lenarray": 6, "size": 9}, "outputs": {"toarray": [0, 1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 1, 4]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4, 6, 7], "lenarray": 5, "size": 8}, "outputs": {"toarray": [0, 1, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 1, 4, 6, 7], "lenarray": 5, "size": 9}, "outputs": {"toarray": [0, 1, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [0, 2], "lenarray": 2, "size": 3}, "outputs": {"toarray": [0, 2]}}, {"error": false, "inputs": {"fromarray": [0, 2], "lenarray": 2, "size": 5}, "outputs": {"toarray": [0, 2]}}, {"error": false, "inputs": {"fromarray": [0, 2, 1, 0], "lenarray": 4, "size": 3}, "outputs": {"toarray": [0, 2, 1, 0]}}, {"error": false, "inputs": {"fromarray": [0, 2, 3], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 2, 3]}}, {"error": false, "inputs": {"fromarray": [0, 2, 3, 4], "lenarray": 4, "size": 5}, "outputs": {"toarray": [0, 2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 2, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 2, 4]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "size": 4}, "outputs": {"toarray": [0, 3]}}, {"error": false, "inputs": {"fromarray": [0, 3], "lenarray": 2, "size": 5}, "outputs": {"toarray": [0, 3]}}, {"error": false, "inputs": {"fromarray": [0, 3, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [0, 3, 4]}}, {"error": false, "inputs": {"fromarray": [0, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [0, 4]}}, {"error": false, "inputs": {"fromarray": [1, 0, 0, 1], "lenarray": 4, "size": 2}, "outputs": {"toarray": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 0, 1], "lenarray": 4, "size": 3}, "outputs": {"toarray": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 0, 1], "lenarray": 4, "size": 5}, "outputs": {"toarray": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1, 0], "lenarray": 4, "size": 2}, "outputs": {"toarray": [1, 0, 1, 0]}}, {"error": false, "inputs": {"fromarray": [1, 0], "lenarray": 2, "size": 2}, "outputs": {"toarray": [1, 0]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1], "lenarray": 3, "size": 2}, "outputs": {"toarray": [1, 0, 1]}}, {"error": false, "inputs": {"fromarray": [1, 0, 1, 1, 1, 0], "lenarray": 6, "size": 2}, "outputs": {"toarray": [1, 0, 1, 1, 1, 0]}}, {"error": false, "inputs": {"fromarray": [1, 1, 1, 1], "lenarray": 4, "size": 2}, "outputs": {"toarray": [1, 1, 1, 1]}}, {"error": false, "inputs": {"fromarray": [1], "lenarray": 1, "size": 2}, "outputs": {"toarray": [1]}}, {"error": false, "inputs": {"fromarray": [1], "lenarray": 1, "size": 5}, "outputs": {"toarray": [1]}}, {"error": false, "inputs": {"fromarray": [1, 2], "lenarray": 2, "size": 3}, "outputs": {"toarray": [1, 2]}}, {"error": false, "inputs": {"fromarray": [1, 2], "lenarray": 2, "size": 5}, "outputs": {"toarray": [1, 2]}}, {"error": false, "inputs": {"fromarray": [1, 2, 3], "lenarray": 3, "size": 5}, "outputs": {"toarray": [1, 2, 3]}}, {"error": false, "inputs": {"fromarray": [1, 2, 3, 4], "lenarray": 4, "size": 5}, "outputs": {"toarray": [1, 2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [1, 2, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [1, 2, 4]}}, {"error": false, "inputs": {"fromarray": [1, 3], "lenarray": 2, "size": 5}, "outputs": {"toarray": [1, 3]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [1, 3, 4]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4, 6, 7], "lenarray": 5, "size": 8}, "outputs": {"toarray": [1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 3, 4, 6, 7], "lenarray": 5, "size": 9}, "outputs": {"toarray": [1, 3, 4, 6, 7]}}, {"error": false, "inputs": {"fromarray": [1, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [1, 4]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 1], "lenarray": 4, "size": 5}, "outputs": {"toarray": [2, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [2, 0, 0, 1], "lenarray": 4, "size": 6}, "outputs": {"toarray": [2, 0, 0, 1]}}, {"error": false, "inputs": {"fromarray": [2, 0], "lenarray": 2, "size": 3}, "outputs": {"toarray": [2, 0]}}, {"error": false, "inputs": {"fromarray": [2], "lenarray": 1, "size": 3}, "outputs": {"toarray": [2]}}, {"error": false, "inputs": {"fromarray": [2], "lenarray": 1, "size": 5}, "outputs": {"toarray": [2]}}, {"error": false, "inputs": {"fromarray": [2, 2, 2, 2], "lenarray": 4, "size": 5}, "outputs": {"toarray": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 2, 2, 2], "lenarray": 4, "size": 6}, "outputs": {"toarray": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 2], "lenarray": 2, "size": 4}, "outputs": {"toarray": [2, 2]}}, {"error": false, "inputs": {"fromarray": [2, 3], "lenarray": 2, "size": 5}, "outputs": {"toarray": [2, 3]}}, {"error": false, "inputs": {"fromarray": [2, 3], "lenarray": 2, "size": 6}, "outputs": {"toarray": [2, 3]}}, {"error": false, "inputs": {"fromarray": [2, 3, 4], "lenarray": 3, "size": 5}, "outputs": {"toarray": [2, 3, 4]}}, {"error": false, "inputs": {"fromarray": [2, 3, 4, 5, 6], "lenarray": 5, "size": 7}, "outputs": {"toarray": [2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"fromarray": [2, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [2, 4]}}, {"error": false, "inputs": {"fromarray": [3, 1, 1, 7], "lenarray": 4, "size": 10}, "outputs": {"toarray": [3, 1, 1, 7]}}, {"error": false, "inputs": {"fromarray": [3, 2, 1, 0], "lenarray": 4, "size": 4}, "outputs": {"toarray": [3, 2, 1, 0]}}, {"error": false, "inputs": {"fromarray": [3, 2, 1], "lenarray": 3, "size": 4}, "outputs": {"toarray": [3, 2, 1]}}, {"error": false, "inputs": {"fromarray": [3], "lenarray": 1, "size": 5}, "outputs": {"toarray": [3]}}, {"error": false, "inputs": {"fromarray": [3, 3, 3], "lenarray": 3, "size": 5}, "outputs": {"toarray": [3, 3, 3]}}, {"error": false, "inputs": {"fromarray": [3, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [3, 4]}}, {"error": false, "inputs": {"fromarray": [4, 3, 2, 1], "lenarray": 4, "size": 8}, "outputs": {"toarray": [4, 3, 2, 1]}}, {"error": false, "inputs": {"fromarray": [4, 3, 2], "lenarray": 3, "size": 8}, "outputs": {"toarray": [4, 3, 2]}}, {"error": false, "inputs": {"fromarray": [4], "lenarray": 1, "size": 5}, "outputs": {"toarray": [4]}}, {"error": false, "inputs": {"fromarray": [4, 4], "lenarray": 2, "size": 5}, "outputs": {"toarray": [4, 4]}}, {"error": false, "inputs": {"fromarray": [4, 5], "lenarray": 2, "size": 6}, "outputs": {"toarray": [4, 5]}}]}, {"name": "awkward_RegularArray_getitem_next_at", "tests": [{"error": false, "inputs": {"at": 0, "length": 1, "size": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 1, "size": 2}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 1, "size": 3}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 1, "size": 5}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 1, "size": 6}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "length": 2, "size": 5}, "outputs": {"tocarry": [0, 5]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 2}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 3}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 4}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 5}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 1, "size": 6}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "length": 2, "size": 5}, "outputs": {"tocarry": [1, 6]}}, {"error": false, "inputs": {"at": 2, "length": 1, "size": 3}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 2, "length": 1, "size": 4}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 2, "length": 1, "size": 5}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 2, "length": 1, "size": 6}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 2, "length": 5, "size": 5}, "outputs": {"tocarry": [2, 7, 12, 17, 22]}}, {"error": false, "inputs": {"at": 3, "length": 1, "size": 4}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 3, "length": 1, "size": 5}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 4, "length": 1, "size": 5}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": 4, "length": 1, "size": 6}, "outputs": {"tocarry": [4]}}]}, {"name": "awkward_RegularArray_getitem_next_range", "tests": [{"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 1, "step": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 2, "step": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 3, "step": 3}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 0, "size": 5, "step": 3}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 2, "step": 1}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 3, "step": 1}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 0, "size": 3, "step": 1}, "outputs": {"tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 4, "regular_start": 0, "size": 4, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 2, "nextsize": 2, "regular_start": 0, "size": 2, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 5, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 5, "regular_start": 0, "size": 6, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 6, "regular_start": 0, "size": 6, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 1, "nextsize": 8, "regular_start": 0, "size": 8, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7]}}, {"error": false, "inputs": {"length": 1, "nextsize": 10, "regular_start": 0, "size": 10, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}}, {"error": false, "inputs": {"length": 3, "nextsize": 5, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]}}, {"error": false, "inputs": {"length": 5, "nextsize": 5, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"length": 2, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 5, 6, 7, 8]}}, {"error": false, "inputs": {"length": 3, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13]}}, {"error": false, "inputs": {"length": 5, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23]}}, {"error": false, "inputs": {"length": 6, "nextsize": 4, "regular_start": 0, "size": 5, "step": 1}, "outputs": {"tocarry": [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23, 25, 26, 27, 28]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 3, "step": 2}, "outputs": {"tocarry": [0, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 5, "step": 2}, "outputs": {"tocarry": [0, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 0, "size": 5, "step": 2}, "outputs": {"tocarry": [0, 2, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 0, "size": 6, "step": 2}, "outputs": {"tocarry": [0, 2, 4]}}, {"error": false, "inputs": {"length": 5, "nextsize": 3, "regular_start": 0, "size": 5, "step": 2}, "outputs": {"tocarry": [0, 2, 4, 5, 7, 9, 10, 12, 14, 15, 17, 19, 20, 22, 24]}}, {"error": false, "inputs": {"length": 6, "nextsize": 3, "regular_start": 0, "size": 5, "step": 2}, "outputs": {"tocarry": [0, 2, 4, 5, 7, 9, 10, 12, 14, 15, 17, 19, 20, 22, 24, 25, 27, 29]}}, {"error": false, "inputs": {"length": 1, "nextsize": 4, "regular_start": 0, "size": 8, "step": 2}, "outputs": {"tocarry": [0, 2, 4, 6]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 0, "size": 5, "step": 3}, "outputs": {"tocarry": [0, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 1, "size": 2, "step": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 1, "size": 3, "step": 2}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 1, "size": 3, "step": 3}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 1, "size": 5, "step": 3}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 1, "size": 3, "step": 1}, "outputs": {"tocarry": [1, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 1, "size": 4, "step": 1}, "outputs": {"tocarry": [1, 2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 5, "regular_start": 1, "size": 6, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 3, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14]}}, {"error": false, "inputs": {"length": 5, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22, 23, 24]}}, {"error": false, "inputs": {"length": 6, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22, 23, 24, 26, 27, 28, 29]}}, {"error": false, "inputs": {"length": 2, "nextsize": 4, "regular_start": 1, "size": 5, "step": 1}, "outputs": {"tocarry": [1, 2, 3, 4, 6, 7, 8, 9]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 1, "size": 5, "step": 2}, "outputs": {"tocarry": [1, 3]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 1, "size": 5, "step": 3}, "outputs": {"tocarry": [1, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 2, "size": 3, "step": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 2, "size": 3, "step": 2}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 2, "size": 3, "step": 3}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 1, "regular_start": 2, "size": 5, "step": 3}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"length": 1, "nextsize": 3, "regular_start": 2, "size": 5, "step": 1}, "outputs": {"tocarry": [2, 3, 4]}}, {"error": false, "inputs": {"length": 1, "nextsize": 2, "regular_start": 3, "size": 5, "step": 1}, "outputs": {"tocarry": [3, 4]}}]}, {"name": "awkward_RegularArray_getitem_next_range_spreadadvanced", "tests": [{"error": false, "inputs": {"fromadvanced": [0], "length": 1, "nextsize": 2}, "outputs": {"toadvanced": [0, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "length": 2, "nextsize": 2}, "outputs": {"toadvanced": [0, 0, 1, 1]}}]}, {"name": "awkward_ListOffsetArray_flatten_offsets", "tests": [{"error": false, "inputs": {"inneroffsets": [0], "inneroffsetslen": 1, "outeroffsets": [0, 0, 0, 0, 0], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 2, 3], "inneroffsetslen": 4, "outeroffsets": [0, 0, 0, 1, 3], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 0, 0, 1, 3]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 2, 3, 4, 5, 6], "inneroffsetslen": 7, "outeroffsets": [0, 0, 1, 3, 6], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 0, 1, 3, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 1, 5], "inneroffsetslen": 4, "outeroffsets": [0, 0, 1, 3], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 0, 1, 5]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 1, 6, 6], "inneroffsetslen": 5, "outeroffsets": [0, 0, 1, 4], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 0, 1, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 4, 8, 12, 14, 16], "inneroffsetslen": 6, "outeroffsets": [0, 3, 3, 5], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 12, 12, 16]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 2, 5, 5, 7, 7, 11], "inneroffsetslen": 8, "outeroffsets": [0, 1, 2, 2, 5, 7], "outeroffsetslen": 6}, "outputs": {"tooffsets": [0, 1, 2, 2, 7, 11]}}, {"error": false, "inputs": {"inneroffsets": [0, 1, 2, 3, 4, 5, 6], "inneroffsetslen": 7, "outeroffsets": [0, 1, 3, 6], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 1, 3, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 5, 10, 15, 20, 25, 30], "inneroffsetslen": 7, "outeroffsets": [0, 3, 6], "outeroffsetslen": 3}, "outputs": {"tooffsets": [0, 15, 30]}}, {"error": false, "inputs": {"inneroffsets": [0, 2, 6], "inneroffsetslen": 3, "outeroffsets": [0, 1, 1, 1, 2], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 0, 2, 6], "inneroffsetslen": 4, "outeroffsets": [0, 2, 2, 2, 3], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 0, 0, 2, 6], "inneroffsetslen": 5, "outeroffsets": [0, 3, 3, 3, 4], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 0, 0, 0, 2, 7, 7], "inneroffsetslen": 7, "outeroffsets": [0, 4, 4, 4, 6], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 2, 2, 2, 7]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 5, 6, 6], "inneroffsetslen": 5, "outeroffsets": [0, 1, 2, 3, 4], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 3, 5, 6, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105, 112, 119, 126, 133, 140, 147, 154, 161, 168, 175, 182, 189, 196, 203, 210], "inneroffsetslen": 31, "outeroffsets": [0, 5, 10, 15, 20, 25, 30], "outeroffsetslen": 7}, "outputs": {"tooffsets": [0, 35, 70, 105, 140, 175, 210]}}, {"error": false, "inputs": {"inneroffsets": [0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16], "inneroffsetslen": 11, "outeroffsets": [0, 2, 4, 6, 8, 10], "outeroffsetslen": 6}, "outputs": {"tooffsets": [0, 4, 8, 12, 14, 16]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 5, 6, 6, 10], "inneroffsetslen": 6, "outeroffsets": [0, 2, 2, 3, 5], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 5, 5, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 5, 6, 6, 10], "inneroffsetslen": 7, "outeroffsets": [0, 3, 3, 4, 6], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 5, 5, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 3, 5, 6, 6, 10], "inneroffsetslen": 8, "outeroffsets": [0, 4, 4, 5, 7], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 5, 5, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 5, 5, 8], "inneroffsetslen": 6, "outeroffsets": [0, 3, 3, 5], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 5, 5, 8]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 6, 9, 12, 14, 16], "inneroffsetslen": 7, "outeroffsets": [0, 2, 4, 5, 6, 6, 6], "outeroffsetslen": 7}, "outputs": {"tooffsets": [0, 6, 12, 14, 16, 16, 16]}}, {"error": false, "inputs": {"inneroffsets": [0, 2, 4, 6, 8, 10], "inneroffsetslen": 6, "outeroffsets": [0, 3, 3, 5], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 6, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20], "inneroffsetslen": 11, "outeroffsets": [0, 3, 3, 5, 8, 8, 10], "outeroffsetslen": 7}, "outputs": {"tooffsets": [0, 6, 6, 10, 16, 16, 20]}}, {"error": false, "inputs": {"inneroffsets": [0, 4, 4, 4, 4, 6, 7, 7, 12, 12], "inneroffsetslen": 10, "outeroffsets": [0, 5, 5, 6, 9], "outeroffsetslen": 5}, "outputs": {"tooffsets": [0, 6, 6, 7, 12]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 6, 9, 11, 13, 14], "inneroffsetslen": 7, "outeroffsets": [0, 3, 5, 6], "outeroffsetslen": 4}, "outputs": {"tooffsets": [0, 9, 13, 14]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 5, 6, 6], "inneroffsetslen": 5, "outeroffsets": [1, 2, 3, 4], "outeroffsetslen": 4}, "outputs": {"tooffsets": [3, 5, 6, 6]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 5, 6, 6, 10], "inneroffsetslen": 7, "outeroffsets": [3, 3, 4, 6], "outeroffsetslen": 4}, "outputs": {"tooffsets": [5, 5, 6, 10]}}, {"error": false, "inputs": {"inneroffsets": [0, 3, 3, 3, 5, 6, 6, 10], "inneroffsetslen": 8, "outeroffsets": [4, 4, 5, 7], "outeroffsetslen": 4}, "outputs": {"tooffsets": [5, 5, 6, 10]}}]}, {"name": "awkward_ListOffsetArray_toRegularArray", "tests": [{"error": false, "inputs": {"fromoffsets": [0, 1, 2, 3], "offsetslength": 4}, "outputs": {"size": [1]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4], "offsetslength": 3}, "outputs": {"size": [2]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 6], "offsetslength": 4}, "outputs": {"size": [2]}}, {"error": false, "inputs": {"fromoffsets": [0, 4], "offsetslength": 2}, "outputs": {"size": [4]}}, {"error": false, "inputs": {"fromoffsets": [0, 5, 10], "offsetslength": 3}, "outputs": {"size": [5]}}]}, {"name": "awkward_MaskedArray_getitem_next_jagged_project", "tests": [{"error": false, "inputs": {"index": [0, 1, 2, 3], "length": 4, "starts_in": [0, 2, 3, 3], "stops_in": [2, 3, 3, 3]}, "outputs": {"starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 3]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3], "length": 4, "starts_in": [0, 2, 3, 3], "stops_in": [2, 3, 3, 5]}, "outputs": {"starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 5]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3], "length": 4, "starts_in": [0, 2, 3, 3], "stops_in": [2, 3, 3, 6]}, "outputs": {"starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 6]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3], "length": 4, "starts_in": [0, 2, 3, 4], "stops_in": [2, 3, 4, 7]}, "outputs": {"starts_out": [0, 2, 3, 4], "stops_out": [2, 3, 4, 7]}}]}, {"name": "awkward_ListOffsetArray_reduce_nonlocal_maxcount_offsetscopy_64", "tests": [{"error": false, "inputs": {"length": 3, "offsets": [0, 2, 3, 5]}, "outputs": {"maxcount": [2], "offsetscopy": [0, 2, 3, 5]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 2, 4, 6]}, "outputs": {"maxcount": [2], "offsetscopy": [0, 2, 4, 6]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 3, 3, 5]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 3, 5]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 3, 5, 6, 8, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 3, 5, 6, 8, 9]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 3, 3, 5, 6, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 3, 5, 6, 9]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 5, 5, 6, 8, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 5, 5, 6, 8, 9]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 5, 6, 7, 7, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 5, 6, 7, 7, 9]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 3, 5, 6, 7, 9]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 5, 6, 7, 9]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 5, 7, 8, 9, 10]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 5, 7, 8, 9, 10]}}, {"error": false, "inputs": {"length": 2, "offsets": [0, 3, 6]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 6]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 3, 6, 9, 12, 15]}, "outputs": {"maxcount": [3], "offsetscopy": [0, 3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"length": 9, "offsets": [0, 0, 1, 3, 6, 10, 13, 15, 16, 16]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 0, 1, 3, 6, 10, 13, 15, 16, 16]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 3, 3, 7]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 3, 3, 7]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 3, 6, 10]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 3, 6, 10]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 4, 4, 6]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 4, 4, 6]}}, {"error": false, "inputs": {"length": 2, "offsets": [0, 4, 6]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 4, 6]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 4, 8, 12]}, "outputs": {"maxcount": [4], "offsetscopy": [0, 4, 8, 12]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 8, 13, 18, 23, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 3, 8, 13, 18, 23, 28]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 4, 9, 13, 18, 23, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 4, 9, 13, 18, 23, 28]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 4, 9, 14, 19, 24, 29]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 4, 9, 14, 19, 24, 29]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 11, 12, 17, 22]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 11, 12, 17, 22]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 14, 18, 23, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 14, 18, 23, 28]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 5, 10, 15]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 19, 24, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 19, 24, 28]}}, {"error": false, "inputs": {"length": 4, "offsets": [0, 5, 10, 15, 20]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 20, 24, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 24, 28]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 5, 10, 15, 20, 25]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 25]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 20, 25, 28]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 25, 28]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 20, 25, 29]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 25, 29]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 10, 15, 20, 25, 30]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 5, 6, 11, 16, 17, 22]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 6, 11, 16, 17, 22]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 5, 8, 11, 14, 17]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 8, 11, 14, 17]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 5, 9, 12]}, "outputs": {"maxcount": [5], "offsetscopy": [0, 5, 9, 12]}}]}, {"name": "awkward_ByteMaskedArray_overlay_mask", "tests": [{"error": false, "inputs": {"length": 2, "mymask": [0, 0], "theirmask": [0, 0], "validwhen": false}, "outputs": {"tomask": [0, 0]}}]}, {"name": "awkward_IndexedArray_flatten_none2empty", "tests": [{"error": false, "inputs": {"offsets": [0, 1, 1, 6], "offsetslength": 4, "outindex": [0, 1, 2, 1], "outindexlength": 4}, "outputs": {"outoffsets": [0, 1, 1, 6, 6]}}, {"error": false, "inputs": {"offsets": [0, 3, 3, 5], "offsetslength": 4, "outindex": [0, 1, 1, 1, 2], "outindexlength": 5}, "outputs": {"outoffsets": [0, 3, 3, 3, 3, 5]}}, {"error": false, "inputs": {"offsets": [0, 3, 3, 4, 7], "offsetslength": 5, "outindex": [0, 1, 2, 1, 3], "outindexlength": 5}, "outputs": {"outoffsets": [0, 3, 3, 4, 4, 7]}}, {"error": false, "inputs": {"offsets": [0, 3, 3, 5, 6, 6, 10], "offsetslength": 7, "outindex": [0, 1, 2, 3, 4, 1, 5], "outindexlength": 7}, "outputs": {"outoffsets": [0, 3, 3, 5, 6, 6, 6, 10]}}, {"error": false, "inputs": {"offsets": [0, 4, 4, 6], "offsetslength": 4, "outindex": [0, 1, 1, 1, 2, 1], "outindexlength": 6}, "outputs": {"outoffsets": [0, 4, 4, 4, 4, 6, 6]}}, {"error": false, "inputs": {"offsets": [0, 4, 4, 6, 7, 7, 12], "offsetslength": 7, "outindex": [0, 1, 1, 1, 2, 3, 4, 5, 1], "outindexlength": 9}, "outputs": {"outoffsets": [0, 4, 4, 4, 4, 6, 7, 7, 12, 12]}}, {"error": false, "inputs": {"offsets": [0, 5, 5, 6, 9], "offsetslength": 5, "outindex": [0, 1, 1, 2, 1, 3], "outindexlength": 6}, "outputs": {"outoffsets": [0, 5, 5, 5, 6, 6, 9]}}]}, {"name": "awkward_IndexedArray_reduce_next_64", "tests": [{"error": false, "inputs": {"index": [0, 1], "length": 2, "parents": [0, 0]}, "outputs": {"nextcarry": [0, 1], "nextparents": [0, 0], "outindex": [0, 1]}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 4, 5, 6], "length": 7, "parents": [0, 0, 2, 2, 3, 4, 4]}, "outputs": {"nextcarry": [0, 1, 2, 3, 4, 5, 6], "nextparents": [0, 0, 2, 2, 3, 4, 4], "outindex": [0, 1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"index": [1, 2], "length": 2, "parents": [0, 0]}, "outputs": {"nextcarry": [1, 2], "nextparents": [0, 0], "outindex": [0, 1]}}, {"error": false, "inputs": {"index": [1, 2, 3], "length": 3, "parents": [0, 0, 0]}, "outputs": {"nextcarry": [1, 2, 3], "nextparents": [0, 0, 0], "outindex": [0, 1, 2]}}, {"error": false, "inputs": {"index": [1, 2, 3, 4], "length": 4, "parents": [0, 0, 0, 0]}, "outputs": {"nextcarry": [1, 2, 3, 4], "nextparents": [0, 0, 0, 0], "outindex": [0, 1, 2, 3]}}, {"error": false, "inputs": {"index": [2, 3], "length": 2, "parents": [0, 0]}, "outputs": {"nextcarry": [2, 3], "nextparents": [0, 0], "outindex": [0, 1]}}, {"error": false, "inputs": {"index": [2, 3, 4], "length": 3, "parents": [0, 0, 0]}, "outputs": {"nextcarry": [2, 3, 4], "nextparents": [0, 0, 0], "outindex": [0, 1, 2]}}, {"error": false, "inputs": {"index": [3, 4], "length": 2, "parents": [0, 0]}, "outputs": {"nextcarry": [3, 4], "nextparents": [0, 0], "outindex": [0, 1]}}, {"error": false, "inputs": {"index": [4, 3, 2, 1, 0], "length": 5, "parents": [0, 0, 0, 0, 0]}, "outputs": {"nextcarry": [4, 3, 2, 1, 0], "nextparents": [0, 0, 0, 0, 0], "outindex": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"index": [5, 2, 4, 1, 3, 0], "length": 6, "parents": [0, 0, 1, 1, 2, 2]}, "outputs": {"nextcarry": [5, 2, 4, 1, 3, 0], "nextparents": [0, 0, 1, 1, 2, 2], "outindex": [0, 1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"index": [5, 4, 3, 2, 1, 0], "length": 6, "parents": [0, 0, 0, 1, 1, 1]}, "outputs": {"nextcarry": [5, 4, 3, 2, 1, 0], "nextparents": [0, 0, 0, 1, 1, 1], "outindex": [0, 1, 2, 3, 4, 5]}}]}, {"name": "awkward_IndexedArray_simplify", "tests": [{"error": false, "inputs": {"innerindex": [0, 1], "innerlength": 2, "outerindex": [0, 1], "outerlength": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2], "innerlength": 5, "outerindex": [0, 1, 2], "outerlength": 3}, "outputs": {"toindex": [0, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 4], "innerlength": 5, "outerindex": [0, 1, 2], "outerlength": 3}, "outputs": {"toindex": [0, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2], "innerlength": 3, "outerindex": [0, 1, 1, 1, 1, 2], "outerlength": 6}, "outputs": {"toindex": [0, 1, 1, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 1, 1], "innerlength": 5, "outerindex": [0, 1, 1, 1, 2], "outerlength": 5}, "outputs": {"toindex": [0, 1, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2], "innerlength": 5, "outerindex": [0, 1, 2, 3, 4, 1, 1], "outerlength": 7}, "outputs": {"toindex": [0, 1, 1, 1, 2, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 4], "innerlength": 5, "outerindex": [0, 1, 2, 3, 4, 1, 1], "outerlength": 7}, "outputs": {"toindex": [0, 1, 1, 1, 4, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 1], "innerlength": 4, "outerindex": [0, 1, 1, 2], "outerlength": 4}, "outputs": {"toindex": [0, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 2], "innerlength": 4, "outerindex": [0, 1, 1, 3], "outerlength": 4}, "outputs": {"toindex": [0, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 2], "innerlength": 4, "outerindex": [0, 1, 2, 3], "outerlength": 4}, "outputs": {"toindex": [0, 1, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 3], "innerlength": 4, "outerindex": [0, 1, 1, 2, 3], "outerlength": 5}, "outputs": {"toindex": [0, 1, 1, 2, 3]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 3], "innerlength": 4, "outerindex": [0, 1, 1, 3], "outerlength": 4}, "outputs": {"toindex": [0, 1, 1, 3]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2], "innerlength": 3, "outerindex": [0, 1, 2], "outerlength": 3}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 3], "innerlength": 4, "outerindex": [0, 1, 2, 1, 3], "outerlength": 5}, "outputs": {"toindex": [0, 1, 2, 1, 3]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 1, 4], "innerlength": 5, "outerindex": [0, 1, 2, 3, 4], "outerlength": 5}, "outputs": {"toindex": [0, 1, 2, 1, 4]}}, {"error": false, "inputs": {"innerindex": [0, 1, 2, 3, 4, 5, 6, 7, 1, 1], "innerlength": 10, "outerindex": [0, 1, 2, 3, 4, 1, 1, 1, 5, 6, 1, 1, 7, 8, 9, 1], "outerlength": 16}, "outputs": {"toindex": [0, 1, 2, 3, 4, 1, 1, 1, 5, 6, 1, 1, 7, 1, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 2, 1, 1, 3, 4], "innerlength": 8, "outerindex": [2, 2, 1, 6, 5], "outerlength": 5}, "outputs": {"toindex": [1, 1, 1, 3, 1]}}, {"error": false, "inputs": {"innerindex": [13, 9, 13, 4, 8, 3, 15, 1, 16, 2, 8], "innerlength": 11, "outerindex": [0, 3, 6], "outerlength": 3}, "outputs": {"toindex": [13, 4, 15]}}, {"error": false, "inputs": {"innerindex": [13, 9, 13, 4, 8, 3, 15, 1, 16, 2, 8], "innerlength": 11, "outerindex": [0, 1, 2, 3, 4, 5, 6, 7, 8], "outerlength": 9}, "outputs": {"toindex": [13, 9, 13, 4, 8, 3, 15, 1, 16]}}, {"error": false, "inputs": {"innerindex": [13, 9, 13, 4, 8, 3, 15, 1, 16, 2, 8], "innerlength": 11, "outerindex": [0, 1, 3, 4, 6, 7], "outerlength": 6}, "outputs": {"toindex": [13, 9, 4, 8, 15, 1]}}, {"error": false, "inputs": {"innerindex": [2, 1, 1, 0], "innerlength": 4, "outerindex": [0, 1, 2, 1, 3], "outerlength": 5}, "outputs": {"toindex": [2, 1, 1, 1, 0]}}, {"error": false, "inputs": {"innerindex": [3, 1, 1, 7], "innerlength": 4, "outerindex": [0, 1, 1, 2, 3], "outerlength": 5}, "outputs": {"toindex": [3, 1, 1, 1, 7]}}, {"error": false, "inputs": {"innerindex": [3, 1, 2, 1], "innerlength": 4, "outerindex": [0, 1, 2, 1, 3], "outerlength": 5}, "outputs": {"toindex": [3, 1, 2, 1, 1]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0], "outerlength": 1}, "outputs": {"toindex": [4]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0, 1], "outerlength": 2}, "outputs": {"toindex": [4, 3]}}, {"error": false, "inputs": {"innerindex": [4, 5, 6, 7, 3, 1, 2, 0, 1, 1], "innerlength": 10, "outerindex": [0, 4, 5, 7], "outerlength": 4}, "outputs": {"toindex": [4, 3, 1, 0]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0, 1, 2], "outerlength": 3}, "outputs": {"toindex": [4, 3, 2]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0, 1, 2, 3, 4], "outerlength": 5}, "outputs": {"toindex": [4, 3, 2, 1, 0]}}, {"error": false, "inputs": {"innerindex": [4, 3, 2, 1, 0], "innerlength": 5, "outerindex": [0, 1, 2, 3], "outerlength": 4}, "outputs": {"toindex": [4, 3, 2, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2, 3, 4, 5, 6, 7], "innerlength": 10, "outerindex": [6, 7, 8, 9, 5, 1, 1, 1, 3, 4, 1, 1, 0, 1, 2, 1], "outerlength": 16}, "outputs": {"toindex": [4, 5, 6, 7, 3, 1, 1, 1, 1, 2, 1, 1, 0, 1, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2, 3, 4, 5, 6, 7], "innerlength": 10, "outerindex": [6, 7, 8, 9, 5, 1, 1, 3, 4, 1, 0, 1, 2], "outerlength": 13}, "outputs": {"toindex": [4, 5, 6, 7, 3, 1, 1, 1, 2, 1, 0, 1, 1]}}, {"error": false, "inputs": {"innerindex": [0, 1, 1, 1, 2, 3, 4, 5, 6, 7], "innerlength": 10, "outerindex": [6, 7, 8, 9, 5, 3, 4, 0, 1, 2], "outerlength": 10}, "outputs": {"toindex": [4, 5, 6, 7, 3, 1, 2, 0, 1, 1]}}, {"error": false, "inputs": {"innerindex": [6, 5, 1, 3, 1, 1, 0], "innerlength": 7, "outerindex": [0, 2, 4, 6], "outerlength": 4}, "outputs": {"toindex": [6, 1, 1, 0]}}, {"error": false, "inputs": {"innerindex": [6, 5, 4, 3, 2, 1, 0], "innerlength": 7, "outerindex": [0, 2, 4, 6], "outerlength": 4}, "outputs": {"toindex": [6, 4, 2, 0]}}]}, {"name": "awkward_IndexedArray_validity", "tests": [{"error": false, "inputs": {"index": [0, 1, 1, 1, 1, 2], "isoption": true, "lencontent": 3, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 1], "isoption": true, "lencontent": 2, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2, 3, 4], "isoption": true, "lencontent": 5, "length": 7}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2, 3], "isoption": true, "lencontent": 4, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1, 2], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 1], "isoption": true, "lencontent": 2, "length": 4}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 1, 3], "isoption": true, "lencontent": 4, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 1], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 1, 4, 5, 6], "isoption": true, "lencontent": 7, "length": 9}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 4, 1, 5], "isoption": true, "lencontent": 6, "length": 8}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 4, 5, 6, 7], "isoption": true, "lencontent": 8, "length": 9}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3, 4, 5], "isoption": true, "lencontent": 6, "length": 7}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2, 3], "isoption": true, "lencontent": 4, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1, 2], "isoption": true, "lencontent": 3, "length": 4}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 1], "isoption": true, "lencontent": 2, "length": 3}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 1], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 3, 1, 4], "isoption": true, "lencontent": 5, "length": 7}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 1, 3], "isoption": true, "lencontent": 4, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 1], "isoption": true, "lencontent": 3, "length": 4}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1, 4, 5, 6, 7, 8, 1, 9], "isoption": true, "lencontent": 10, "length": 12}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1, 4, 5, 6], "isoption": true, "lencontent": 7, "length": 8}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1, 4], "isoption": true, "lencontent": 5, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 3, 1], "isoption": true, "lencontent": 4, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 1], "isoption": true, "lencontent": 2, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 1, 2], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 1, 3], "isoption": true, "lencontent": 4, "length": 6}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 1], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 2, 3], "isoption": true, "lencontent": 4, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 0, 1, 2], "isoption": true, "lencontent": 3, "length": 4}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 1], "isoption": true, "lencontent": 2, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 1, 0, 1, 2], "isoption": true, "lencontent": 3, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 1, 1, 0, 1], "isoption": true, "lencontent": 2, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [1, 4, 4, 1, 0], "isoption": true, "lencontent": 10, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [2, 1, 4, 0, 8], "isoption": true, "lencontent": 10, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [2, 2, 0, 1, 4], "isoption": true, "lencontent": 5, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [2, 4, 4, 0, 8], "isoption": false, "lencontent": 10, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [6, 4, 4, 8, 0], "isoption": false, "lencontent": 10, "length": 5}, "outputs": {}}, {"error": false, "inputs": {"index": [6, 5, 4, 3, 2, 1, 0], "isoption": false, "lencontent": 7, "length": 7}, "outputs": {}}]}, {"name": "awkward_IndexedOptionArray_rpad_and_clip_mask_axis1", "tests": [{"error": false, "inputs": {"frommask": [0, 0, 0, 0], "length": 4}, "outputs": {"toindex": [0, 1, 2, 3]}}]}, {"name": "awkward_index_rpad_and_clip_axis1", "tests": [{"error": false, "inputs": {"length": 4, "target": 1}, "outputs": {"tostarts": [0, 1, 2, 3], "tostops": [1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 5, "target": 1}, "outputs": {"tostarts": [0, 1, 2, 3, 4], "tostops": [1, 2, 3, 4, 5]}}, {"error": false, "inputs": {"length": 6, "target": 1}, "outputs": {"tostarts": [0, 1, 2, 3, 4, 5], "tostops": [1, 2, 3, 4, 5, 6]}}, {"error": false, "inputs": {"length": 3, "target": 2}, "outputs": {"tostarts": [0, 2, 4], "tostops": [2, 4, 6]}}, {"error": false, "inputs": {"length": 7, "target": 2}, "outputs": {"tostarts": [0, 2, 4, 6, 8, 10, 12], "tostops": [2, 4, 6, 8, 10, 12, 14]}}, {"error": false, "inputs": {"length": 6, "target": 2}, "outputs": {"tostarts": [0, 2, 4, 6, 8, 10], "tostops": [2, 4, 6, 8, 10, 12]}}, {"error": false, "inputs": {"length": 5, "target": 2}, "outputs": {"tostarts": [0, 2, 4, 6, 8], "tostops": [2, 4, 6, 8, 10]}}, {"error": false, "inputs": {"length": 6, "target": 3}, "outputs": {"tostarts": [0, 3, 6, 9, 12, 15], "tostops": [3, 6, 9, 12, 15, 18]}}, {"error": false, "inputs": {"length": 5, "target": 3}, "outputs": {"tostarts": [0, 3, 6, 9, 12], "tostops": [3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"length": 6, "target": 4}, "outputs": {"tostarts": [0, 4, 8, 12, 16, 20], "tostops": [4, 8, 12, 16, 20, 24]}}, {"error": false, "inputs": {"length": 5, "target": 4}, "outputs": {"tostarts": [0, 4, 8, 12, 16], "tostops": [4, 8, 12, 16, 20]}}, {"error": false, "inputs": {"length": 6, "target": 5}, "outputs": {"tostarts": [0, 5, 10, 15, 20, 25], "tostops": [5, 10, 15, 20, 25, 30]}}, {"error": false, "inputs": {"length": 5, "target": 5}, "outputs": {"tostarts": [0, 5, 10, 15, 20], "tostops": [5, 10, 15, 20, 25]}}]}, {"name": "awkward_ListArray_combinations_length", "tests": [{"error": false, "inputs": {"length": 5, "n": 3, "replacement": false, "starts": [0, 4, 4, 7, 8], "stops": [4, 4, 7, 8, 13]}, "outputs": {"tooffsets": [0, 4, 4, 5, 5, 15], "totallen": [15]}}, {"error": false, "inputs": {"length": 5, "n": 2, "replacement": false, "starts": [0, 4, 4, 7, 8], "stops": [4, 4, 7, 8, 13]}, "outputs": {"tooffsets": [0, 6, 6, 9, 9, 19], "totallen": [19]}}, {"error": false, "inputs": {"length": 5, "n": 2, "replacement": true, "starts": [0, 4, 4, 7, 8], "stops": [4, 4, 7, 8, 13]}, "outputs": {"tooffsets": [0, 10, 10, 16, 17, 32], "totallen": [32]}}, {"error": false, "inputs": {"length": 3, "n": 2, "replacement": false, "starts": [0, 3, 3], "stops": [3, 3, 5]}, "outputs": {"tooffsets": [0, 3, 3, 4], "totallen": [4]}}, {"error": false, "inputs": {"length": 3, "n": 2, "replacement": false, "starts": [0, 3, 5], "stops": [3, 3, 7]}, "outputs": {"tooffsets": [0, 3, 3, 4], "totallen": [4]}}, {"error": false, "inputs": {"length": 5, "n": 3, "replacement": true, "starts": [0, 4, 4, 7, 8], "stops": [4, 4, 7, 8, 13]}, "outputs": {"tooffsets": [0, 20, 20, 30, 31, 66], "totallen": [66]}}, {"error": false, "inputs": {"length": 5, "n": 2, "replacement": false, "starts": [0, 3, 3, 10, 10], "stops": [3, 3, 5, 10, 13]}, "outputs": {"tooffsets": [0, 3, 3, 4, 4, 7], "totallen": [7]}}]}, {"name": "awkward_ListArray_getitem_jagged_carrylen", "tests": [{"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 0, 0, 0], "slicestops": [0, 0, 0, 0]}, "outputs": {"carrylen": [0]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 0, 0], "slicestops": [0, 0, 0]}, "outputs": {"carrylen": [0]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 0, 1, 1], "slicestops": [0, 1, 1, 1]}, "outputs": {"carrylen": [1]}}, {"error": false, "inputs": {"sliceouterlen": 6, "slicestarts": [0, 1, 3, 5, 6, 8], "slicestops": [1, 3, 5, 6, 8, 10]}, "outputs": {"carrylen": [10]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 5, 5, 6, 8], "slicestops": [5, 5, 6, 8, 10]}, "outputs": {"carrylen": [10]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 3, 4, 7], "slicestops": [3, 4, 7, 11]}, "outputs": {"carrylen": [11]}}, {"error": false, "inputs": {"sliceouterlen": 6, "slicestarts": [0, 1, 3, 6, 7, 9], "slicestops": [1, 3, 6, 7, 9, 12]}, "outputs": {"carrylen": [12]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 0, 0], "slicestops": [0, 0, 2]}, "outputs": {"carrylen": [2]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 2]}, "outputs": {"carrylen": [2]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 1, 1], "slicestops": [1, 1, 3]}, "outputs": {"carrylen": [3]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 1, 1, 2, 2], "slicestops": [1, 1, 2, 2, 3]}, "outputs": {"carrylen": [3]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"carrylen": [3]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 2, 3, 3], "slicestops": [2, 3, 3, 3]}, "outputs": {"carrylen": [3]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 2, 2, 2, 2], "slicestops": [2, 2, 2, 2, 4]}, "outputs": {"carrylen": [4]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 4]}, "outputs": {"carrylen": [4]}}, {"error": false, "inputs": {"sliceouterlen": 2, "slicestarts": [0, 3], "slicestops": [3, 4]}, "outputs": {"carrylen": [4]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 1, 1, 3, 3], "slicestops": [1, 1, 3, 3, 5]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 3], "slicestops": [2, 3, 5]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 2, 3, 3], "slicestops": [2, 3, 3, 5]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 3, 3], "slicestops": [3, 3, 5]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 4, 5], "slicestops": [4, 4, 6]}, "outputs": {"carrylen": [5]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 1, 3, 4], "slicestops": [1, 3, 4, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 2, 2, 2, 2], "slicestops": [2, 2, 2, 2, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 2, "slicestarts": [0, 3], "slicestops": [3, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 4, 5], "slicestops": [4, 5, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 4, 6], "slicestops": [4, 6, 6]}, "outputs": {"carrylen": [6]}}, {"error": false, "inputs": {"sliceouterlen": 3, "slicestarts": [0, 2, 5], "slicestops": [2, 5, 7]}, "outputs": {"carrylen": [7]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 3, 3, 3, 4], "slicestops": [3, 3, 3, 4, 7]}, "outputs": {"carrylen": [7]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 1, 4, 5], "slicestops": [1, 4, 5, 8]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 7, "slicestarts": [0, 2, 2, 4, 4, 5, 5], "slicestops": [2, 2, 4, 4, 5, 5, 8]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 2, 2, 4, 5], "slicestops": [2, 2, 4, 5, 8]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 4, "slicestarts": [0, 3, 0, 3], "slicestops": [3, 4, 3, 4]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 3, 3, 4, 5], "slicestops": [3, 3, 4, 5, 8]}, "outputs": {"carrylen": [8]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 2, 2, 4, 5], "slicestops": [2, 2, 4, 5, 9]}, "outputs": {"carrylen": [9]}}, {"error": false, "inputs": {"sliceouterlen": 5, "slicestarts": [0, 3, 3, 5, 6], "slicestops": [3, 3, 5, 6, 9]}, "outputs": {"carrylen": [9]}}]}, {"name": "awkward_ListArray_getitem_jagged_descend", "tests": [{"error": false, "inputs": {"fromstarts": [0, 2], "fromstops": [2, 4], "sliceouterlen": 2, "slicestarts": [0, 2], "slicestops": [2, 4]}, "outputs": {"tooffsets": [0, 2, 4]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3, 4], "fromstops": [3, 3, 4, 5], "sliceouterlen": 4, "slicestarts": [0, 3, 3, 4], "slicestops": [3, 3, 4, 5]}, "outputs": {"tooffsets": [0, 3, 3, 4, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceouterlen": 3, "slicestarts": [0, 3, 3], "slicestops": [3, 3, 5]}, "outputs": {"tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"fromstarts": [0, 3], "fromstops": [3, 6], "sliceouterlen": 2, "slicestarts": [0, 3], "slicestops": [3, 6]}, "outputs": {"tooffsets": [0, 3, 6]}}]}, {"name": "awkward_ListArray_getitem_jagged_expand", "tests": [{"error": false, "inputs": {"fromstarts": [0, 2], "fromstops": [2, 4], "jaggedsize": 2, "length": 2, "singleoffsets": [0, 3, 4]}, "outputs": {"multistarts": [0, 3, 0, 3], "multistops": [3, 4, 3, 4], "tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"fromstarts": [2], "fromstops": [4], "jaggedsize": 2, "length": 1, "singleoffsets": [0, 3, 4]}, "outputs": {"multistarts": [0, 3], "multistops": [3, 4], "tocarry": [2, 3]}}]}, {"name": "awkward_ListArray_getitem_next_array", "tests": [{"error": false, "inputs": {"fromarray": [0, 0, 1, 1], "fromstarts": [0], "fromstops": [2], "lenarray": 4, "lencontent": 3, "lenstarts": 1}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 0, 1, 1]}}, {"error": false, "inputs": {"fromarray": [0, 3], "fromstarts": [0, 4, 8], "fromstops": [4, 8, 12], "lenarray": 2, "lencontent": 13, "lenstarts": 3}, "outputs": {"toadvanced": [0, 1, 0, 1, 0, 1], "tocarry": [0, 3, 4, 7, 8, 11]}}, {"error": false, "inputs": {"fromarray": [1, 1, 0, 0], "fromstarts": [0], "fromstops": [2], "lenarray": 4, "lencontent": 3, "lenstarts": 1}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 1, 0, 0]}}, {"error": false, "inputs": {"fromarray": [0, 3], "fromstarts": [4, 8], "fromstops": [8, 12], "lenarray": 2, "lencontent": 13, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1, 0, 1], "tocarry": [4, 7, 8, 11]}}, {"error": false, "inputs": {"fromarray": [2, 1, 1, 0], "fromstarts": [6], "fromstops": [10], "lenarray": 4, "lencontent": 10, "lenstarts": 1}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [8, 7, 7, 6]}}]}, {"name": "awkward_ListArray_min_range", "tests": [{"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5}, "outputs": {"tomin": [0]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "lenstarts": 3}, "outputs": {"tomin": [0]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lenstarts": 5}, "outputs": {"tomin": [0]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lenstarts": 4}, "outputs": {"tomin": [1]}}]}, {"name": "awkward_ListArray_rpad_and_clip_length_axis1", "tests": [{"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5, "target": 1}, "outputs": {"tomin": [10]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lenstarts": 4, "target": 1}, "outputs": {"tomin": [10]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5, "target": 2}, "outputs": {"tomin": [12]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lenstarts": 4, "target": 3}, "outputs": {"tomin": [13]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lenstarts": 5, "target": 2}, "outputs": {"tomin": [13]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5, "target": 3}, "outputs": {"tomin": [15]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "lenstarts": 4, "target": 4}, "outputs": {"tomin": [16]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lenstarts": 5, "target": 3}, "outputs": {"tomin": [16]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "lenstarts": 5, "target": 4}, "outputs": {"tomin": [20]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "lenstarts": 5, "target": 4}, "outputs": {"tomin": [20]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "lenstarts": 3, "target": 3}, "outputs": {"tomin": [9]}}]}, {"name": "awkward_ListArray_validity", "tests": [{"error": false, "inputs": {"lencontent": 0, "length": 5, "starts": [0, 0, 0, 0, 0], "stops": [0, 0, 0, 0, 0]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 0, "length": 4, "starts": [0, 0, 0, 0], "stops": [0, 0, 0, 0]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 0, "length": 3, "starts": [0, 0, 0], "stops": [0, 0, 0]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 1, "length": 3, "starts": [0, 0, 1], "stops": [0, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 3, "starts": [0, 0, 1], "stops": [0, 1, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 1, "length": 4, "starts": [0, 0, 1, 1], "stops": [0, 1, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 4, "starts": [0, 0, 1, 3], "stops": [0, 1, 3, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 5, "starts": [0, 0, 1, 3, 6], "stops": [0, 1, 3, 6, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 19, "length": 8, "starts": [0, 0, 3, 3, 8, 12, 12, 16], "stops": [0, 3, 3, 8, 12, 12, 16, 19]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 19, "length": 9, "starts": [0, 0, 3, 3, 8, 12, 12, 16, 19], "stops": [0, 3, 3, 8, 12, 12, 16, 19, 19]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 3, "starts": [0, 1, 3], "stops": [1, 3, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 15, "length": 5, "starts": [0, 1, 3, 6, 10], "stops": [1, 3, 6, 10, 15]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 12, "length": 6, "starts": [0, 1, 3, 6, 7, 9], "stops": [1, 3, 6, 7, 9, 12]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 8, "length": 4, "starts": [0, 1, 4, 5], "stops": [1, 4, 5, 8]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 3, "length": 3, "starts": [0, 2, 2], "stops": [2, 2, 3]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 3, "starts": [0, 2, 2], "stops": [2, 2, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 3, "length": 2, "starts": [0, 2], "stops": [2, 3]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 2, "starts": [0, 2], "stops": [2, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 8, "length": 7, "starts": [0, 2, 2, 4, 4, 5, 5], "stops": [2, 2, 4, 4, 5, 5, 8]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 5, "starts": [0, 2, 2, 4, 5], "stops": [2, 2, 4, 5, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 5, "starts": [0, 2, 2, 4, 5], "stops": [2, 2, 4, 5, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 3, "length": 3, "starts": [0, 2, 3], "stops": [2, 3, 3]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 3, "starts": [0, 2, 3], "stops": [2, 3, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 5, "length": 3, "starts": [0, 2, 3], "stops": [2, 3, 5]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 3, "starts": [0, 2, 3], "stops": [2, 3, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 5, "length": 4, "starts": [0, 2, 3, 3], "stops": [2, 3, 3, 5]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 7, "length": 4, "starts": [0, 2, 3, 4], "stops": [2, 3, 4, 7]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 3, "starts": [0, 2, 4], "stops": [2, 4, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 7, "length": 3, "starts": [0, 2, 5], "stops": [2, 5, 7]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 8, "length": 3, "starts": [0, 2, 6], "stops": [2, 6, 8]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 5, "length": 3, "starts": [0, 3, 3], "stops": [3, 3, 5]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 7, "length": 3, "starts": [0, 3, 3], "stops": [3, 3, 7]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 8, "length": 3, "starts": [0, 3, 3], "stops": [3, 3, 8]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 4, "length": 2, "starts": [0, 3], "stops": [3, 4]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 4, "starts": [0, 3, 3, 5], "stops": [3, 3, 5, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 11, "length": 6, "starts": [0, 3, 3, 5, 6, 10], "stops": [3, 3, 5, 6, 10, 11]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 5, "starts": [0, 3, 3, 5, 6], "stops": [3, 3, 5, 6, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 6, "starts": [0, 3, 3, 5, 6, 8], "stops": [3, 3, 5, 6, 8, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 2, "starts": [0, 3], "stops": [3, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 7, "length": 2, "starts": [0, 3], "stops": [3, 7]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 11, "length": 4, "starts": [0, 3, 4, 7], "stops": [3, 4, 7, 11]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 25, "length": 7, "starts": [0, 3, 6, 11, 14, 17, 20], "stops": [3, 6, 11, 14, 17, 20, 25]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 20, "length": 6, "starts": [0, 3, 6, 11, 14, 17], "stops": [3, 6, 11, 14, 17, 20]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 19, "length": 5, "starts": [0, 3, 6, 11, 15], "stops": [3, 6, 11, 15, 19]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 3, "starts": [0, 3, 6], "stops": [3, 6, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 11, "length": 3, "starts": [0, 3, 6], "stops": [3, 6, 11]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 21, "length": 9, "starts": [0, 3, 6, 6, 10, 14, 14, 18, 21], "stops": [3, 6, 6, 10, 14, 14, 18, 21, 21]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 21, "length": 8, "starts": [0, 3, 6, 6, 10, 14, 14, 18], "stops": [3, 6, 6, 10, 14, 14, 18, 21]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 22, "length": 9, "starts": [0, 3, 6, 6, 11, 15, 15, 19, 22], "stops": [3, 6, 6, 11, 15, 15, 19, 22, 22]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 22, "length": 8, "starts": [0, 3, 6, 6, 11, 15, 15, 19], "stops": [3, 6, 6, 11, 15, 15, 19, 22]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 24, "length": 9, "starts": [0, 3, 6, 8, 13, 17, 17, 21, 24], "stops": [3, 6, 8, 13, 17, 17, 21, 24, 24]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 24, "length": 8, "starts": [0, 3, 6, 8, 13, 17, 17, 21], "stops": [3, 6, 8, 13, 17, 17, 21, 24]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 9, "length": 3, "starts": [0, 3, 7], "stops": [3, 7, 9]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 2, "starts": [0, 4], "stops": [4, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 6, "length": 3, "starts": [0, 4, 4], "stops": [4, 4, 6]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 3, "starts": [0, 4, 6], "stops": [4, 6, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 14, "length": 4, "starts": [0, 4, 6, 9], "stops": [4, 6, 9, 14]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 11, "length": 6, "starts": [0, 4, 7, 7, 9, 9], "stops": [4, 7, 7, 9, 9, 11]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 12, "length": 3, "starts": [0, 4, 8], "stops": [4, 8, 12]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 30, "length": 6, "starts": [0, 5, 10, 15, 20, 25], "stops": [5, 10, 15, 20, 25, 30]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 10, "length": 2, "starts": [0, 5], "stops": [5, 10]}, "outputs": {}}, {"error": false, "inputs": {"lencontent": 12, "length": 6, "starts": [3, 0, 999, 2, 6, 10], "stops": [7, 3, 999, 4, 6, 12]}, "outputs": {}}]}, {"name": "awkward_ListArray_getitem_jagged_apply", "tests": [{"error": false, "inputs": {"contentlen": 0, "fromstarts": [0, 0, 0, 0], "fromstops": [0, 0, 0, 0], "sliceindex": [], "sliceinnerlen": 0, "sliceouterlen": 4, "slicestarts": [0, 0, 0, 0], "slicestops": [0, 0, 0, 0]}, "outputs": {"tocarry": [], "tooffsets": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [], "sliceinnerlen": 0, "sliceouterlen": 3, "slicestarts": [0, 0, 0], "slicestops": [0, 0, 0]}, "outputs": {"tocarry": [], "tooffsets": [0, 0, 0, 0]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1], "sliceinnerlen": 2, "sliceouterlen": 3, "slicestarts": [0, 0, 0], "slicestops": [0, 0, 2]}, "outputs": {"tocarry": [3, 4], "tooffsets": [0, 0, 0, 2]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 0, 1], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 1, 1], "slicestops": [1, 1, 3]}, "outputs": {"tocarry": [0, 3, 4], "tooffsets": [0, 1, 1, 3]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [2, 0, 1], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 1, 1], "slicestops": [1, 1, 3]}, "outputs": {"tocarry": [2, 3, 4], "tooffsets": [0, 1, 1, 3]}}, {"error": false, "inputs": {"contentlen": 10, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 10], "sliceindex": [1, 0, 1, 0, 3], "sliceinnerlen": 5, "sliceouterlen": 5, "slicestarts": [0, 1, 1, 3, 3], "slicestops": [1, 1, 3, 3, 5]}, "outputs": {"tocarry": [1, 3, 4, 6, 9], "tooffsets": [0, 1, 1, 3, 3, 5]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1], "sliceinnerlen": 2, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 2]}, "outputs": {"tocarry": [0, 1], "tooffsets": [0, 2, 2, 2]}}, {"error": false, "inputs": {"contentlen": 4, "fromstarts": [0, 1, 1, 1, 1], "fromstops": [1, 1, 1, 1, 4], "sliceindex": [0, 0, 2, 1, 1, 2], "sliceinnerlen": 6, "sliceouterlen": 5, "slicestarts": [0, 2, 2, 2, 2], "slicestops": [2, 2, 2, 2, 6]}, "outputs": {"tocarry": [0, 0, 3, 2, 2, 3], "tooffsets": [0, 2, 2, 2, 2, 6]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1, 0], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"tocarry": [0, 1, 3], "tooffsets": [0, 2, 2, 3]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1, 1], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"tocarry": [0, 1, 4], "tooffsets": [0, 2, 2, 3]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [2, 0, 1], "sliceinnerlen": 3, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"tocarry": [2, 0, 4], "tooffsets": [0, 2, 2, 3]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 2, 0, 1], "sliceinnerlen": 4, "sliceouterlen": 3, "slicestarts": [0, 2, 2], "slicestops": [2, 2, 4]}, "outputs": {"tocarry": [0, 2, 3, 4], "tooffsets": [0, 2, 2, 4]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [0, 2, 0, 1, 0, 0, 1, 2], "sliceinnerlen": 8, "sliceouterlen": 5, "slicestarts": [0, 2, 2, 4, 5], "slicestops": [2, 2, 4, 5, 8]}, "outputs": {"tocarry": [0, 2, 3, 4, 5, 6, 7, 8], "tooffsets": [0, 2, 2, 4, 5, 8]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [1, 2, 0, 1, 0, 0, 1, 2], "sliceinnerlen": 8, "sliceouterlen": 5, "slicestarts": [0, 2, 2, 4, 5], "slicestops": [2, 2, 4, 5, 8]}, "outputs": {"tocarry": [1, 2, 3, 4, 5, 6, 7, 8], "tooffsets": [0, 2, 2, 4, 5, 8]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [0, 1, 2, 0, 0, 1, 2], "sliceinnerlen": 7, "sliceouterlen": 5, "slicestarts": [0, 3, 3, 3, 4], "slicestops": [3, 3, 3, 4, 7]}, "outputs": {"tocarry": [0, 1, 2, 5, 6, 7, 8], "tooffsets": [0, 3, 3, 3, 4, 7]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [0, 1, 2, 1, 0, 0, 1, 2], "sliceinnerlen": 8, "sliceouterlen": 5, "slicestarts": [0, 3, 3, 4, 5], "slicestops": [3, 3, 4, 5, 8]}, "outputs": {"tocarry": [0, 1, 2, 4, 5, 6, 7, 8], "tooffsets": [0, 3, 3, 4, 5, 8]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [0, 1, 2, 0, 1], "sliceinnerlen": 5, "sliceouterlen": 3, "slicestarts": [0, 3, 3], "slicestops": [3, 3, 5]}, "outputs": {"tocarry": [0, 1, 2, 3, 4], "tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"contentlen": 5, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "sliceindex": [2, 1, 0, 0, 1], "sliceinnerlen": 5, "sliceouterlen": 3, "slicestarts": [0, 3, 3], "slicestops": [3, 3, 5]}, "outputs": {"tocarry": [2, 1, 0, 3, 4], "tooffsets": [0, 3, 3, 5]}}, {"error": false, "inputs": {"contentlen": 9, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 9], "sliceindex": [0, 1, 2, 0, 1, 0, 0, 1, 2], "sliceinnerlen": 9, "sliceouterlen": 5, "slicestarts": [0, 3, 3, 5, 6], "slicestops": [3, 3, 5, 6, 9]}, "outputs": {"tocarry": [0, 1, 2, 3, 4, 5, 6, 7, 8], "tooffsets": [0, 3, 3, 5, 6, 9]}}, {"error": false, "inputs": {"contentlen": 6, "fromstarts": [0, 3], "fromstops": [3, 6], "sliceindex": [2, 1, 0, 2, 1, 0], "sliceinnerlen": 6, "sliceouterlen": 2, "slicestarts": [0, 3], "slicestops": [3, 6]}, "outputs": {"tocarry": [2, 1, 0, 5, 4, 3], "tooffsets": [0, 3, 6]}}, {"error": false, "inputs": {"contentlen": 6, "fromstarts": [0, 3, 5], "fromstops": [3, 5, 6], "sliceindex": [2, 1, 1, 0, 1, 0], "sliceinnerlen": 6, "sliceouterlen": 3, "slicestarts": [0, 4, 5], "slicestops": [4, 4, 6]}, "outputs": {"tocarry": [2, 1, 1, 0, 5], "tooffsets": [0, 4, 4, 5]}}, {"error": false, "inputs": {"contentlen": 6, "fromstarts": [0, 3, 5], "fromstops": [3, 5, 6], "sliceindex": [2, 1, 1, 0, 1, 0], "sliceinnerlen": 6, "sliceouterlen": 3, "slicestarts": [0, 4, 5], "slicestops": [4, 5, 6]}, "outputs": {"tocarry": [2, 1, 1, 0, 4, 5], "tooffsets": [0, 4, 5, 6]}}, {"error": false, "inputs": {"contentlen": 8, "fromstarts": [0, 4, 7], "fromstops": [4, 7, 8], "sliceindex": [3, 2, 2, 1, 1, 2], "sliceinnerlen": 6, "sliceouterlen": 3, "slicestarts": [0, 4, 6], "slicestops": [4, 6, 6]}, "outputs": {"tocarry": [3, 2, 2, 1, 5, 6], "tooffsets": [0, 4, 6, 6]}}, {"error": false, "inputs": {"contentlen": 13, "fromstarts": [0, 4, 4, 7, 8], "fromstops": [4, 4, 7, 8, 13], "sliceindex": [3, 2, 1, 1, 0, 1, 0, 0, 1, 2], "sliceinnerlen": 10, "sliceouterlen": 5, "slicestarts": [0, 5, 5, 6, 8], "slicestops": [5, 5, 6, 8, 10]}, "outputs": {"tocarry": [3, 2, 1, 1, 0, 5, 7, 7, 9, 10], "tooffsets": [0, 5, 5, 6, 8, 10]}}]}, {"name": "awkward_UnionArray_regular_index", "tests": [{"error": false, "inputs": {"fromtags": [0, 1, 0, 1, 0, 1], "length": 6, "size": 2}, "outputs": {"current": [3, 3], "toindex": [0, 0, 1, 1, 2, 2]}}, {"error": false, "inputs": {"fromtags": [1, 0, 1, 1], "length": 4, "size": 2}, "outputs": {"current": [1, 3], "toindex": [0, 0, 1, 2]}}, {"error": false, "inputs": {"fromtags": [1, 1, 0, 0, 1, 0, 1, 1], "length": 8, "size": 2}, "outputs": {"current": [3, 5], "toindex": [0, 1, 0, 1, 2, 2, 3, 4]}}]}, {"name": "awkward_UnionArray_regular_index_getsize", "tests": [{"error": false, "inputs": {"fromtags": [0, 1, 0, 1, 0, 1], "length": 6}, "outputs": {"size": [2]}}, {"error": false, "inputs": {"fromtags": [1, 0, 1, 1], "length": 4}, "outputs": {"size": [2]}}, {"error": false, "inputs": {"fromtags": [1, 1, 0, 0, 1, 0, 1, 1], "length": 8}, "outputs": {"size": [2]}}]}, {"name": "awkward_IndexedArray_fill", "tests": [{"error": false, "inputs": {"base": 0, "fromindex": [0, 1, -1, -1, 4], "length": 5, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, -1, -1, 4]}}, {"error": false, "inputs": {"base": 0, "fromindex": [0, 1, 2, 3, -1], "length": 5, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2, 3, -1]}}, {"error": false, "inputs": {"base": 0, "fromindex": [0, 1, 2], "length": 3, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"base": 0, "fromindex": [-1, -1, 0, -1, 1, 2], "length": 6, "toindexoffset": 0}, "outputs": {"toindex": [-1, -1, 0, -1, 1, 2]}}, {"error": false, "inputs": {"base": 0, "fromindex": [2, 0, -1, 0, 1, 2], "length": 6, "toindexoffset": 0}, "outputs": {"toindex": [2, 0, -1, 0, 1, 2]}}]}, {"name": "awkward_ListArray_fill", "tests": [{"error": false, "inputs": {"base": 0, "fromstarts": [0, 0, 1], "fromstops": [0, 1, 3], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 0, 1], "tostops": [0, 1, 3]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 2, 2], "fromstops": [2, 2, 4], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 2, 2], "tostops": [2, 2, 4]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 2, 4], "fromstops": [2, 4, 6], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 2, 4], "tostops": [2, 4, 6]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 3, 3, 5, 6], "fromstops": [3, 3, 5, 6, 10], "length": 5, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 3, 3, 5, 6], "tostops": [3, 3, 5, 6, 10]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 3, 3], "fromstops": [3, 3, 5], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 3, 3], "tostops": [3, 3, 5]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 3, 6], "fromstops": [3, 6, 11], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 3, 6], "tostops": [3, 6, 11]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 5, 10], "fromstops": [5, 10, 15], "length": 3, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 5, 10], "tostops": [5, 10, 15]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [0, 7], "fromstops": [7, 14], "length": 2, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [0, 7], "tostops": [7, 14]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [1, 3, 3, 3], "fromstops": [3, 3, 3, 5], "length": 4, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [1, 3, 3, 3], "tostops": [3, 3, 3, 5]}}, {"error": false, "inputs": {"base": 0, "fromstarts": [3, 5], "fromstops": [5, 5], "length": 2, "tostartsoffset": 0, "tostopsoffset": 0}, "outputs": {"tostarts": [3, 5], "tostops": [5, 5]}}]}, {"name": "awkward_UnionArray_fillindex", "tests": [{"error": false, "inputs": {"fromindex": [0, 0, 1, 1], "length": 4, "toindexoffset": 0}, "outputs": {"toindex": [0, 0, 1, 1]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 0, 1, 2], "length": 6, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2, 0, 1, 2]}}]}, {"name": "awkward_UnionArray_validity", "tests": [{"error": false, "inputs": {"index": [0, 1, 2, 3, 0, 1], "lencontents": [4, 2, 0, 945], "length": 6, "numcontents": 2, "tags": [0, 0, 0, 0, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 2, 0, 1, 2, 3], "lencontents": [3, 4], "length": 7, "numcontents": 2, "tags": [0, 0, 0, 1, 1, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 1, 0, 1, 2, 3], "lencontents": [2, 4, 32, 49, 0, 0], "length": 6, "numcontents": 2, "tags": [0, 0, 1, 1, 1, 1]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 0, 1, 1, 2, 3, 2, 4], "lencontents": [5, 3, 32, 33], "length": 8, "numcontents": 2, "tags": [0, 1, 1, 0, 0, 0, 1, 0]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 0, 1, 1, 2, 3, 2, 4], "lencontents": [5, 3, 32, 625, 0, 0, 0], "length": 8, "numcontents": 2, "tags": [0, 1, 1, 0, 0, 0, 1, 0]}, "outputs": {}}, {"error": false, "inputs": {"index": [0, 0, 1, 1, 2, 2, 3], "lencontents": [3, 4, 32, 177], "length": 7, "numcontents": 2, "tags": [0, 1, 1, 0, 0, 1, 1]}, "outputs": {}}]}, {"name": "awkward_ByteMaskedArray_reduce_next_nonlocal_nextshifts_64", "tests": [{"error": false, "inputs": {"length": 7, "mask": [0, 0, 0, 1, 1, 0, 0], "valid_when": false}, "outputs": {"nextshifts": [0, 0, 0, 2, 2]}}]}, {"name": "awkward_IndexedArray_index_of_nulls", "tests": [{"error": false, "inputs": {"fromindex": [-1, -1, 0, 1, 2, -1, -1, -1, 3, -1, 4, 5, -1, -1, 6, 7, 8], "lenindex": 17, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4], "starts": [0, 5, 8, 11, 14]}, "outputs": {"toindex": [0, 1, 0, 1, 2, 1, 1, 2]}}, {"error": false, "inputs": {"fromindex": [-1, -1, 3, 5, 6, -1, -1, -1, -1, 7, 0, -1, 4, -1, 8, 1, 2], "lenindex": 17, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4], "starts": [0, 5, 10, 15, 16]}, "outputs": {"toindex": [0, 1, 0, 1, 2, 3, 1, 3]}}, {"error": false, "inputs": {"fromindex": [-1, -1, 0, 1, 2], "lenindex": 5, "parents": [0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"fromindex": [0, -1, 3, 5, 6, 1, -1, 4, -1, 7, 2, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "lenindex": 25, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4], "starts": [0, 5, 10, 15, 20]}, "outputs": {"toindex": [1, 1, 3, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromindex": [0, -1, 1, 2, -1, 3, 4, 5], "lenindex": 8, "parents": [0, 0, 0, 0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [1, 4]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2], "lenindex": 4, "parents": [0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [2]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, -1, 4], "lenindex": 5, "parents": [0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [2, 3]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2, 3, -1], "lenindex": 6, "parents": [0, 0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"toindex": [2, 5]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2, 3, -1, 4, 5, -1, 6, 7, -1], "lenindex": 12, "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"toindex": [2, 5, 2, 5]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, -1, -1, -1, -1, 7, 8], "lenindex": 9, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 1], "starts": [0, 4]}, "outputs": {"toindex": [3, 0, 1, 2]}}]}, {"name": "awkward_IndexedArray_reduce_next_fix_offsets_64", "tests": [{"error": false, "inputs": {"outindexlength": 6, "starts": [0, 1, 2, 5], "startslength": 4}, "outputs": {"outoffsets": [0, 1, 2, 5, 6]}}, {"error": false, "inputs": {"outindexlength": 2, "starts": [0], "startslength": 1}, "outputs": {"outoffsets": [0, 2]}}, {"error": false, "inputs": {"outindexlength": 9, "starts": [0, 3, 3, 5, 6], "startslength": 5}, "outputs": {"outoffsets": [0, 3, 3, 5, 6, 9]}}, {"error": false, "inputs": {"outindexlength": 6, "starts": [0, 3], "startslength": 2}, "outputs": {"outoffsets": [0, 3, 6]}}, {"error": false, "inputs": {"outindexlength": 4, "starts": [0], "startslength": 1}, "outputs": {"outoffsets": [0, 4]}}, {"error": false, "inputs": {"outindexlength": 5, "starts": [0], "startslength": 1}, "outputs": {"outoffsets": [0, 5]}}, {"error": false, "inputs": {"outindexlength": 8, "starts": [0], "startslength": 1}, "outputs": {"outoffsets": [0, 8]}}]}, {"name": "awkward_IndexedArray_reduce_next_nonlocal_nextshifts_64", "tests": [{"error": false, "inputs": {"index": [0, 1, 2, -1, 3, -1, 4], "length": 7}, "outputs": {"nextshifts": [0, 0, 0, 1, 2]}}, {"error": false, "inputs": {"index": [0, 1, 2, -1, -1, -1, -1, 7, 8], "length": 9}, "outputs": {"nextshifts": [0, 0, 0, 4, 4]}}, {"error": false, "inputs": {"index": [0, 1, -1, 2, 3, -1], "length": 6}, "outputs": {"nextshifts": [0, 0, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, -1, 2, 3, 4], "length": 6}, "outputs": {"nextshifts": [0, 0, 1, 1, 1]}}, {"error": false, "inputs": {"index": [0, 1, -1, 2, 3, -1, 4], "length": 7}, "outputs": {"nextshifts": [0, 0, 1, 1, 2]}}, {"error": false, "inputs": {"index": [0, 1, -1, 2, 3, -1, 4, 5, -1, 6, 7, -1], "length": 12}, "outputs": {"nextshifts": [0, 0, 1, 1, 2, 2, 3, 3]}}, {"error": false, "inputs": {"index": [0, 1, -1, -1, 4], "length": 5}, "outputs": {"nextshifts": [0, 0, 2]}}, {"error": false, "inputs": {"index": [4, 2, -1, -1, 1, 0, 1], "length": 7}, "outputs": {"nextshifts": [0, 0, 2, 2, 2]}}, {"error": false, "inputs": {"index": [-1, -1, 0, 1, 2], "length": 5}, "outputs": {"nextshifts": [2, 2, 2]}}, {"error": false, "inputs": {"index": [-1, -1, 0, 1, 2, -1, -1, -1, 3, -1, 4, 5, -1, -1, 6, 7, 8], "length": 17}, "outputs": {"nextshifts": [2, 2, 2, 5, 6, 6, 8, 8, 8]}}]}, {"name": "awkward_IndexedArray_reduce_next_nonlocal_nextshifts_fromshifts_64", "tests": [{"error": false, "inputs": {"index": [0, 3, 4, 1, -1, 5, 2], "length": 7, "shifts": [0, 0, 1, 0, 0, 1, 0]}, "outputs": {"nextshifts": [0, 0, 1, 0, 2, 1]}}, {"error": false, "inputs": {"index": [0, 3, 4, 1, -1, 5, 2], "length": 7, "shifts": [0, 1, 1, 0, 1, 1, 0]}, "outputs": {"nextshifts": [0, 1, 1, 0, 2, 1]}}, {"error": false, "inputs": {"index": [0, -1, 3, 5, 6, 1, -1, 4, -1, 7, 2, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "length": 25, "shifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"nextshifts": [0, 1, 1, 1, 1, 2, 3, 3, 6]}}, {"error": false, "inputs": {"index": [0, -1, 4, 1, 3, 5, 2], "length": 7, "shifts": [0, 1, 1, 0, 1, 1, 0]}, "outputs": {"nextshifts": [0, 2, 1, 2, 2, 1]}}, {"error": false, "inputs": {"index": [-1, -1, 3, 5, 6, -1, -1, -1, -1, 7, 0, -1, 4, -1, 8, 1, 2], "length": 17, "shifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"nextshifts": [2, 2, 2, 6, 6, 7, 8, 8, 8]}}]}, {"name": "awkward_ListArray_getitem_next_array_advanced", "tests": [{"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [0, 0], "fromstarts": [0, 0], "fromstops": [1, 1], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [0, 0]}}, {"error": false, "inputs": {"fromadvanced": [0], "fromarray": [0], "fromstarts": [0], "fromstops": [2], "lenarray": 1, "lencontent": 4, "lenstarts": 1}, "outputs": {"toadvanced": [0], "tocarry": [0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [0, 0, 0, 0], "fromstops": [3, 3, 3, 3], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 1, 2, 1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "fromstarts": [0, 3, 3, 3], "fromstops": [3, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [0, 3, 3, 3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [1, 0], "fromstarts": [0, 0], "fromstops": [3, 3], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [0, 0, 0, 0], "fromstops": [3, 3, 3, 3], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 0, 0, 1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [0, 0], "fromstarts": [1, 0], "fromstops": [3, 2], "lenarray": 2, "lencontent": 3, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [10, 11, 14, 11]}}, {"error": false, "inputs": {"fromadvanced": [0], "fromarray": [0], "fromstarts": [1], "fromstops": [3], "lenarray": 1, "lencontent": 3, "lenstarts": 1}, "outputs": {"toadvanced": [0], "tocarry": [1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [11, 10, 10, 11]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, -2, 0, -1], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [11, 13, 10, 14]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, -2, 0, -1], "fromstarts": [10, 0, 0, 5], "fromstops": [15, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [11, 3, 0, 9]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [0, 15, 15, 15], "fromstops": [5, 20, 20, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 15, 15, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [1, 2], "fromstarts": [0, 0], "fromstops": [3, 3], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [1, 2]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 0, 0, 1], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [12, 10, 10, 11]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [2, 2, 2, 2], "fromstarts": [10, 0, 0, 5], "fromstops": [15, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [12, 2, 2, 7]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-2, -2, -2, -2], "fromstarts": [10, 10, 10, 10], "fromstops": [15, 15, 15, 15], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [13, 13, 13, 13]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-2, -2, -2, -2], "fromstarts": [10, 0, 0, 5], "fromstops": [15, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [13, 3, 3, 8]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [0, 3, 3, 3], "fromstops": [3, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 3, 3, 4]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [0, 5, 10, 5], "fromstops": [5, 10, 15, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [1, 5, 10, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [15, 0, 0, 15], "fromstops": [20, 5, 5, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [15, 1, 4, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [15, 15, 15, 15], "fromstops": [20, 20, 20, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [15, 16, 19, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [15, 15, 15, 15], "fromstops": [20, 20, 20, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [16, 15, 15, 16]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [15, 0, 0, 15], "fromstops": [20, 5, 5, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [19, 4, 4, 19]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [-1, 0], "fromstarts": [0, 0], "fromstops": [3, 3], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [0, 0, 0, 0], "fromstops": [3, 3, 3, 3], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 2, 2, 2]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [1, 2], "fromstarts": [1, 1], "fromstops": [4, 4], "lenarray": 2, "lencontent": 4, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [0, 3, 3, 3], "fromstops": [3, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [2, 5, 5, 5]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "fromstarts": [3, 0, 0, 3], "fromstops": [6, 3, 3, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 0, 0, 3]}}, {"error": false, "inputs": {"fromadvanced": [0], "fromarray": [1], "fromstarts": [2], "fromstops": [5], "lenarray": 1, "lencontent": 5, "lenstarts": 1}, "outputs": {"toadvanced": [0], "tocarry": [3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [-1, 0], "fromstarts": [1, 1], "fromstops": [4, 4], "lenarray": 2, "lencontent": 4, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [3, 1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [3, 0, 0, 3], "fromstops": [6, 3, 3, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 1, 2, 4]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 0, 0, 0], "fromstarts": [3, 3, 3, 3], "fromstops": [6, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 3, 3, 3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [3, 3, 3, 3], "fromstops": [6, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [3, 4, 5, 4]}}, {"error": false, "inputs": {"fromadvanced": [0, 1], "fromarray": [1, 1], "fromstarts": [3, 0], "fromstops": [5, 3], "lenarray": 2, "lencontent": 5, "lenstarts": 2}, "outputs": {"toadvanced": [0, 1], "tocarry": [4, 1]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 1, 0, 0], "fromstarts": [3, 0, 0, 6], "fromstops": [5, 3, 3, 9], "lenarray": 4, "lencontent": 9, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 1, 0, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [0, 15, 15, 15], "fromstops": [5, 20, 20, 20], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 19, 19, 19]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, -1, 0, 0], "fromstarts": [3, 0, 0, 3], "fromstops": [5, 3, 3, 5], "lenarray": 4, "lencontent": 5, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 2, 0, 3]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 0, 0, 1], "fromstarts": [3, 3, 3, 3], "fromstops": [6, 6, 6, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 3, 3, 4]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [0, 5, 10, 5], "fromstops": [5, 10, 15, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [4, 9, 14, 9]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3, 4, 5], "fromarray": [2, 0, 1, 1, 2, 0], "fromstarts": [3, 0, 3, 3, 3, 0], "fromstops": [6, 3, 6, 6, 6, 3], "lenarray": 6, "lencontent": 6, "lenstarts": 6}, "outputs": {"toadvanced": [0, 1, 2, 3, 4, 5], "tocarry": [5, 0, 4, 4, 5, 0]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [0, 1, -1, 1], "fromstarts": [5, 0, 0, 5], "fromstops": [10, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [5, 1, 4, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [3, 0, 0, 3], "fromstops": [6, 3, 3, 6], "lenarray": 4, "lencontent": 6, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [5, 2, 2, 5]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [1, 1, 0, 0], "fromstarts": [6, 0, 0, 6], "fromstops": [9, 3, 3, 9], "lenarray": 4, "lencontent": 9, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [7, 1, 0, 6]}}, {"error": false, "inputs": {"fromadvanced": [0, 1, 2, 3], "fromarray": [-1, -1, -1, -1], "fromstarts": [5, 0, 0, 5], "fromstops": [10, 5, 5, 10], "lenarray": 4, "lencontent": 30, "lenstarts": 4}, "outputs": {"toadvanced": [0, 1, 2, 3], "tocarry": [9, 4, 4, 9]}}]}, {"name": "awkward_ListArray_getitem_next_at", "tests": [{"error": false, "inputs": {"at": 0, "fromstarts": [], "fromstops": [], "lenstarts": 0}, "outputs": {"tocarry": []}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0], "fromstops": [1], "lenstarts": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0], "fromstops": [2], "lenstarts": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": -5, "fromstarts": [0], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [0]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 1], "fromstops": [1, 2], "lenstarts": 2}, "outputs": {"tocarry": [0, 1]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 1, 2, 3], "fromstops": [1, 2, 3, 4], "lenstarts": 4}, "outputs": {"tocarry": [0, 1, 2, 3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 1, 2, 3, 4], "fromstops": [1, 2, 3, 4, 5], "lenstarts": 5}, "outputs": {"tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 2, 3], "fromstops": [2, 3, 5], "lenstarts": 3}, "outputs": {"tocarry": [0, 2, 3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [0, 3, 5, 6], "fromstops": [3, 5, 6, 10], "lenstarts": 4}, "outputs": {"tocarry": [0, 3, 5, 6]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [10], "fromstops": [15], "lenstarts": 1}, "outputs": {"tocarry": [10]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0], "fromstops": [2], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [0], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [10], "fromstops": [15], "lenstarts": 1}, "outputs": {"tocarry": [11]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [1], "fromstops": [2], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [1], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [1]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [10], "fromstops": [15], "lenstarts": 1}, "outputs": {"tocarry": [13]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0, 3], "fromstops": [3, 5], "lenstarts": 2}, "outputs": {"tocarry": [1, 4]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [0, 5], "fromstops": [5, 10], "lenstarts": 2}, "outputs": {"tocarry": [1, 6]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [15], "fromstops": [20], "lenstarts": 1}, "outputs": {"tocarry": [16]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [15], "fromstops": [20], "lenstarts": 1}, "outputs": {"tocarry": [18]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [15], "fromstops": [20], "lenstarts": 1}, "outputs": {"tocarry": [19]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [0], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [1], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [1], "fromstops": [4], "lenstarts": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [2], "fromstops": [3], "lenstarts": 1}, "outputs": {"tocarry": [2]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [2], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [3], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [3], "fromstops": [6], "lenstarts": 1}, "outputs": {"tocarry": [3]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [3, 5, 6], "fromstops": [5, 6, 9], "lenstarts": 3}, "outputs": {"tocarry": [3, 5, 6]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [0], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": 4, "fromstarts": [0], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [3], "fromstops": [5], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [3], "fromstops": [6], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [3], "fromstops": [6], "lenstarts": 1}, "outputs": {"tocarry": [4]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [3, 5, 6], "fromstops": [5, 6, 9], "lenstarts": 3}, "outputs": {"tocarry": [4, 5, 8]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [0, 5], "fromstops": [5, 10], "lenstarts": 2}, "outputs": {"tocarry": [4, 9]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [5, 10], "fromstops": [10, 15], "lenstarts": 2}, "outputs": {"tocarry": [5, 10]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [3], "fromstops": [6], "lenstarts": 1}, "outputs": {"tocarry": [5]}}, {"error": false, "inputs": {"at": 0, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [5]}}, {"error": false, "inputs": {"at": -5, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [5]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [5, 10], "fromstops": [10, 15], "lenstarts": 2}, "outputs": {"tocarry": [6, 11]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [6]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [6], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [7]}}, {"error": false, "inputs": {"at": 1, "fromstarts": [6], "fromstops": [9], "lenstarts": 1}, "outputs": {"tocarry": [7]}}, {"error": false, "inputs": {"at": -2, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [8]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [5, 10], "fromstops": [10, 15], "lenstarts": 2}, "outputs": {"tocarry": [9, 14]}}, {"error": false, "inputs": {"at": -1, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [9]}}, {"error": false, "inputs": {"at": 4, "fromstarts": [5], "fromstops": [10], "lenstarts": 1}, "outputs": {"tocarry": [9]}}]}, {"name": "awkward_ListArray_getitem_next_range_counts", "tests": [{"error": false, "inputs": {"fromoffsets": [0, 2, 2, 4, 4, 5, 6, 7, 9, 9], "lenstarts": 9}, "outputs": {"total": [9]}}, {"error": false, "inputs": {"fromoffsets": [0, 2, 4, 5, 6, 7, 9], "lenstarts": 6}, "outputs": {"total": [9]}}]}, {"name": "awkward_ListArray_localindex", "tests": [{"error": false, "inputs": {"length": 1, "offsets": [0, 1]}, "outputs": {"toindex": [0]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 2, 3, 5]}, "outputs": {"toindex": [0, 1, 0, 0, 1]}}, {"error": false, "inputs": {"length": 4, "offsets": [0, 2, 3, 3, 6]}, "outputs": {"toindex": [0, 1, 0, 0, 1, 2]}}, {"error": false, "inputs": {"length": 2, "offsets": [0, 2, 3]}, "outputs": {"toindex": [0, 1, 0]}}, {"error": false, "inputs": {"length": 1, "offsets": [0, 2]}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 4, "offsets": [0, 3, 3, 4, 5]}, "outputs": {"toindex": [0, 1, 2, 0, 0]}}, {"error": false, "inputs": {"length": 7, "offsets": [0, 3, 3, 5, 6, 10, 10, 13]}, "outputs": {"toindex": [0, 1, 2, 0, 1, 0, 0, 1, 2, 3, 0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 3, 3, 5, 6, 10]}, "outputs": {"toindex": [0, 1, 2, 0, 1, 0, 0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 6, "offsets": [0, 3, 3, 5, 6, 6, 10]}, "outputs": {"toindex": [0, 1, 2, 0, 1, 0, 0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 3, "offsets": [0, 3, 3, 5]}, "outputs": {"toindex": [0, 1, 2, 0, 1]}}, {"error": false, "inputs": {"length": 5, "offsets": [0, 4, 4, 7, 8, 13]}, "outputs": {"toindex": [0, 1, 2, 3, 0, 1, 2, 0, 0, 1, 2, 3, 4]}}]}, {"name": "awkward_ListArray_rpad_axis1", "tests": [{"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5, "target": 4}, "outputs": {"toindex": [0, 1, 2, -1, -1, -1, -1, -1, 4, 5, -1, -1, 5, 6, 7, -1, 8, -1, -1, -1], "tostarts": [0, 4, 8, 12, 16], "tostops": [4, 8, 12, 16, 20]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5, "target": 3}, "outputs": {"toindex": [0, 1, 2, -1, -1, -1, 4, 5, -1, 5, 6, 7, 8, -1, -1], "tostarts": [0, 3, 6, 9, 12], "tostops": [3, 6, 9, 12, 15]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 5], "fromstops": [3, 3, 7], "length": 3, "target": 3}, "outputs": {"toindex": [0, 1, 2, -1, -1, -1, 5, 6, -1], "tostarts": [0, 3, 6], "tostops": [3, 6, 9]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5, "target": 2}, "outputs": {"toindex": [0, 1, 2, -1, -1, 4, 5, 5, 6, 7, 8, -1], "tostarts": [0, 3, 5, 7, 10], "tostops": [3, 5, 7, 10, 12]}}, {"error": false, "inputs": {"fromstarts": [0, 3, 4, 5, 8], "fromstops": [3, 3, 6, 8, 9], "length": 5, "target": 1}, "outputs": {"toindex": [0, 1, 2, -1, 4, 5, 5, 6, 7, 8], "tostarts": [0, 3, 4, 6, 9], "tostops": [3, 4, 6, 9, 10]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "length": 4, "target": 4}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, -1, -1, 3, 4, -1, -1, 0, 1, 2, -1], "tostarts": [0, 4, 8, 12], "tostops": [4, 8, 12, 16]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "length": 5, "target": 4}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, -1, -1, 3, 4, -1, -1, -1, -1, -1, -1, 0, 1, 2, -1], "tostarts": [0, 4, 8, 12, 16], "tostops": [4, 8, 12, 16, 20]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "length": 4, "target": 3}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, -1, 3, 4, -1, 0, 1, 2], "tostarts": [0, 4, 7, 10], "tostops": [4, 7, 10, 13]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "length": 5, "target": 3}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, -1, 3, 4, -1, -1, -1, -1, 0, 1, 2], "tostarts": [0, 4, 7, 10, 13], "tostops": [4, 7, 10, 13, 16]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 3, 0], "fromstops": [10, 6, 5, 3, 3], "length": 5, "target": 2}, "outputs": {"toindex": [6, 7, 8, 9, 5, -1, 3, 4, -1, -1, 0, 1, 2], "tostarts": [0, 4, 6, 8, 10], "tostops": [4, 6, 8, 10, 13]}}, {"error": false, "inputs": {"fromstarts": [6, 5, 3, 0], "fromstops": [10, 6, 5, 3], "length": 4, "target": 1}, "outputs": {"toindex": [6, 7, 8, 9, 5, 3, 4, 0, 1, 2], "tostarts": [0, 4, 5, 7], "tostops": [4, 5, 7, 10]}}]}, {"name": "awkward_ListOffsetArray_reduce_local_outoffsets_64", "tests": [{"error": false, "inputs": {"lenparents": 10, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 10]}}, {"error": false, "inputs": {"lenparents": 1, "outlength": 1, "parents": [0]}, "outputs": {"outoffsets": [0, 1]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 3, "parents": [0, 2, 2]}, "outputs": {"outoffsets": [0, 1, 1, 3]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 4, "parents": [0, 1, 3]}, "outputs": {"outoffsets": [0, 1, 2, 2, 3]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 3, "parents": [0, 1, 1]}, "outputs": {"outoffsets": [0, 1, 3, 3]}}, {"error": false, "inputs": {"lenparents": 4, "outlength": 3, "parents": [0, 1, 1, 2]}, "outputs": {"outoffsets": [0, 1, 3, 4]}}, {"error": false, "inputs": {"lenparents": 2, "outlength": 1, "parents": [0, 0]}, "outputs": {"outoffsets": [0, 2]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 5, "parents": [0, 0, 2, 2, 3, 4]}, "outputs": {"outoffsets": [0, 2, 2, 4, 5, 6]}}, {"error": false, "inputs": {"lenparents": 7, "outlength": 5, "parents": [0, 0, 2, 2, 3, 4, 4]}, "outputs": {"outoffsets": [0, 2, 2, 4, 5, 7]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 2, "parents": [0, 0, 1]}, "outputs": {"outoffsets": [0, 2, 3]}}, {"error": false, "inputs": {"lenparents": 4, "outlength": 2, "parents": [0, 0, 1, 1]}, "outputs": {"outoffsets": [0, 2, 4]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"outoffsets": [0, 3]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 2, "parents": [0, 0, 0, 1, 1, 1]}, "outputs": {"outoffsets": [0, 3, 6]}}, {"error": false, "inputs": {"lenparents": 4, "outlength": 1, "parents": [0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 4]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 0, 2, 2]}, "outputs": {"outoffsets": [0, 4, 4, 6]}}, {"error": false, "inputs": {"lenparents": 8, "outlength": 2, "parents": [0, 0, 0, 0, 1, 1, 1, 1]}, "outputs": {"outoffsets": [0, 4, 8]}}, {"error": false, "inputs": {"lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 5]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 6]}}, {"error": false, "inputs": {"lenparents": 7, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 7]}}, {"error": false, "inputs": {"lenparents": 8, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 8]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0, 0, 0, 0]}, "outputs": {"outoffsets": [0, 9]}}]}, {"name": "awkward_ListOffsetArray_reduce_nonlocal_nextshifts_64", "tests": [{"error": false, "inputs": {"length": 3, "maxcount": 5, "nextcarry": [0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14], "nextlen": 15, "offsets": [0, 5, 10, 15], "parents": [0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nummissing": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"length": 2, "maxcount": 3, "nextcarry": [0, 3, 1, 4, 2, 5], "nextlen": 6, "offsets": [0, 3, 6], "parents": [0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0], "nummissing": [0, 0, 0]}}, {"error": false, "inputs": {"length": 3, "maxcount": 5, "nextcarry": [0, 5, 9, 1, 6, 10, 2, 7, 11, 3, 8, 4], "nextlen": 12, "offsets": [0, 5, 9, 12], "parents": [0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nummissing": [0, 0, 0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "maxcount": 5, "nextcarry": [0, 5, 8, 11, 14, 1, 6, 9, 12, 15, 2, 7, 10, 13, 16, 3, 4], "nextlen": 17, "offsets": [0, 5, 8, 11, 14, 17], "parents": [0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "nummissing": [0, 0, 0, 4, 4]}}, {"error": false, "inputs": {"length": 4, "maxcount": 3, "nextcarry": [0, 2, 5, 7, 1, 3, 6, 8, 4], "nextlen": 9, "offsets": [0, 2, 5, 7, 9], "parents": [0, 0, 1, 1], "starts": [0, 2]}, "outputs": {"missing": [0, 0, 0, 0, 1, 0, 0, 0, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 1], "nummissing": [0, 0, 2]}}, {"error": false, "inputs": {"length": 3, "maxcount": 4, "nextcarry": [0, 2, 3, 1, 4, 5, 6], "nextlen": 7, "offsets": [0, 2, 3, 7], "parents": [0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 1, 2, 2], "nextshifts": [0, 0, 0, 0, 1, 2, 2], "nummissing": [0, 1, 2, 2]}}, {"error": false, "inputs": {"length": 10, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2], "nummissing": [0, 2, 4]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 2, 2], "nummissing": [0, 2, 4]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 3, 2], "nummissing": [0, 2, 4]}}, {"error": false, "inputs": {"length": 3, "maxcount": 4, "nextcarry": [0, 3, 1, 4, 2, 5, 6], "nextlen": 7, "offsets": [0, 3, 3, 7], "parents": [0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 1, 1, 1, 2], "nextshifts": [0, 1, 0, 1, 0, 1, 2], "nummissing": [1, 1, 1, 2]}}, {"error": false, "inputs": {"length": 4, "maxcount": 3, "nextcarry": [0, 3, 5, 1, 4, 6, 2], "nextlen": 7, "offsets": [0, 3, 5, 5, 7], "parents": [0, 0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 0, 0, 1, 1], "nextshifts": [0, 0, 1, 0, 0, 1, 0], "nummissing": [1, 1, 3]}}, {"error": false, "inputs": {"length": 4, "maxcount": 3, "nextcarry": [0, 3, 5, 1, 4, 6, 2], "nextlen": 7, "offsets": [0, 3, 3, 5, 7], "parents": [0, 0, 0, 0], "starts": [0]}, "outputs": {"missing": [0, 0, 0, 1, 1, 1, 1], "nextshifts": [0, 1, 1, 0, 1, 1, 0], "nummissing": [1, 1, 3]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 18, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2, 0, 1, 1], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 15, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2, 1, 2, 1], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 10, 12, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1, 1, 2, 3, 1, 2, 1], "nextshifts": [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 11, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 1, 1, 2, 1, 2, 3, 1, 2, 1], "nextshifts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 15, 17, 18, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 15, 17, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 1], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 15, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 0, 1, 2, 1, 2, 1], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 10, 12, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 0, 0, 1, 1, 2, 3, 1, 2, 1], "nextshifts": [0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 3, 1, 2, 1], "nextshifts": [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 18, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 0], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 3, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 0, 1, 2, 0, 1, 1], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 2, 2, 2, 1, 1, 1, 3, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 15, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 0, 1, 2, 1, 2, 1], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 2, 3, 2], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 10, 12, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 0, 0, 1, 1, 2, 3, 1, 2, 1], "nextshifts": [1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 2, 2, 2, 1, 2, 2, 3, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 1, 1, 2, 1, 2, 3, 1, 2, 1], "nextshifts": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3], "nummissing": [1, 3, 5]}}, {"error": false, "inputs": {"length": 12, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 8, 9, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], "starts": [0, 5]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 0, 1, 0, 2, 2, 3, 2, 3, 4, 2, 3, 2], "nextshifts": [0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 2, 4], "nummissing": [2, 4, 6]}}, {"error": false, "inputs": {"length": 13, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 1, 3, 6, 6, 8, 9, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [0, 0, 1, 0, 1, 2, 1, 2, 1, 2, 2, 3, 2, 3, 4, 2, 3, 2], "nextshifts": [0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 3, 3, 3, 2, 4], "nummissing": [2, 4, 6]}}, {"error": false, "inputs": {"length": 13, "maxcount": 3, "nextcarry": [0, 1, 3, 6, 8, 9, 10, 12, 15, 17, 2, 4, 7, 11, 13, 16, 5, 14], "nextlen": 18, "offsets": [0, 0, 1, 3, 6, 8, 9, 9, 9, 10, 12, 15, 17, 18], "parents": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], "starts": [0, 6]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, 4, 2, 3, 2], "nextshifts": [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4], "nummissing": [2, 4, 6]}}, {"error": false, "inputs": {"length": 9, "maxcount": 4, "nextcarry": [0, 1, 3, 6, 10, 13, 15, 2, 4, 7, 11, 14, 5, 8, 12, 9], "nextlen": 16, "offsets": [0, 0, 1, 3, 6, 10, 13, 15, 16, 16], "parents": [0, 0, 0, 0, 0, 0, 0, 0, 0], "starts": [0]}, "outputs": {"missing": [1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 1, 2, 1], "nextshifts": [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4], "nummissing": [2, 4, 6, 8]}}]}, {"name": "awkward_ListOffsetArray_reduce_nonlocal_nextstarts_64", "tests": [{"error": false, "inputs": {"nextlen": 18, "nextparents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 2, 5]}, "outputs": {"nextstarts": [0, 10, 16, 5, 13, 17]}}, {"error": false, "inputs": {"nextlen": 21, "nextparents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 4, 2, 5, 5, 5]}, "outputs": {"nextstarts": [0, 10, 17, 5, 13, 18]}}, {"error": false, "inputs": {"nextlen": 3, "nextparents": [0, 1, 2]}, "outputs": {"nextstarts": [0, 1, 2]}}, {"error": false, "inputs": {"nextlen": 5, "nextparents": [0, 0, 1, 2, 3]}, "outputs": {"nextstarts": [0, 2, 3, 4]}}, {"error": false, "inputs": {"nextlen": 6, "nextparents": [0, 0, 1, 1, 2, 2]}, "outputs": {"nextstarts": [0, 2, 4]}}, {"error": false, "inputs": {"nextlen": 6, "nextparents": [0, 0, 1, 1, 2, 3]}, "outputs": {"nextstarts": [0, 2, 4, 5]}}, {"error": false, "inputs": {"nextlen": 8, "nextparents": [0, 0, 1, 1, 2, 2, 3, 3]}, "outputs": {"nextstarts": [0, 2, 4, 6]}}, {"error": false, "inputs": {"nextlen": 7, "nextparents": [0, 0, 1, 1, 2, 2, 3]}, "outputs": {"nextstarts": [0, 2, 4, 6]}}, {"error": false, "inputs": {"nextlen": 6, "nextparents": [0, 0, 0, 1, 1, 1]}, "outputs": {"nextstarts": [0, 3]}}, {"error": false, "inputs": {"nextlen": 5, "nextparents": [0, 0, 0, 1, 1]}, "outputs": {"nextstarts": [0, 3]}}, {"error": false, "inputs": {"nextlen": 7, "nextparents": [0, 0, 0, 1, 1, 2, 3]}, "outputs": {"nextstarts": [0, 3, 5, 6]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 0, 1, 1, 2, 2, 3, 4]}, "outputs": {"nextstarts": [0, 3, 5, 7, 8]}}, {"error": false, "inputs": {"nextlen": 7, "nextparents": [0, 0, 0, 1, 1, 1, 2]}, "outputs": {"nextstarts": [0, 3, 6]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 3]}, "outputs": {"nextstarts": [0, 3, 6, 8]}}, {"error": false, "inputs": {"nextlen": 10, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"nextstarts": [0, 3, 6, 9]}}, {"error": false, "inputs": {"nextlen": 12, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"nextstarts": [0, 3, 6, 9]}}, {"error": false, "inputs": {"nextlen": 12, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4]}, "outputs": {"nextstarts": [0, 3, 6, 9, 11]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"nextstarts": [0, 3, 6, 9, 12]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 5, 5, 1, 6, 6, 2, 7, 7, 3, 8, 8, 4, 9, 9]}, "outputs": {"nextstarts": [0, 3, 6, 9, 12, 1, 4, 7, 10, 13]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14]}, "outputs": {"nextstarts": [0, 3, 6, 9, 12, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 0, 5, 1, 1, 6, 2, 2, 7, 3, 3, 8, 4, 4, 9]}, "outputs": {"nextstarts": [0, 3, 6, 9, 12, 2, 5, 8, 11, 14]}}, {"error": false, "inputs": {"nextlen": 6, "nextparents": [0, 0, 0, 0, 1, 1]}, "outputs": {"nextstarts": [0, 4]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 0, 0, 1, 1, 1, 2, 2]}, "outputs": {"nextstarts": [0, 4, 7]}}, {"error": false, "inputs": {"nextlen": 20, "nextparents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]}, "outputs": {"nextstarts": [0, 4, 8, 12, 16]}}, {"error": false, "inputs": {"nextlen": 20, "nextparents": [0, 0, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 3, 8, 8, 4, 4, 9, 9]}, "outputs": {"nextstarts": [0, 4, 8, 12, 16, 2, 6, 10, 14, 18]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 3, 3, 1, 1, 4, 4, 2]}, "outputs": {"nextstarts": [0, 4, 8, 2, 6]}}, {"error": false, "inputs": {"nextlen": 12, "nextparents": [0, 0, 3, 3, 1, 1, 4, 4, 2, 2, 5, 5]}, "outputs": {"nextstarts": [0, 4, 8, 2, 6, 10]}}, {"error": false, "inputs": {"nextlen": 15, "nextparents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"nextstarts": [0, 5, 10]}}, {"error": false, "inputs": {"nextlen": 17, "nextparents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4]}, "outputs": {"nextstarts": [0, 5, 10, 15, 16]}}, {"error": false, "inputs": {"nextlen": 25, "nextparents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]}, "outputs": {"nextstarts": [0, 5, 10, 15, 20]}}, {"error": false, "inputs": {"nextlen": 9, "nextparents": [0, 0, 0, 3, 3, 1, 1, 4, 2]}, "outputs": {"nextstarts": [0, 5, 8, 3, 7]}}, {"error": false, "inputs": {"nextlen": 22, "nextparents": [0, 0, 0, 5, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 3, 8, 8, 4, 4, 9, 9]}, "outputs": {"nextstarts": [0, 6, 10, 14, 18, 3, 8, 12, 16, 20]}}, {"error": false, "inputs": {"nextlen": 16, "nextparents": [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"nextstarts": [0, 7, 12, 15]}}]}, {"name": "awkward_ListOffsetArray_reduce_nonlocal_outstartsstops_64", "tests": [{"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 5, 15]}}, {"error": false, "inputs": {"distincts": [0, 0], "lendistincts": 2, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [2]}}, {"error": false, "inputs": {"distincts": [0, 0, 0], "lendistincts": 3, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [3]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 1, 1, -1], "lendistincts": 6, "outlength": 2}, "outputs": {"outstarts": [0, 3], "outstops": [3, 5]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 1, 1, 1], "lendistincts": 6, "outlength": 2}, "outputs": {"outstarts": [0, 3], "outstops": [3, 6]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 1, 1, -1, 2, -1, -1], "lendistincts": 9, "outlength": 3}, "outputs": {"outstarts": [0, 3, 6], "outstops": [3, 5, 7]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 1, -1, -1, 2, 1, -1, 3, -1, -1], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [3, 4, 8, 10]}}, {"error": false, "inputs": {"distincts": [0, 0, -1, 1, -1, -1, -1, -1, -1, 2, 1, 0], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [2, 4, 6, 12]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0], "lendistincts": 4, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [4]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, -1, 1, 1, 1, 0], "lendistincts": 8, "outlength": 2}, "outputs": {"outstarts": [0, 4], "outstops": [3, 8]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0], "lendistincts": 5, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [5]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, -1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 10, 14]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 10, 15]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, -1, -1, -1, -1, 2, 1, 1, 1, 1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 6, 15]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, -1, 2, 2, 2, 2, 1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 9, 15]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1], "lendistincts": 15, "outlength": 3}, "outputs": {"outstarts": [0, 5, 10], "outstops": [5, 10, 10]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1], "lendistincts": 10, "outlength": 2}, "outputs": {"outstarts": [0, 5], "outstops": [5, 10]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, -1, -1, -1, 1, 1, -1], "lendistincts": 9, "outlength": 3}, "outputs": {"outstarts": [0, 3, 6], "outstops": [3, 3, 8]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, -1, -1, -1, 1, 1, 1], "lendistincts": 9, "outlength": 3}, "outputs": {"outstarts": [0, 3, 6], "outstops": [3, 3, 9]}}, {"error": false, "inputs": {"distincts": [0, 0, -1, -1, -1, -1, 1, -1, -1, 2, 1, 0], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [2, 3, 7, 12]}}, {"error": false, "inputs": {"distincts": [0, 0, -1, -1, -1, -1, -1, -1, -1, 1, 1, 0], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [2, 3, 6, 12]}}, {"error": false, "inputs": {"distincts": [0, 0, 0, -1, -1, -1, -1, -1, -1, 1, 1, 1], "lendistincts": 12, "outlength": 4}, "outputs": {"outstarts": [0, 3, 6, 9], "outstops": [3, 3, 6, 12]}}, {"error": false, "inputs": {"distincts": [], "lendistincts": 0, "outlength": 1}, "outputs": {"outstarts": [0], "outstops": [0]}}]}, {"name": "awkward_NumpyArray_reduce_mask_ByteMaskedArray_64", "tests": [{"error": false, "inputs": {"lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 18, "outlength": 6, "parents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 2, 5]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 21, "outlength": 6, "parents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 4, 2, 5, 5, 5]}, "outputs": {"toptr": [0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 20, "outlength": 5, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 15, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 12, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 1, 2, 2, 3, 4]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [0, 0]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 7, "outlength": 4, "parents": [0, 0, 0, 1, 1, 2, 3]}, "outputs": {"toptr": [0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"toptr": [0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 5, "parents": [0, 0, 3, 3, 1, 1, 4, 4, 2]}, "outputs": {"toptr": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 1, 1, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 0, 1, 1, 1, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 5, "outlength": 3, "parents": [0, 0, 1, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 22, "outlength": 8, "parents": [0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 1, 1, 1, 5, 5, 5, 5, 2, 6, 6, 6, 7]}, "outputs": {"toptr": [0, 0, 0, 1, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 2, 2, 4, 4, 4]}, "outputs": {"toptr": [0, 0, 0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [0, 0, 0, 1, 1, 1, 0, 0]}}, {"error": false, "inputs": {"lenparents": 12, "outlength": 9, "parents": [0, 0, 6, 6, 1, 1, 7, 7, 2, 2, 8, 8]}, "outputs": {"toptr": [0, 0, 0, 1, 1, 1, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 1, 1, 3]}, "outputs": {"toptr": [0, 0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 3, 3, 3]}, "outputs": {"toptr": [0, 0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [0, 1, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 4]}, "outputs": {"toptr": [0, 1, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 2, 2, 2]}, "outputs": {"toptr": [0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 3, "parents": [0, 0, 2]}, "outputs": {"toptr": [0, 1, 0]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 7, "parents": [0, 0, 0, 2, 2, 3, 6, 6, 6]}, "outputs": {"toptr": [0, 1, 0, 0, 1, 1, 0]}}]}, {"name": "awkward_UnionArray_fillna", "tests": [{"error": false, "inputs": {"fromindex": [-1, -1, -1, -1, -1], "length": 5}, "outputs": {"toindex": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [-1, -1, 0, -1, 1, 2, 3, 4, 5, -1, -1, -1], "length": 12}, "outputs": {"toindex": [0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [-1, 0, 1, -1], "length": 4}, "outputs": {"toindex": [0, 0, 1, 0]}}, {"error": false, "inputs": {"fromindex": [0, -1, 1], "length": 3}, "outputs": {"toindex": [0, 0, 1]}}, {"error": false, "inputs": {"fromindex": [0, -1, 1, -1, 2], "length": 5}, "outputs": {"toindex": [0, 0, 1, 0, 2]}}, {"error": false, "inputs": {"fromindex": [0, -1, 1, 2], "length": 4}, "outputs": {"toindex": [0, 0, 1, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1], "length": 3}, "outputs": {"toindex": [0, 1, 0]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2], "length": 4}, "outputs": {"toindex": [0, 1, 0, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, -1, 2, 3, -1, 4], "length": 7}, "outputs": {"toindex": [0, 1, 0, 2, 3, 0, 4]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, -1, -1, -1], "length": 6}, "outputs": {"toindex": [0, 1, 2, 0, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, -1, -1, 3, 4, 5, -1, -1], "length": 10}, "outputs": {"toindex": [0, 1, 2, 0, 0, 3, 4, 5, 0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4, -1, -1], "length": 7}, "outputs": {"toindex": [0, 1, 2, 3, 4, 0, 0]}}, {"error": false, "inputs": {"fromindex": [13, 9, 13, 4, 8, 3, 15, -1, 16, 2, 8], "length": 11}, "outputs": {"toindex": [13, 9, 13, 4, 8, 3, 15, 0, 16, 2, 8]}}]}, {"name": "awkward_UnionArray_filltags", "tests": [{"error": false, "inputs": {"base": 0, "fromtags": [0, 0, 0, 1, 1, 1], "length": 6, "totagsoffset": 0}, "outputs": {"totags": [0, 0, 0, 1, 1, 1]}}]}, {"name": "awkward_UnionArray_project", "tests": [{"error": false, "inputs": {"fromindex": [], "fromtags": [], "length": 0, "which": 0}, "outputs": {"lenout": [0], "tocarry": []}}, {"error": false, "inputs": {"fromindex": [], "fromtags": [], "length": 0, "which": 1}, "outputs": {"lenout": [0], "tocarry": []}}, {"error": false, "inputs": {"fromindex": [1], "fromtags": [1], "length": 1, "which": 1}, "outputs": {"lenout": [1], "tocarry": [1]}}, {"error": false, "inputs": {"fromindex": [0, 0], "fromtags": [1, 1], "length": 2, "which": 1}, "outputs": {"lenout": [2], "tocarry": [0, 0]}}, {"error": false, "inputs": {"fromindex": [0, 1], "fromtags": [0, 0], "length": 2, "which": 0}, "outputs": {"lenout": [2], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromindex": [0, 1], "fromtags": [1, 1], "length": 2, "which": 1}, "outputs": {"lenout": [2], "tocarry": [0, 1]}}, {"error": false, "inputs": {"fromindex": [2, 3], "fromtags": [0, 0], "length": 2, "which": 0}, "outputs": {"lenout": [2], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromindex": [2, 3], "fromtags": [1, 1], "length": 2, "which": 1}, "outputs": {"lenout": [2], "tocarry": [2, 3]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2], "fromtags": [0, 0, 0], "length": 3, "which": 0}, "outputs": {"lenout": [3], "tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2], "fromtags": [1, 1, 1], "length": 3, "which": 1}, "outputs": {"lenout": [3], "tocarry": [0, 1, 2]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4], "fromtags": [0, 0, 0, 0, 0], "length": 5, "which": 0}, "outputs": {"lenout": [5], "tocarry": [0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"fromindex": [0, 1, 2, 3, 4], "fromtags": [1, 1, 1, 1, 1], "length": 5, "which": 1}, "outputs": {"lenout": [5], "tocarry": [0, 1, 2, 3, 4]}}]}, {"name": "awkward_UnionArray_simplify_one", "tests": [{"error": false, "inputs": {"base": 0, "fromindex": [], "fromtags": [], "fromwhich": 0, "length": 0, "towhich": 0}, "outputs": {"toindex": [], "totags": []}}, {"error": false, "inputs": {"base": 0, "fromindex": [0, 0, 0, 0, 0], "fromtags": [1, 1, 1, 1, 1], "fromwhich": 1, "length": 5, "towhich": 0}, "outputs": {"toindex": [0, 0, 0, 0, 0], "totags": [0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"base": 9, "fromindex": [0, 1, 2, 3, 4, 5, 6, 7, 8], "fromtags": [1, 1, 1, 1, 1, 1, 1, 1, 1], "fromwhich": 1, "length": 9, "towhich": 0}, "outputs": {"toindex": [9, 10, 11, 12, 13, 14, 15, 16, 17], "totags": [0, 0, 0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"base": 0, "fromindex": [0, 1], "fromtags": [1, 1], "fromwhich": 1, "length": 2, "towhich": 0}, "outputs": {"toindex": [0, 1], "totags": [0, 0]}}, {"error": false, "inputs": {"base": 0, "fromindex": [0], "fromtags": [1], "fromwhich": 1, "length": 1, "towhich": 0}, "outputs": {"toindex": [0], "totags": [0]}}, {"error": false, "inputs": {"base": 0, "fromindex": [], "fromtags": [], "fromwhich": 1, "length": 0, "towhich": 0}, "outputs": {"toindex": [], "totags": []}}, {"error": false, "inputs": {"base": 0, "fromindex": [], "fromtags": [], "fromwhich": 1, "length": 0, "towhich": 1}, "outputs": {"toindex": [], "totags": []}}]}, {"name": "awkward_localindex", "tests": [{"error": false, "inputs": {"length": 0}, "outputs": {"toindex": []}}, {"error": false, "inputs": {"length": 2}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 4}, "outputs": {"toindex": [0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 5}, "outputs": {"toindex": [0, 1, 2, 3, 4]}}]}, {"name": "awkward_BitMaskedArray_to_IndexedOptionArray", "tests": [{"error": false, "inputs": {"bitmasklength": 2, "frombitmask": [58, 59], "lsb_order": false, "validwhen": false}, "outputs": {"toindex": [0, 1, -1, -1, -1, 5, -1, 7, 8, 9, -1, -1, -1, 13, -1, -1]}}, {"error": false, "inputs": {"bitmasklength": 2, "frombitmask": [58, 59], "lsb_order": true, "validwhen": false}, "outputs": {"toindex": [0, -1, 2, -1, -1, -1, 6, 7, -1, -1, 10, -1, -1, -1, 14, 15]}}]}, {"name": "awkward_ListArray_getitem_jagged_shrink", "tests": [{"error": false, "inputs": {"length": 1, "missing": [0, 0, 0, 0], "slicestarts": [0, 1, 1, 1], "slicestops": [4]}, "outputs": {"tocarry": [0, 1, 2, 3], "tolargeoffsets": [0, 4], "tosmalloffsets": [0, 4]}}, {"error": false, "inputs": {"length": 2, "missing": [0, 0, 0, 0], "slicestarts": [0, 2, 2], "slicestops": [2, 2, 3]}, "outputs": {"tocarry": [0, 1], "tolargeoffsets": [0, 2, 2], "tosmalloffsets": [0, 2, 2]}}, {"error": false, "inputs": {"length": 2, "missing": [0, 0, 0, 0], "slicestarts": [0, 2, 2], "slicestops": [2, 2, 4]}, "outputs": {"tocarry": [0, 1], "tolargeoffsets": [0, 2, 2], "tosmalloffsets": [0, 2, 2]}}, {"error": false, "inputs": {"length": 3, "missing": [0, 0, 0, 0], "slicestarts": [0, 2, 3, 3], "slicestops": [2, 3, 3, 4]}, "outputs": {"tocarry": [0, 1, 2], "tolargeoffsets": [0, 2, 3, 3], "tosmalloffsets": [0, 2, 3, 3]}}, {"error": false, "inputs": {"length": 3, "missing": [0, 0, 0, 0], "slicestarts": [0, 2, 3, 3], "slicestops": [2, 3, 3, 6]}, "outputs": {"tocarry": [0, 1, 2], "tolargeoffsets": [0, 2, 3, 3], "tosmalloffsets": [0, 2, 3, 3]}}]}, {"name": "awkward_Content_getitem_next_missing_jagged_getmaskstartstop", "tests": [{"error": false, "inputs": {"index_in": [0, -1], "length": 2, "offsets_in": [0, 1]}, "outputs": {"mask_out": [0, -1], "starts_out": [0, 1], "stops_out": [1, 1]}}, {"error": false, "inputs": {"index_in": [0, -1], "length": 2, "offsets_in": [0, 4]}, "outputs": {"mask_out": [0, -1], "starts_out": [0, 4], "stops_out": [4, 4]}}, {"error": false, "inputs": {"index_in": [0, -1, -1], "length": 3, "offsets_in": [0, 1]}, "outputs": {"mask_out": [0, -1, -1], "starts_out": [0, 1, 1], "stops_out": [1, 1, 1]}}, {"error": false, "inputs": {"index_in": [0, -1, 1], "length": 3, "offsets_in": [0, 1, 2]}, "outputs": {"mask_out": [0, -1, 2], "starts_out": [0, 1, 1], "stops_out": [1, 1, 2]}}, {"error": false, "inputs": {"index_in": [0, -1, 1], "length": 3, "offsets_in": [0, 2, 4]}, "outputs": {"mask_out": [0, -1, 2], "starts_out": [0, 2, 2], "stops_out": [2, 2, 4]}}, {"error": false, "inputs": {"index_in": [0, -1, -1, 1], "length": 4, "offsets_in": [0, 0, 0]}, "outputs": {"mask_out": [0, -1, -1, 3], "starts_out": [0, 0, 0, 0], "stops_out": [0, 0, 0, 0]}}, {"error": false, "inputs": {"index_in": [0, -1, -1, 1], "length": 4, "offsets_in": [0, 1, 2]}, "outputs": {"mask_out": [0, -1, -1, 3], "starts_out": [0, 1, 1, 1], "stops_out": [1, 1, 1, 2]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, -1], "length": 4, "offsets_in": [0, 2, 3]}, "outputs": {"mask_out": [0, -1, 2, -1], "starts_out": [0, 2, 2, 3], "stops_out": [2, 2, 3, 3]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, -1, 2], "length": 5, "offsets_in": [0, 2, 2, 4]}, "outputs": {"mask_out": [0, -1, 2, -1, 4], "starts_out": [0, 2, 2, 2, 2], "stops_out": [2, 2, 2, 2, 4]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 0, 0, 0]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 0, 0, 0], "stops_out": [0, 0, 0, 0]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 0, 1, 1]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 0, 1, 1], "stops_out": [0, 1, 1, 1]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2], "length": 4, "offsets_in": [0, 1, 2, 3]}, "outputs": {"mask_out": [0, -1, 2, 3], "starts_out": [0, 1, 1, 2], "stops_out": [1, 1, 2, 3]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 3, 3]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 3]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 3, 4]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 4]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 3, 5]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 5]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2], "length": 4, "offsets_in": [0, 2, 3, 5]}, "outputs": {"mask_out": [0, -1, 2, 3], "starts_out": [0, 2, 2, 3], "stops_out": [2, 2, 3, 5]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 3, 6]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 3, 3], "stops_out": [2, 3, 3, 6]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 2, 4, 5]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 2, 4, 4], "stops_out": [2, 4, 4, 5]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2], "length": 4, "offsets_in": [0, 3, 3, 4]}, "outputs": {"mask_out": [0, -1, 2, 3], "starts_out": [0, 3, 3, 3], "stops_out": [3, 3, 3, 4]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 3, 3, 5]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 3, 3, 3], "stops_out": [3, 3, 3, 5]}}, {"error": false, "inputs": {"index_in": [0, 1, -1, 2], "length": 4, "offsets_in": [0, 4, 5, 6]}, "outputs": {"mask_out": [0, 1, -1, 3], "starts_out": [0, 4, 5, 5], "stops_out": [4, 5, 5, 6]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2], "length": 4, "offsets_in": [0, 4, 5, 6]}, "outputs": {"mask_out": [0, -1, 2, 3], "starts_out": [0, 4, 4, 5], "stops_out": [4, 4, 5, 6]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2, -1, 3, 4, 5], "length": 8, "offsets_in": [0, 2, 4, 6, 8, 10, 12]}, "outputs": {"mask_out": [0, -1, 2, 3, -1, 5, 6, 7], "starts_out": [0, 2, 2, 4, 6, 6, 8, 10], "stops_out": [2, 2, 4, 6, 6, 8, 10, 12]}}, {"error": false, "inputs": {"index_in": [0, -1, 1, 2, 3, 4, 5, 6], "length": 8, "offsets_in": [0, 1, 1, 1, 1, 1, 1, 1]}, "outputs": {"mask_out": [0, -1, 2, 3, 4, 5, 6, 7], "starts_out": [0, 1, 1, 1, 1, 1, 1, 1], "stops_out": [1, 1, 1, 1, 1, 1, 1, 1]}}]}, {"name": "awkward_reduce_sum_bool", "tests": [{"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 0, 1, 0, 0, 0], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 0, 1, 0, 0, 1, 0, 1, 1], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [1, 0, 0, 1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 0, 1, 0, 1, 0, 0, 1, 1], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [1, 0, 1, 0, 0, 0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [0, 1, 1, 0, 1, 0, 0, 0, 0, 0], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 0, 2, 0, 0, 0, 0, 0], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 0, 0, 2, 2, 0, 3, 0, 0, 0], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [1]}}]}, {"name": "awkward_reduce_prod_bool", "tests": [{"error": false, "inputs": {"fromptr": [1, 0, 1, 0, 1, 0, 0, 1, 1], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [0, 0, 1, 1, 1, 1, 0, 1]}}, {"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 1], "lenparents": 6, "outlength": 2, "parents": [0, 0, 0, 1, 1, 1]}, "outputs": {"toptr": [0, 1]}}, {"error": false, "inputs": {"fromptr": [1, 0, 1, 0, 0, 1, 0, 1, 1], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [0, 1, 0, 1, 0, 1]}}, {"error": false, "inputs": {"fromptr": [1, 0, 0, 1, 1, 1, 1, 0, 0, 1], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 0, 1]}}, {"error": false, "inputs": {"fromptr": [1, 0, 0, 2, 2, 2, 3, 0, 0, 4], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 0, 1]}}, {"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 1, 1, 1, 1, 1], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 25, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5]}, "outputs": {"toptr": [0, 1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], "lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [0, 1, 1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], "lenparents": 22, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5]}, "outputs": {"toptr": [1, 0, 0, 1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 0, 1, 0, 0, 1, 0, 1], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 0, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 19, "outlength": 5, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4]}, "outputs": {"toptr": [1, 0, 0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 0, 2, 0, 0, 2, 0, 4], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 0, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 0, 0, 0], "lenparents": 6, "outlength": 2, "parents": [0, 0, 0, 1, 1, 1]}, "outputs": {"toptr": [1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 0, 0, 0], "lenparents": 9, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1], "lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [1, 1, 0, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 11, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 17, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [1, 1, 1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 19, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [1, 1, 1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "lenparents": 22, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5]}, "outputs": {"toptr": [1, 1, 1, 1, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [1]}}]}, {"name": "awkward_reduce_argmax", "tests": [{"error": false, "inputs": {"fromptr": [1, -1, 1, -1, 1, 21], "lenparents": 6, "outlength": 3, "parents": [0, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [0, 2, 5]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 6, 7], "lenparents": 6, "outlength": 3, "parents": [0, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [0, 2, 5]}}, {"error": false, "inputs": {"fromptr": [6, 1, 10, 33, -1, 21, 2, 45, 4], "lenparents": 9, "outlength": 5, "parents": [0, 0, 3, 3, 1, 1, 4, 4, 2]}, "outputs": {"toptr": [0, 5, 8, 3, 7]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 6], "lenparents": 5, "outlength": 3, "parents": [0, 0, 1, 2, 2]}, "outputs": {"toptr": [1, 2, 4]}}, {"error": false, "inputs": {"fromptr": [3, 4, 2, 1, 2, 3, 6, 1, -1, 1, 7, 4], "lenparents": 12, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4]}, "outputs": {"toptr": [1, 5, 6, 10, 11]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [2]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 6], "lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 1, 1, 2]}, "outputs": {"toptr": [2, 4, 5]}}, {"error": false, "inputs": {"fromptr": [3, 1, 6, 1, 4, 4, 2, 1, 7, 2, 3, -1], "lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [2, 8, 10]}}, {"error": false, "inputs": {"fromptr": [0, 0, 4, 4, 6], "lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [4]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 6], "lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [4]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [5]}}]}, {"name": "awkward_reduce_max", "tests": [{"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "identity": -9223372036854775808, "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [13, 11, 5, -9223372036854775808, -9223372036854775808, -9223372036854775808, 23, 19]}}, {"error": false, "inputs": {"fromptr": [0, 1, 3, 4, 5, 6], "identity": -9223372036854775808, "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 3, 3, 3]}, "outputs": {"toptr": [1, 3, -9223372036854775808, 6]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "identity": -9223372036854775808, "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [3]}}, {"error": false, "inputs": {"fromptr": [0, 4, 1, 3, 5, 6], "identity": -9223372036854775808, "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 1, 1, 3]}, "outputs": {"toptr": [4, 5, -9223372036854775808, 6]}}, {"error": false, "inputs": {"fromptr": [1, 2, 5, 3, 3, 5, 1, 4, 2], "identity": -9223372036854775808, "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 1, 2, 2, 3, 4]}, "outputs": {"toptr": [5, 3, 5, 4, 2]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 2, 3, 1, 5], "identity": 4, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [5, 4, 4, 5]}}, {"error": false, "inputs": {"fromptr": [1, 3, 6, 4, 2, 2, 3, 1, 6], "identity": 4, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [6, 4, 4, 6]}}, {"error": false, "inputs": {"fromptr": [1, 3, 2, 5, 3, 7, 3, 1, 5, 8, 1, 9, 4, 2, 7, 10, 2, 4, 7, 2], "identity": -9223372036854775808, "lenparents": 20, "outlength": 5, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]}, "outputs": {"toptr": [5, 7, 9, 10, 7]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 3, 7, 8, 2, 4, 2, 3, 1, 7, 7, 5, 1, 9, 10, 2], "identity": -9223372036854775808, "lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [5, 8, 7, 10]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "identity": -9223372036854775808, "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [5, -9223372036854775808, 11, 13, 19, 23]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 2, 3, 1, 5], "identity": -9223372036854775808, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [5, -9223372036854775808, 3, 5]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "identity": -9223372036854775808, "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [6]}}]}, {"name": "awkward_reduce_countnonzero", "tests": [{"error": false, "inputs": {"fromptr": [1, 0, 0, 2, 2, 2, 3, 0, 0, 4], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 3, 1, 1]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [3, 0, 2, 1, 2, 1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 0, 2, 0, 0, 2, 0, 4], "lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [3, 1, 2]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [3]}}, {"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [3, 2, 1, 0, 0, 0, 2, 1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [6]}}]}, {"name": "awkward_reduce_count_64", "tests": [{"error": false, "inputs": {"lenparents": 19, "outlength": 9, "parents": [1, 1, 1, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [0, 3, 0, 5, 4, 0, 4, 3, 0]}}, {"error": false, "inputs": {"lenparents": 19, "outlength": 8, "parents": [1, 1, 1, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [0, 3, 0, 5, 4, 0, 4, 3]}}, {"error": false, "inputs": {"lenparents": 1696, "outlength": 331, "parents": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16]}, "outputs": {"toptr": [626, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 3, "parents": [0, 0, 2]}, "outputs": {"toptr": [2, 0, 1]}}, {"error": false, "inputs": {"lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [3]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [3, 0, 2, 1, 2, 1]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [3, 2, 1, 0, 0, 0, 2, 1]}}, {"error": false, "inputs": {"lenparents": 21, "outlength": 9, "parents": [0, 0, 0, 1, 1, 1, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 0, 4, 4, 0, 4, 3, 0]}}, {"error": false, "inputs": {"lenparents": 21, "outlength": 8, "parents": [0, 0, 0, 1, 1, 1, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 0, 4, 4, 0, 4, 3]}}, {"error": false, "inputs": {"lenparents": 22, "outlength": 9, "parents": [0, 0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 0, 5, 4, 0, 4, 3, 0]}}, {"error": false, "inputs": {"lenparents": 22, "outlength": 8, "parents": [0, 0, 0, 1, 1, 1, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 0, 5, 4, 0, 4, 3]}}, {"error": false, "inputs": {"lenparents": 24, "outlength": 9, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 2, 5, 4, 0, 4, 3, 0]}}, {"error": false, "inputs": {"lenparents": 24, "outlength": 8, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 6, 6, 7, 7, 7]}, "outputs": {"toptr": [3, 3, 2, 5, 4, 0, 4, 3]}}, {"error": false, "inputs": {"lenparents": 9, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]}, "outputs": {"toptr": [3, 3, 3, 1]}}, {"error": false, "inputs": {"lenparents": 18, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]}, "outputs": {"toptr": [3, 3, 3, 3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 21, "outlength": 7, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6]}, "outputs": {"toptr": [3, 3, 3, 3, 3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9]}, "outputs": {"toptr": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 23, "outlength": 7, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6]}, "outputs": {"toptr": [3, 3, 3, 3, 3, 5, 3]}}, {"error": false, "inputs": {"lenparents": 23, "outlength": 7, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6]}, "outputs": {"toptr": [3, 3, 3, 3, 5, 3, 3]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [3, 3, 4]}}, {"error": false, "inputs": {"lenparents": 43, "outlength": 10, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9]}, "outputs": {"toptr": [3, 3, 4, 2, 4, 5, 6, 4, 5, 7]}}, {"error": false, "inputs": {"lenparents": 39, "outlength": 10, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9]}, "outputs": {"toptr": [3, 3, 4, 3, 3, 5, 6, 4, 3, 5]}}, {"error": false, "inputs": {"lenparents": 11, "outlength": 3, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [3, 3, 5]}}, {"error": false, "inputs": {"lenparents": 20, "outlength": 6, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]}, "outputs": {"toptr": [3, 3, 5, 3, 3, 3]}}, {"error": false, "inputs": {"lenparents": 25, "outlength": 7, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6]}, "outputs": {"toptr": [3, 3, 5, 3, 3, 3, 5]}}, {"error": false, "inputs": {"lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [5]}}, {"error": false, "inputs": {"lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [5, 5]}}, {"error": false, "inputs": {"lenparents": 29, "outlength": 7, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6]}, "outputs": {"toptr": [5, 5, 5, 3, 3, 3, 5]}}, {"error": false, "inputs": {"lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [6]}}]}, {"name": "awkward_reduce_sum", "tests": [{"error": false, "inputs": {"fromptr": [0], "lenparents": 1, "outlength": 1, "parents": [0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"fromptr": [0, 5, 20, 1, 6, 21, 2, 7, 22, 3, 8, 23, 4, 9, 24], "lenparents": 15, "outlength": 10, "parents": [0, 5, 5, 1, 6, 6, 2, 7, 7, 3, 8, 8, 4, 9, 9]}, "outputs": {"toptr": [0, 1, 2, 3, 4, 25, 27, 29, 31, 33]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [10, 0, 18, 13, 36, 23]}}, {"error": false, "inputs": {"fromptr": [1, 0, 0, 1, 0, 0], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [1, 0, 1, 0]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24], "lenparents": 15, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [10, 35, 110]}}, {"error": false, "inputs": {"fromptr": [0, 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], "lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [10, 35, 60, 85, 110, 135]}}, {"error": false, "inputs": {"fromptr": [0, 1, 3, 4, 5, 6], "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 3, 3, 3]}, "outputs": {"toptr": [1, 3, 0, 15]}}, {"error": false, "inputs": {"fromptr": [0, 5, 10, 15, 25, 1, 11, 16, 26, 2, 12, 17, 27, 8, 18, 28, 4, 9, 14, 29], "lenparents": 20, "outlength": 10, "parents": [0, 0, 0, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 8, 8, 4, 4, 4, 9]}, "outputs": {"toptr": [15, 12, 14, 8, 27, 40, 42, 44, 46, 29]}}, {"error": false, "inputs": {"fromptr": [15, 20, 25, 16, 21, 26, 17, 22, 27, 18, 23, 28, 19, 24, 29], "lenparents": 15, "outlength": 15, "parents": [0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14]}, "outputs": {"toptr": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]}}, {"error": false, "inputs": {"fromptr": [0, 15, 5, 10, 25, 1, 16, 11, 26, 2, 17, 12, 27, 18, 8, 28, 4, 9, 14, 29], "lenparents": 20, "outlength": 15, "parents": [0, 0, 5, 10, 10, 1, 1, 11, 11, 2, 2, 12, 12, 3, 8, 13, 4, 9, 14, 14]}, "outputs": {"toptr": [15, 17, 19, 18, 4, 5, 0, 0, 8, 9, 35, 37, 39, 28, 43]}}, {"error": false, "inputs": {"fromptr": [0, 15, 5, 20, 10, 25, 1, 16, 6, 21, 11, 26, 2, 17, 7, 22, 12, 27, 3, 18, 8, 23, 13, 28, 4, 19, 9, 24, 14, 29], "lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43]}}, {"error": false, "inputs": {"fromptr": [0, 5, 10, 15, 20, 25, 1, 6, 11, 16, 21, 26, 2, 7, 12, 17, 22, 27, 3, 8, 13, 18, 23, 28, 4, 9, 14, 19, 24, 29], "lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [15, 18, 21, 24, 27, 60, 63, 66, 69, 72]}}, {"error": false, "inputs": {"fromptr": [1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 0], "lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [15, 240, 0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 1, 2, 3, 4, 5], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [15, 15]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [21]}}, {"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [22, 14, 5, 0, 0, 0, 40, 19]}}, {"error": false, "inputs": {"fromptr": [1, 16, 0, 2, 32, 0, 4, 64, 0, 8, 128, 0], "lenparents": 12, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"toptr": [17, 34, 68, 136]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 5], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [3, 0, 7, 5]}}, {"error": false, "inputs": {"fromptr": [0, 4, 1, 3, 5, 6], "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 1, 1, 3]}, "outputs": {"toptr": [4, 9, 0, 6]}}, {"error": false, "inputs": {"fromptr": [1, 4, 9, 16, 25, 1, 4, 9, 16, 25], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [55, 55]}}, {"error": false, "inputs": {"fromptr": [1, 4, 9, 16, 26, 1, 4, 10, 16, 24], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [56, 55]}}, {"error": false, "inputs": {"fromptr": [0, 5, 20, 1, 6, 21, 2, 7, 22, 3, 8, 23, 4, 9, 24], "lenparents": 15, "outlength": 10, "parents": [0, 0, 5, 1, 1, 6, 2, 2, 7, 3, 3, 8, 4, 4, 9]}, "outputs": {"toptr": [5, 7, 9, 11, 13, 20, 21, 22, 23, 24]}}, {"error": false, "inputs": {"fromptr": [15, 20, 25, 16, 21, 26, 17, 22, 27, 18, 23, 28, 19, 24, 29], "lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [60, 63, 66, 69, 72]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [6]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 4, 5, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 25, 26, 27, 28, 29], "lenparents": 20, "outlength": 6, "parents": [0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [7, 22, 47, 66, 0, 135]}}, {"error": false, "inputs": {"fromptr": [2, 2, 4, 5, 5], "lenparents": 5, "outlength": 3, "parents": [0, 0, 0, 2, 2]}, "outputs": {"toptr": [8, 0, 10]}}, {"error": false, "inputs": {"fromptr": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "lenparents": 15, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [85, 110, 135]}}, {"error": false, "inputs": {"fromptr": [4, 1, 0, 1, 4, 5, 1, 0, 1, 3], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [10, 10]}}, {"error": false, "inputs": {"fromptr": [4, 1, 0, 1, 4, 4, 1, 0, 1, 4], "lenparents": 10, "outlength": 2, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]}, "outputs": {"toptr": [10, 10]}}]}, {"name": "awkward_reduce_prod", "tests": [{"error": false, "inputs": {"fromptr": [1, 0, 0, 1, 0, 0], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 0, 0]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 5], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [0, 1, 12, 5]}}, {"error": false, "inputs": {"fromptr": [2, 53, 31, 101, 3, 59, 37, 103, 5, 61, 41, 107, 7, 67, 43, 109, 11, 71, 47, 113], "lenparents": 20, "outlength": 15, "parents": [0, 0, 10, 10, 1, 1, 11, 11, 2, 2, 12, 12, 3, 3, 13, 13, 4, 4, 14, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 1, 1, 1, 1, 1, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 47, 113], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 14, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 1, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 11, 71, 29, 97, 47], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 4, 4, 9, 9, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 43, 47]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 29, 97], "lenparents": 28, "outlength": 14, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 29, 97, 47], "lenparents": 29, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 47]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 29, 97, 47, 113], "lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 53, 13, 73, 31, 101, 3, 59, 17, 79, 37, 103, 5, 61, 19, 83, 41, 107, 7, 67, 23, 89, 43, 109, 11, 71, 29, 47], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 14]}, "outputs": {"toptr": [106, 177, 305, 469, 781, 949, 1343, 1577, 2047, 29, 3131, 3811, 4387, 4687, 47]}}, {"error": false, "inputs": {"fromptr": [0], "lenparents": 1, "outlength": 3, "parents": [2]}, "outputs": {"toptr": [1, 1, 0]}}, {"error": false, "inputs": {"fromptr": [101, 103, 107, 109, 113, 53, 59, 61, 67, 71, 31, 37, 41, 43, 47, 2, 3, 5, 7, 11], "lenparents": 20, "outlength": 6, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [13710311357, 1, 907383479, 95041567, 1, 2310]}}, {"error": false, "inputs": {"fromptr": [101, 103, 107, 109, 113, 73, 79, 83, 89, 97, 53, 59, 61, 67, 71, 31, 37, 41, 43, 47, 13, 17, 19, 23, 29, 2, 3, 5, 7, 11], "lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [13710311357, 4132280413, 907383479, 95041567, 2800733, 2310]}}, {"error": false, "inputs": {"fromptr": [101, 103, 107, 109, 113, 53, 59, 61, 67, 71, 31, 37, 41, 43, 47, 2, 3, 5, 7, 11], "lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [13710311357, 907383479, 95041567, 2310]}}, {"error": false, "inputs": {"fromptr": [2, 7, 17, 29, 3, 11, 19, 31, 5, 13, 23, 37], "lenparents": 12, "outlength": 6, "parents": [0, 0, 3, 3, 1, 1, 4, 4, 2, 2, 5, 5]}, "outputs": {"toptr": [14, 33, 65, 493, 589, 851]}}, {"error": false, "inputs": {"fromptr": [3, 53, 13, 73, 31, 101, 5, 59, 17, 79, 37, 103, 7, 61, 19, 83, 41, 107, 67, 23, 89, 43, 109, 71, 29, 97, 47, 113], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 8, 8, 13, 13, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [159, 295, 427, 67, 71, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [3, 53, 13, 73, 31, 101, 5, 59, 17, 79, 37, 103, 7, 61, 19, 83, 41, 107, 11, 67, 23, 89, 43, 109, 71, 29, 97, 47, 113], "lenparents": 29, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [159, 295, 427, 737, 71, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [3, 53, 13, 73, 31, 101, 5, 59, 17, 79, 37, 103, 7, 61, 19, 83, 41, 107, 11, 67, 23, 89, 43, 109, 71, 97, 47, 113], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 9, 14, 14]}, "outputs": {"toptr": [159, 295, 427, 737, 71, 949, 1343, 1577, 2047, 97, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [182, 33, 5, 1, 1, 1, 391, 19]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37], "lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]}, "outputs": {"toptr": [210, 46189, 765049]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 101, 103, 107, 109, 113], "lenparents": 20, "outlength": 6, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [2310, 1, 95041567, 907383479, 1, 13710311357]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113], "lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [2310, 2800733, 95041567, 907383479, 4132280413, 13710311357]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 101, 103, 107, 109, 113], "lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [2310, 95041567, 907383479, 13710311357]}}, {"error": false, "inputs": {"fromptr": [2, 7, 3, 11, 5], "lenparents": 5, "outlength": 8, "parents": [0, 6, 1, 7, 2]}, "outputs": {"toptr": [2, 3, 5, 1, 1, 1, 7, 11]}}, {"error": false, "inputs": {"fromptr": [5, 53, 13, 73, 31, 101, 7, 59, 17, 79, 37, 103, 11, 61, 19, 83, 41, 107, 67, 23, 89, 43, 109, 71, 29, 97, 47, 113], "lenparents": 28, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 8, 8, 13, 13, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [265, 413, 671, 67, 71, 949, 1343, 1577, 2047, 2813, 3131, 3811, 4387, 4687, 5311]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37], "lenparents": 12, "outlength": 8, "parents": [0, 0, 0, 3, 3, 3, 4, 4, 4, 7, 7, 7]}, "outputs": {"toptr": [30, 1, 1, 1001, 7429, 1, 1, 33263]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13], "lenparents": 6, "outlength": 4, "parents": [0, 0, 0, 2, 2, 3]}, "outputs": {"toptr": [30, 1, 77, 13]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [30, 1, 77, 13, 323, 23]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19], "lenparents": 8, "outlength": 5, "parents": [0, 0, 0, 2, 2, 3, 4, 4]}, "outputs": {"toptr": [30, 1, 77, 13, 323]}}, {"error": false, "inputs": {"fromptr": [6, 5, 7, 11, 13, 17, 19], "lenparents": 7, "outlength": 5, "parents": [0, 0, 2, 2, 3, 4, 4]}, "outputs": {"toptr": [30, 1, 77, 13, 323]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11], "lenparents": 5, "outlength": 3, "parents": [0, 0, 0, 2, 2]}, "outputs": {"toptr": [30, 1, 77]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [30]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11], "lenparents": 5, "outlength": 4, "parents": [0, 0, 0, 1, 2]}, "outputs": {"toptr": [30, 7, 11, 1]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11], "lenparents": 5, "outlength": 3, "parents": [0, 0, 0, 1, 2]}, "outputs": {"toptr": [30, 7, 11]}}, {"error": false, "inputs": {"fromptr": [101, 31, 53, 2, 103, 37, 59, 3, 107, 41, 61, 5, 109, 43, 67, 7, 113, 47, 71, 11], "lenparents": 20, "outlength": 15, "parents": [0, 0, 10, 10, 1, 1, 11, 11, 2, 2, 12, 12, 3, 3, 13, 13, 4, 4, 14, 14]}, "outputs": {"toptr": [3131, 3811, 4387, 4687, 5311, 1, 1, 1, 1, 1, 106, 177, 305, 469, 781]}}, {"error": false, "inputs": {"fromptr": [101, 31, 73, 13, 53, 2, 103, 37, 79, 17, 59, 3, 107, 41, 83, 19, 61, 5, 109, 43, 89, 23, 67, 7, 113, 47, 97, 29, 71, 11], "lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [3131, 3811, 4387, 4687, 5311, 949, 1343, 1577, 2047, 2813, 106, 177, 305, 469, 781]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 11, "outlength": 12, "parents": [0, 0, 3, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, -1, 1, 1, 1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 11, "outlength": 12, "parents": [0, 0, 6, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, -1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 10, "outlength": 12, "parents": [0, 0, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, 1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 29, 3, 19, 31, 37], "lenparents": 8, "outlength": 12, "parents": [0, 0, 3, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, -1, 1, 1, 1, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 29, 3, 19, 31, 37], "lenparents": 8, "outlength": 12, "parents": [0, 0, 6, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, -1, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, 29, 3, 19, 31, 37], "lenparents": 7, "outlength": 12, "parents": [0, 0, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, 1, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 39, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 12, "outlength": 12, "parents": [0, 0, 6, 6, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, -39, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 39, 29, 3, 19, 31, 37], "lenparents": 9, "outlength": 12, "parents": [0, 0, 6, 6, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, 1, 1, 1, -39, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, 7, 29, 3, 19, 11, 31, 5, 23, 13, 37], "lenparents": 12, "outlength": 12, "parents": [0, 0, 9, 9, 1, 1, 10, 10, 2, 2, 11, 11]}, "outputs": {"toptr": [34, 57, 115, 1, 1, 1, 1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 39, 7, 29, 3, 19, 11, 31, 13, 37], "lenparents": 12, "outlength": 12, "parents": [0, 0, 3, 3, 9, 9, 1, 1, 10, 10, 11, 11]}, "outputs": {"toptr": [34, 57, 1, -39, 1, 1, 1, 1, 1, 203, 341, 481]}}, {"error": false, "inputs": {"fromptr": [2, 17, -1, 39, 29, 3, 19, 31, 37], "lenparents": 9, "outlength": 12, "parents": [0, 0, 3, 3, 9, 1, 1, 10, 11]}, "outputs": {"toptr": [34, 57, 1, -39, 1, 1, 1, 1, 1, 29, 31, 37]}}, {"error": false, "inputs": {"fromptr": [2, 17, 7, 23, 13, 29, 3, 19, 11, 5], "lenparents": 10, "outlength": 7, "parents": [0, 0, 3, 3, 6, 6, 1, 1, 4, 2]}, "outputs": {"toptr": [34, 57, 5, 161, 11, 1, 377]}}, {"error": false, "inputs": {"fromptr": [2, 17, 23, 7, 13, 3, 19, 11, 5], "lenparents": 9, "outlength": 10, "parents": [0, 0, 3, 6, 9, 1, 1, 7, 2]}, "outputs": {"toptr": [34, 57, 5, 23, 1, 1, 7, 11, 1, 13]}}, {"error": false, "inputs": {"fromptr": [2, 11, 17, 7, 19, 3, 13, 23, 5], "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 3, 3, 1, 1, 4, 2]}, "outputs": {"toptr": [374, 39, 5, 133, 23]}}, {"error": false, "inputs": {"fromptr": [101, 73, 53, 31, 13, 2, 103, 79, 59, 37, 17, 3, 107, 83, 61, 41, 19, 5, 109, 89, 67, 43, 23, 7, 113, 97, 71, 47, 29, 11], "lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [390769, 480083, 541741, 649967, 778231, 806, 1887, 3895, 6923, 14993]}}, {"error": false, "inputs": {"fromptr": [2, 11, 23, 3, 13, 29, 5, 17, 31, 7, 19, 37], "lenparents": 12, "outlength": 4, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"toptr": [506, 1131, 2635, 4921]}}, {"error": false, "inputs": {"fromptr": [101, 53, 31, 2, 103, 59, 37, 3, 107, 61, 41, 5, 109, 67, 43, 7, 113, 71, 47, 11], "lenparents": 20, "outlength": 10, "parents": [0, 0, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 3, 8, 8, 4, 4, 9, 9]}, "outputs": {"toptr": [5353, 6077, 6527, 7303, 8023, 62, 111, 205, 301, 517]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [6]}}, {"error": false, "inputs": {"fromptr": [2, 31, 53, 101, 3, 37, 59, 103, 5, 41, 61, 107, 7, 43, 67, 109, 11, 47, 71, 113], "lenparents": 20, "outlength": 10, "parents": [0, 0, 5, 5, 1, 1, 6, 6, 2, 2, 7, 7, 3, 3, 8, 8, 4, 4, 9, 9]}, "outputs": {"toptr": [62, 111, 205, 301, 517, 5353, 6077, 6527, 7303, 8023]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19], "lenparents": 8, "outlength": 7, "parents": [0, 0, 1, 2, 3, 4, 5, 6]}, "outputs": {"toptr": [6, 5, 7, 11, 13, 17, 19]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19], "lenparents": 8, "outlength": 6, "parents": [0, 0, 1, 2, 3, 4, 5, 5]}, "outputs": {"toptr": [6, 5, 7, 11, 13, 323]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [720]}}, {"error": false, "inputs": {"fromptr": [2, 13, 31, 53, 73, 101, 3, 17, 37, 59, 79, 103, 5, 19, 41, 61, 83, 107, 7, 23, 43, 67, 89, 109, 11, 29, 47, 71, 97, 113], "lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [806, 1887, 3895, 6923, 14993, 390769, 480083, 541741, 649967, 778231]}}]}, {"name": "awkward_reduce_min", "tests": [{"error": false, "inputs": {"fromptr": [0, 4, 1, 3, 5, 6], "identity": 9223372036854775807, "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 1, 1, 3]}, "outputs": {"toptr": [0, 1, 9223372036854775807, 6]}}, {"error": false, "inputs": {"fromptr": [0, 1, 3, 4, 5, 6], "identity": 9223372036854775807, "lenparents": 6, "outlength": 4, "parents": [0, 0, 1, 3, 3, 3]}, "outputs": {"toptr": [0, 3, 9223372036854775807, 4]}}, {"error": false, "inputs": {"fromptr": [1, 3, 2, 5, 3, 7, 3, 1, 5, 8, 1, 9, 4, 2, 7, 10, 2, 4, 7, 2], "identity": 9223372036854775807, "lenparents": 20, "outlength": 5, "parents": [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]}, "outputs": {"toptr": [1, 1, 1, 2, 2]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "identity": 9223372036854775807, "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [1]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "identity": 9223372036854775807, "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [1]}}, {"error": false, "inputs": {"fromptr": [1, 3, 6, 4, 2, 2, 3, 1, 6], "identity": 4, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 4, 1, 4]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 3, 7, 8, 2, 4, 2, 3, 1, 7, 7, 5, 1, 9, 10, 2], "identity": 9223372036854775807, "lenparents": 20, "outlength": 4, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]}, "outputs": {"toptr": [1, 2, 1, 1]}}, {"error": false, "inputs": {"fromptr": [1, 4, 4, 2, 2, 5, 3, 3, 3, 6, 2, 4], "identity": 9223372036854775807, "lenparents": 12, "outlength": 9, "parents": [0, 0, 6, 6, 1, 1, 7, 7, 2, 2, 8, 8]}, "outputs": {"toptr": [1, 2, 3, 9223372036854775807, 9223372036854775807, 9223372036854775807, 2, 3, 2]}}, {"error": false, "inputs": {"fromptr": [1, 2, 5, 3, 3, 5, 1, 4, 2], "identity": 9223372036854775807, "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 1, 2, 2, 3, 4]}, "outputs": {"toptr": [1, 3, 1, 4, 2]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 2, 3, 1, 5], "identity": 4, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 4, 1, 4]}}, {"error": false, "inputs": {"fromptr": [1, 3, 5, 4, 2, 2, 3, 1, 5], "identity": 9223372036854775807, "lenparents": 9, "outlength": 4, "parents": [0, 0, 0, 0, 0, 2, 2, 2, 3]}, "outputs": {"toptr": [1, 9223372036854775807, 1, 5]}}, {"error": false, "inputs": {"fromptr": [2, 7, 13, 17, 23, 3, 11, 19, 5], "identity": 9223372036854775807, "lenparents": 9, "outlength": 8, "parents": [0, 0, 0, 6, 6, 1, 1, 7, 2]}, "outputs": {"toptr": [2, 3, 5, 9223372036854775807, 9223372036854775807, 9223372036854775807, 17, 19]}}, {"error": false, "inputs": {"fromptr": [2, 3, 5, 7, 11, 13, 17, 19, 23], "identity": 9223372036854775807, "lenparents": 9, "outlength": 6, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 5]}, "outputs": {"toptr": [2, 9223372036854775807, 7, 13, 17, 23]}}]}, {"name": "awkward_reduce_argmin", "tests": [{"error": false, "inputs": {"fromptr": [0, 0, 4, 4, 6], "lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3], "lenparents": 3, "outlength": 1, "parents": [0, 0, 0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"fromptr": [1, 2, 3, 4, 5, 6], "lenparents": 6, "outlength": 1, "parents": [0, 0, 0, 0, 0, 0]}, "outputs": {"toptr": [0]}}, {"error": false, "inputs": {"fromptr": [0, 1, 2, 3, 4, 6], "lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 1, 1, 2]}, "outputs": {"toptr": [0, 3, 5]}}, {"error": false, "inputs": {"fromptr": [1, 4, 2, 6, 3, 0, -10], "lenparents": 7, "outlength": 4, "parents": [0, 0, 0, 1, 1, 2, 3]}, "outputs": {"toptr": [0, 4, 5, 6]}}, {"error": false, "inputs": {"fromptr": [2, 1, 3, 4, 6, 6, -4, -6, -7], "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 2, 2, 3, 4, 4, 4]}, "outputs": {"toptr": [1, -1, 3, 5, 8]}}, {"error": false, "inputs": {"fromptr": [2, 1, 3, -4, -6, -7], "lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 2, 2, 2]}, "outputs": {"toptr": [1, -1, 5]}}, {"error": false, "inputs": {"fromptr": [2, 1, 3, 2, 1], "lenparents": 5, "outlength": 3, "parents": [0, 0, 1, 2, 2]}, "outputs": {"toptr": [1, 2, 4]}}, {"error": false, "inputs": {"fromptr": [2, 2, 1, 0, 1, 0], "lenparents": 6, "outlength": 3, "parents": [0, 0, 1, 1, 1, 2]}, "outputs": {"toptr": [0, 3, 5]}}, {"error": false, "inputs": {"fromptr": [2, 0, 2, 1, 1, 0], "lenparents": 6, "outlength": 3, "parents": [0, 0, 0, 1, 1, 2]}, "outputs": {"toptr": [1, 3, 5]}}, {"error": false, "inputs": {"fromptr": [3, -3, 4, 4, 2, 2, 2, 2, 2, -2, 1, 1, 6, -6, 1, 1, 4, 4, 1, 1, 3, -3, 3, 3, 4, 4, 6, 6, 6, -6], "lenparents": 30, "outlength": 15, "parents": [0, 0, 5, 5, 10, 10, 1, 1, 6, 6, 11, 11, 2, 2, 7, 7, 12, 12, 3, 3, 8, 8, 13, 13, 4, 4, 9, 9, 14, 14]}, "outputs": {"toptr": [1, 6, 13, 18, 24, 2, 9, 14, 21, 26, 4, 10, 16, 22, 29]}}, {"error": false, "inputs": {"fromptr": [3, 1, 6, 1, 4, 4, 2, 1, 7, 2, 3, -1], "lenparents": 12, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2]}, "outputs": {"toptr": [1, 7, 11]}}, {"error": false, "inputs": {"fromptr": [-4, -6, -7, 6, 4, 6, 2, 1, 3], "lenparents": 9, "outlength": 5, "parents": [0, 0, 0, 1, 2, 2, 4, 4, 4]}, "outputs": {"toptr": [2, 3, 4, -1, 7]}}, {"error": false, "inputs": {"fromptr": [-4, -6, -7, 6, -4, -6, -7, 2, 1, 3], "lenparents": 10, "outlength": 4, "parents": [0, 0, 0, 1, 2, 2, 2, 3, 3, 3]}, "outputs": {"toptr": [2, 3, 6, 8]}}, {"error": false, "inputs": {"fromptr": [3, 4, 2, 1, 2, 3, 6, 1, -1, 1, 7, 4], "lenparents": 12, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4]}, "outputs": {"toptr": [2, 3, 8, 9, 11]}}, {"error": false, "inputs": {"fromptr": [3, 4, 2, 2, 2, 1, 6, 1, 4, 1, 3, 3, 4, 6, 6], "lenparents": 15, "outlength": 5, "parents": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]}, "outputs": {"toptr": [2, 5, 7, 9, 12]}}, {"error": false, "inputs": {"fromptr": [3, 4, 2, -3, 4, 2, 2, 2, 1, 2, -2, 1, 6, 1, 4, -6, 1, 4, 1, 3, 3, 1, -3, 3, 4, 6, 6, 4, 6, -6], "lenparents": 30, "outlength": 10, "parents": [0, 0, 0, 5, 5, 5, 1, 1, 1, 6, 6, 6, 2, 2, 2, 7, 7, 7, 3, 3, 3, 8, 8, 8, 4, 4, 4, 9, 9, 9]}, "outputs": {"toptr": [2, 8, 13, 18, 24, 3, 10, 15, 22, 29]}}, {"error": false, "inputs": {"fromptr": [6, 3, 2, 1, 2], "lenparents": 5, "outlength": 1, "parents": [0, 0, 0, 0, 0]}, "outputs": {"toptr": [3]}}, {"error": false, "inputs": {"fromptr": [3, 2, 6, 1, 4, 4, 2, 1, 3, 6, 2, 1, 4, 3, 6, -3, 2, -6, 1, 4, 4, -2, 1, -3, 6, 2, 1, 4, 3, -6], "lenparents": 30, "outlength": 6, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5]}, "outputs": {"toptr": [3, 7, 11, 17, 23, 29]}}, {"error": false, "inputs": {"fromptr": [3, 2, 6, 1, 4, 4, 2, 1, 3, 6, 2, 1, 4, 3, 6], "lenparents": 15, "outlength": 3, "parents": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]}, "outputs": {"toptr": [3, 7, 11]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 999, 1, 1, 1, 1, 999, 1, 2, 2, 2, 2, 2, 2, 3, 3], "lenparents": 18, "outlength": 6, "parents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 2, 5]}, "outputs": {"toptr": [0, 10, 16, 5, 13, 17]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 999, 1, 1, 1, 1, 999, 1, 2, 2, 2, 999, 2, 2, 2, 3, 999, 999, 3, 999], "lenparents": 22, "outlength": 8, "parents": [0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 1, 1, 1, 5, 5, 5, 5, 2, 6, 6, 6, 7]}, "outputs": {"toptr": [0, 10, 17, -1, 5, 14, 20, 21]}}, {"error": false, "inputs": {"fromptr": [1, 1, 1, 999, 1, 1, 1, 1, 999, 1, 2, 2, 2, 999, 2, 2, 2, 3, 999, 999, 3], "lenparents": 21, "outlength": 6, "parents": [0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 1, 4, 4, 4, 4, 2, 5, 5, 5]}, "outputs": {"toptr": [0, 10, 17, 5, 14, 20]}}]}, {"name": "awkward_UnionArray_fillindex_count", "tests": [{"error": false, "inputs": {"length": 3, "toindexoffset": 4}, "outputs": {"toindex": [123, 123, 123, 123, 0, 1, 2]}}, {"error": false, "inputs": {"length": 2, "toindexoffset": 2}, "outputs": {"toindex": [123, 123, 0, 1]}}, {"error": false, "inputs": {"length": 2, "toindexoffset": 0}, "outputs": {"toindex": [0, 1]}}, {"error": false, "inputs": {"length": 3, "toindexoffset": 6}, "outputs": {"toindex": [123, 123, 123, 123, 123, 123, 0, 1, 2]}}, {"error": false, "inputs": {"length": 3, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2]}}, {"error": false, "inputs": {"length": 5, "toindexoffset": 9}, "outputs": {"toindex": [123, 123, 123, 123, 123, 123, 123, 123, 123, 0, 1, 2, 3, 4]}}, {"error": false, "inputs": {"length": 4, "toindexoffset": 5}, "outputs": {"toindex": [123, 123, 123, 123, 123, 0, 1, 2, 3]}}, {"error": false, "inputs": {"length": 5, "toindexoffset": 0}, "outputs": {"toindex": [0, 1, 2, 3, 4]}}]}, {"name": "awkward_UnionArray_simplify", "tests": [{"error": false, "inputs": {"base": 0, "innerindex": [0, 0, 1, 1, 2, 3, 2], "innertags": [0, 1, 0, 1, 0, 0, 1], "innerwhich": 0, "length": 12, "outerindex": [0, 1, 0, 1, 2, 2, 3, 4, 5, 3, 6, 4], "outertags": [0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0], "outerwhich": 1, "towhich": 1}, "outputs": {"toindex": [123, 123, 0, 123, 1, 123, 123, 2, 3, 123, 123, 123], "totags": [123, 123, 1, 123, 1, 123, 123, 1, 1, 123, 123, 123]}}, {"error": false, "inputs": {"base": 5, "innerindex": [0, 0, 1, 1, 2, 3, 2], "innertags": [0, 1, 0, 1, 0, 0, 1], "innerwhich": 1, "length": 12, "outerindex": [0, 1, 0, 1, 2, 2, 3, 4, 5, 3, 6, 4], "outertags": [0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0], "outerwhich": 1, "towhich": 0}, "outputs": {"toindex": [123, 123, 123, 5, 123, 123, 6, 123, 123, 123, 7, 123], "totags": [123, 123, 123, 0, 123, 123, 0, 123, 123, 123, 0, 123]}}]}]} diff --git a/pyproject.toml b/pyproject.toml index 0dd25f789a..b148d7bb2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "hatchling.build" [project] name = "awkward" -version = "2.1.3" +version = "2.2.3" description = "Manipulate JSON-like data with NumPy-like idioms." license = { text = "BSD-3-Clause" } requires-python = ">=3.7" @@ -40,7 +40,7 @@ classifiers = [ "Topic :: Utilities", ] dependencies = [ - "awkward_cpp==14", + "awkward_cpp==17", "importlib_resources;python_version < \"3.9\"", "numpy>=1.17.0", "packaging", diff --git a/src/awkward/_backends/backend.py b/src/awkward/_backends/backend.py index aac9f0aa90..b7079e8288 100644 --- a/src/awkward/_backends/backend.py +++ b/src/awkward/_backends/backend.py @@ -4,10 +4,11 @@ from abc import ABC, abstractmethod import awkward as ak +from awkward._kernels import KernelError from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import NumpyLike, NumpyMetadata +from awkward._nplikes.numpylike import ArrayLike, NumpyLike, NumpyMetadata from awkward._singleton import Singleton -from awkward._typing import Callable, Tuple, TypeAlias, TypeVar, Unpack +from awkward._typing import Callable, Protocol, Tuple, TypeAlias, TypeVar, Unpack np = NumpyMetadata.instance() numpy = Numpy.instance() @@ -15,7 +16,12 @@ T = TypeVar("T", covariant=True) KernelKeyType: TypeAlias = Tuple[str, Unpack[Tuple[np.dtype, ...]]] -KernelType: TypeAlias = Callable[..., None] +KernelType: TypeAlias = "Callable[..., KernelError | None]" + + +class UfuncLike(Protocol): + def __call__(self, *args: ArrayLike, **kwargs) -> ArrayLike: + ... class Backend(Singleton, ABC): @@ -34,14 +40,33 @@ def index_nplike(self) -> NumpyLike: def __getitem__(self, key: KernelKeyType) -> KernelType: raise NotImplementedError - def apply_reducer( + def prepare_reducer(self, reducer: ak._reducers.Reducer) -> ak._reducers.Reducer: + return reducer + + def prepare_ufunc(self, ufunc: UfuncLike) -> UfuncLike: + return ufunc + + def format_kernel_error( self, - reducer: ak._reducers.Reducer, - layout: ak.contents.NumpyArray, - parents: ak.index.Index, - outlength: int, - ) -> ak.contents.NumpyArray: - return reducer.apply(layout, parents, outlength) - - def apply_ufunc(self, ufunc, method, args, kwargs): - return getattr(ufunc, method)(*args, **kwargs) + error: KernelError, + ): + if error.filename is None: + filename = "" + else: + filename = " (in compiled code: " + error.filename.decode( + errors="surrogateescape" + ).lstrip("\n").lstrip("(") + + message = error.str.decode(errors="surrogateescape") + + if error.attempt != ak._util.kSliceNone: + message += f" while attempting to get index {error.attempt}" + + message += filename + return message + + def maybe_kernel_error(self, error: KernelError | None): + if error is None or error.str is None: + return + else: + raise ValueError(self.format_kernel_error(error)) diff --git a/src/awkward/_backends/dispatch.py b/src/awkward/_backends/dispatch.py index d328611833..4ce6d19390 100644 --- a/src/awkward/_backends/dispatch.py +++ b/src/awkward/_backends/dispatch.py @@ -7,7 +7,7 @@ from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyLike, NumpyMetadata from awkward._typing import Callable, TypeAlias, TypeVar -from awkward._util import unset +from awkward._util import UNSET np = NumpyMetadata.instance() numpy = Numpy.instance() @@ -69,7 +69,7 @@ def common_backend(backends: Iterable[Backend]) -> Backend: ) -def _backend_of(obj, default: D = unset) -> Backend | D: +def _backend_of(obj, default: D = UNSET) -> Backend | D: cls = type(obj) try: lookup = _type_to_backend_lookup[cls] @@ -80,7 +80,7 @@ def _backend_of(obj, default: D = unset) -> Backend | D: if maybe_lookup is not None: break else: - if default is unset: + if default is UNSET: raise TypeError(f"cannot find nplike for {cls.__name__}") else: return default @@ -88,7 +88,7 @@ def _backend_of(obj, default: D = unset) -> Backend | D: return maybe_lookup(obj) -def backend_of(*objects, default: D = unset) -> Backend | D: +def backend_of(*objects, default: D = UNSET) -> Backend | D: """ Args: objects: objects for which to find a suitable backend @@ -104,7 +104,7 @@ def backend_of(*objects, default: D = unset) -> Backend | D: if backends: return common_backend(backends) - elif default is unset: + elif default is UNSET: raise ValueError("could not find backend for", objects) else: return default diff --git a/src/awkward/_backends/jax.py b/src/awkward/_backends/jax.py index aad16b0455..1a825d4a9a 100644 --- a/src/awkward/_backends/jax.py +++ b/src/awkward/_backends/jax.py @@ -4,7 +4,7 @@ import awkward_cpp import awkward as ak -from awkward._backends.backend import Backend, KernelKeyType +from awkward._backends.backend import Backend, KernelKeyType, UfuncLike from awkward._backends.dispatch import register_backend from awkward._kernels import JaxKernel from awkward._nplikes.jax import Jax @@ -39,23 +39,12 @@ def __getitem__(self, index: KernelKeyType) -> JaxKernel: # JAX uses Awkward's C++ kernels for index-only operations return JaxKernel(awkward_cpp.cpu_kernels.kernel[index], index) - def apply_reducer( - self, - reducer: ak._reducers.Reducer, - layout: ak.contents.NumpyArray, - parents: ak.index.Index, - outlength: int, - ) -> ak.contents.NumpyArray: + def prepare_reducer(self, reducer: ak._reducers.Reducer) -> ak._reducers.Reducer: from awkward._connect.jax import get_jax_reducer - jax_reducer = get_jax_reducer(reducer) - return jax_reducer.apply(layout, parents, outlength) + return get_jax_reducer(reducer) - def apply_ufunc(self, ufunc, method, args, kwargs): + def prepare_ufunc(self, ufunc: UfuncLike) -> UfuncLike: from awkward._connect.jax import get_jax_ufunc - if method != "__call__": - raise ValueError(f"unsupported ufunc method {method} called") - - jax_ufunc = get_jax_ufunc(ufunc) - return jax_ufunc(*args, **kwargs) + return get_jax_ufunc(ufunc) diff --git a/src/awkward/_backends/typetracer.py b/src/awkward/_backends/typetracer.py index d7edd6d3cc..cef237ed21 100644 --- a/src/awkward/_backends/typetracer.py +++ b/src/awkward/_backends/typetracer.py @@ -43,18 +43,3 @@ def _coerce_ufunc_argument(self, x): return self._coerce_ufunc_argument(x.content) else: return x - - def apply_ufunc(self, ufunc, method, args, kwargs): - shape = None - numpy_args = [] - - for x in args: - if isinstance(x, TypeTracerArray): - x.touch_data() - shape = x.shape - - numpy_args.append(self._coerce_ufunc_argument(x)) - - assert shape is not None - tmp = getattr(ufunc, method)(*numpy_args, **kwargs) - return self._typetracer.empty((shape[0],) + tmp.shape[1:], dtype=tmp.dtype) diff --git a/src/awkward/_behavior.py b/src/awkward/_behavior.py index 48e4e26c53..50f3a34f24 100644 --- a/src/awkward/_behavior.py +++ b/src/awkward/_behavior.py @@ -6,6 +6,7 @@ import awkward as ak from awkward._nplikes import ufuncs +from awkward._typing import Any def overlay_behavior(behavior: dict | None) -> Mapping: @@ -59,100 +60,69 @@ def find_record_reducer(reducer, layout, behavior): def find_custom_cast(obj, behavior): behavior = overlay_behavior(behavior) - for key, fcn in behavior.items(): - if ( - isinstance(key, tuple) - and len(key) == 2 - and key[0] == "__cast__" - and isinstance(obj, key[1]) - ): + for cls in type(obj).__mro__: + fcn = behavior.get(("__cast__", cls)) + if fcn is not None: return fcn return None -def find_custom_broadcast(layout, behavior): - behavior = overlay_behavior(behavior) - custom = layout.parameter("__array__") - if not isinstance(custom, str): - custom = layout.parameter("__record__") - if not isinstance(custom, str): - custom = layout.purelist_parameter("__record__") - if isinstance(custom, str): - for key, fcn in behavior.items(): - if ( - isinstance(key, tuple) - and len(key) == 2 - and key[0] == "__broadcast__" - and key[1] == custom - ): - return fcn - return None - - def find_ufunc_generic(ufunc, layout, behavior): behavior = overlay_behavior(behavior) custom = layout.parameter("__array__") - if not isinstance(custom, str): + if custom is None: custom = layout.parameter("__record__") if isinstance(custom, str): - for key, fcn in behavior.items(): - if ( - isinstance(key, tuple) - and len(key) == 2 - and (key[0] is ufunc or key[0] is ufuncs.ufunc) - and key[1] == custom - ): - return fcn - return None + fcn = behavior.get((ufunc, custom)) + if fcn is None: + fcn = behavior.get((ufuncs.ufunc, custom)) + return fcn + else: + return None -def find_ufunc(behavior, signature): +def find_ufunc(behavior, signature: tuple): if not any(s is None for s in signature): behavior = overlay_behavior(behavior) - for key, custom in behavior.items(): - if ( - isinstance(key, tuple) - and len(key) == len(signature) - and key[0] == signature[0] - and all( - k == s - or ( - isinstance(k, type) and isinstance(s, type) and issubclass(s, k) + + # Special case all strings or hashable types. + if all(isinstance(x, str) for x in signature): + return behavior.get(signature) + else: + for key, custom in behavior.items(): + if ( + isinstance(key, tuple) + and len(key) == len(signature) + and key[0] == signature[0] + and all( + k == s + or ( + isinstance(k, type) + and isinstance(s, type) + and issubclass(s, k) + ) + for k, s in zip(key[1:], signature[1:]) ) - for k, s in zip(key[1:], signature[1:]) - ) - ): - return custom + ): + return custom -def find_typestrs(behavior): +def find_record_typestr( + behavior: None | Mapping, parameters: None | Mapping[str, Any], default: str = None +): + if parameters is None: + return default behavior = overlay_behavior(behavior) - out = {} - for key, typestr in behavior.items(): - if ( - isinstance(key, tuple) - and len(key) == 2 - and key[0] == "__typestr__" - and isinstance(key[1], str) - and isinstance(typestr, str) - ): - out[key[1]] = typestr - return out - - -def find_typestr(parameters, typestrs): - if parameters is not None: - record = parameters.get("__record__") - if record is not None: - typestr = typestrs.get(record) - if typestr is not None: - return typestr - array = parameters.get("__array__") - if array is not None: - typestr = typestrs.get(array) - if typestr is not None: - return typestr - return None + return behavior.get(("__typestr__", parameters.get("__record__")), default) + + +def find_array_typestr( + behavior: None | Mapping, parameters: None | Mapping[str, Any], default: str = None +): + if parameters is None: + return default + behavior = overlay_behavior(behavior) + return behavior.get(("__typestr__", parameters.get("__array__")), default) def behavior_of(*arrays, **kwargs): diff --git a/src/awkward/_broadcasting.py b/src/awkward/_broadcasting.py index f96cfc6afc..bd8cd65383 100644 --- a/src/awkward/_broadcasting.py +++ b/src/awkward/_broadcasting.py @@ -10,7 +10,6 @@ import awkward as ak from awkward._backends.backend import Backend from awkward._backends.dispatch import backend_of -from awkward._behavior import find_custom_broadcast from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyMetadata from awkward._nplikes.shape import unknown_length @@ -20,7 +19,7 @@ parameters_intersect, ) from awkward._typing import Any, Callable, Dict, List, TypeAlias, Union -from awkward._util import unset +from awkward._util import UNSET, Sentinel from awkward.contents.bitmaskedarray import BitMaskedArray from awkward.contents.bytemaskedarray import ByteMaskedArray from awkward.contents.content import Content @@ -67,6 +66,7 @@ def length_of_broadcast(inputs: Sequence) -> int | type[unknown_length]: def broadcast_pack(inputs: Sequence, isscalar: list[bool]) -> list: maxlen = length_of_broadcast(inputs) nextinputs = [] + for x in inputs: if isinstance(x, Record): index = x.backend.index_nplike.full(maxlen, x.at, dtype=np.int64) @@ -76,7 +76,7 @@ def broadcast_pack(inputs: Sequence, isscalar: list[bool]) -> list: nextinputs.append( RegularArray( x, - x.length if x.backend.nplike.known_data else 1, + x.length, 1, parameters=None, ) @@ -106,19 +106,27 @@ def in_function(options): if options["function_name"] is None: return "" else: - return "in " + options["function_name"] + return " in " + options["function_name"] def checklength(inputs, options): - length = inputs[0].length - for x in inputs[1:]: - if x.length != length: + it = iter(inputs) + length: int + for content in it: + if content.length is not unknown_length: + length = content.length + break + + for other_content in it: + if other_content.length is unknown_length: + continue + if other_content.length != length: raise ValueError( "cannot broadcast {} of length {} with {} of length {}{}".format( - type(inputs[0]).__name__, + type(content).__name__, length, - type(x).__name__, - x.length, + type(other_content).__name__, + other_content.length, in_function(options), ) ) @@ -174,21 +182,6 @@ def all_same_offsets(backend: Backend, inputs: list) -> bool: return True -# TODO: move to _util or another module -class Sentinel: - """A class for implementing sentinel types""" - - def __init__(self, name, module=None): - self._name = name - self._module = module - - def __repr__(self): - if self._module is not None: - return f"{self._module}.{self._name}" - else: - return f"{self._name}" - - NO_PARAMETERS = Sentinel("NO_PARAMETERS", __name__) @@ -418,11 +411,7 @@ def apply_step( ) # Now all lengths must agree. - if backend.nplike.known_data: - checklength(contents, options) - else: - for x in contents: - x._touch_shape(recursive=False) + checklength(contents, options) # Load the parameter broadcasting rule implementation rule = options["broadcast_parameters_rule"] @@ -440,10 +429,10 @@ def broadcast_any_record(): if not options["allow_records"]: raise ValueError(f"cannot broadcast records {in_function(options)}") - fields, length, istuple = unset, unset, unset + fields, length, istuple = UNSET, UNSET, UNSET for x in contents: if x.is_record: - if fields is unset: + if fields is UNSET: fields = x.fields elif set(fields) != set(x.fields): raise ValueError( @@ -454,7 +443,7 @@ def broadcast_any_record(): ", ".join(sorted(x.fields)), ) ) - if length is unset: + if length is UNSET: length = x.length elif length != x.length: raise ValueError( @@ -464,7 +453,7 @@ def broadcast_any_record(): ) ) # Records win over tuples - if istuple is unset or not x.is_tuple: + if istuple is UNSET or not x.is_tuple: istuple = False outcontents, numoutputs = [], None @@ -497,114 +486,102 @@ def broadcast_any_record(): ) def broadcast_any_list(): + index_nplike = backend.index_nplike # All regular? if all(x.is_regular or not x.is_list for x in contents): # Ensure all layouts have same length - length = unset + length = None for x in contents: - if length is unset: + if length is None: length = x.length - elif backend.nplike.known_data: + elif length is not unknown_length and x.length is not unknown_length: assert length == x.length - assert length is not unset + assert length is not None - if any(x.size == 0 for x in contents if x.is_regular): - dimsize = 0 - else: - dimsize = max(x.size for x in contents if x.is_regular) - - if backend.nplike.known_data: - for x in contents: - if x.is_regular: - if dimsize > 1 and x.size == 1: - # For any (N, 1) array, we know we'll broadcast to (N, M) where M is maxsize - tmpindex = Index64( - backend.index_nplike.repeat( - backend.index_nplike.arange( - x.length, dtype=np.int64 - ), - dimsize, - ), - nplike=backend.index_nplike, - ) - - nextinputs = [] - for x in inputs: - if isinstance(x, RegularArray): - if dimsize > 1 and x.size == 1: - nextinputs.append( - x.content[: x.length * x.size]._carry( - tmpindex, allow_lazy=False - ) - ) - elif x.size == dimsize: - nextinputs.append(x.content[: x.length * x.size]) - elif dimsize == 0: - nextinputs.append(x.content[:0]) - else: - raise ValueError( - "cannot broadcast RegularArray of size " - "{} with RegularArray of size {} {}".format( - x.size, dimsize, in_function(options) - ) - ) - else: - nextinputs.append(x) - - else: - nextinputs = [] - for x in inputs: - if isinstance(x, RegularArray): - x._touch_data(recursive=False) - nextinputs.append(x.content) - else: - nextinputs.append(x) + # Determine the size of the broadcast result + dim_size = None + for x in contents: + if not x.is_regular: + continue + + # Any unknown length sets max_size to unknown + if x.size is unknown_length: + dim_size = unknown_length + # Any zero-length column triggers zero broadcasting + elif x.size == 0: + dim_size = 0 + break + # Take first size as dim_size + elif dim_size is None: + dim_size = x.size + # If the dim_size is unknown, we can't compare + elif dim_size is unknown_length: + continue + else: + dim_size = max(dim_size, x.size) - outcontent = apply_step( - backend, - nextinputs, - action, - depth + 1, - copy.copy(depth_context), - lateral_context, - behavior, - options, - ) - assert isinstance(outcontent, tuple) - parameters = parameters_factory(len(outcontent)) - return tuple( - RegularArray(x, dimsize, length, parameters=p) - for x, p in zip(outcontent, parameters) + dimsize_greater_than_one_if_known = ( + dim_size is unknown_length or dim_size > 1 ) + dimsize_known_to_be_zero = dim_size is not unknown_length and dim_size == 0 - elif not backend.nplike.known_data: - offsets = None + # Build a broadcast index for size=1 contents + size_one_carry_index = None + for x in contents: + if x.is_regular: + x_size_known_to_be_one = ( + x.size is not unknown_length and x.size == 1 + ) + if dimsize_greater_than_one_if_known and x_size_known_to_be_one: + # For any (N, 1) array, we know we'll broadcast to (N, M) where M is maxsize + size_one_carry_index = Index64( + index_nplike.repeat( + index_nplike.arange( + index_nplike.shape_item_as_index(x.length), + dtype=np.int64, + ), + index_nplike.shape_item_as_index(dim_size), + ), + nplike=index_nplike, + ) + break + + # Here we have three possible broadcasting outcomes (by precedence): + # 1. any (exactly) size-0 content trims all other contents + # 2. any (exactly) size-1 content broadcasts to the common length + # 3. otherwise, recurse into the content as-is nextinputs = [] for x in inputs: - if isinstance(x, ListOffsetArray): - x._touch_data(recursive=False) - offsets = Index64( - backend.index_nplike.empty( - x.offsets.data.shape[0], dtype=np.int64 - ), - nplike=backend.index_nplike, - ) - nextinputs.append(x.content) - elif isinstance(x, ListArray): - x._touch_data(recursive=False) - offsets = Index64( - backend.index_nplike.empty( - x.starts.data.shape[0] + 1, dtype=np.int64 - ), - nplike=backend.index_nplike, + if isinstance(x, RegularArray): + x_size_known_to_be_one = ( + x.size is not unknown_length and x.size == 1 ) - nextinputs.append(x.content) - elif isinstance(x, RegularArray): - x._touch_data(recursive=False) - nextinputs.append(x.content) + # If dimsize is known to be exactly zero, all contents are zero length + if dimsize_known_to_be_zero: + nextinputs.append(x.content[:0]) + # If we have a known size=1 content, then broadcast it to the dimension size + elif dimsize_greater_than_one_if_known and x_size_known_to_be_one: + nextinputs.append( + x.content[: x.length * x.size]._carry( + size_one_carry_index, allow_lazy=False + ) + ) + # Any unknown values or sizes are assumed to be correct as-is + elif ( + dim_size is unknown_length + or x.size is unknown_length + or x.size == dim_size + ): + nextinputs.append(x.content[: x.length * x.size]) + else: + raise ValueError( + "cannot broadcast RegularArray of size " + "{} with RegularArray of size {} {}".format( + x.size, dim_size, in_function(options) + ) + ) else: nextinputs.append(x) - assert offsets is not None outcontent = apply_step( backend, @@ -619,28 +596,32 @@ def broadcast_any_list(): assert isinstance(outcontent, tuple) parameters = parameters_factory(len(outcontent)) return tuple( - ListOffsetArray(offsets, x, parameters=p) + RegularArray(x, dim_size, length, parameters=p) for x, p in zip(outcontent, parameters) ) # Not all regular, but all same offsets? # Optimization: https://github.com/scikit-hep/awkward-1.0/issues/442 - elif all_same_offsets(backend, inputs): + elif index_nplike.known_data and all_same_offsets(backend, inputs): lencontent, offsets, starts, stops = None, None, None, None nextinputs = [] for x in inputs: if isinstance(x, ListOffsetArray): offsets = x.offsets - lencontent = offsets[-1] + lencontent = index_nplike.index_as_shape_item(offsets[-1]) nextinputs.append(x.content[:lencontent]) elif isinstance(x, ListArray): starts, stops = x.starts, x.stops - if starts.length == 0 or stops.length == 0: + if (starts.length is not unknown_length and starts.length == 0) or ( + stops.length is not unknown_length and stops.length == 0 + ): nextinputs.append(x.content[:0]) else: - lencontent = backend.index_nplike.max(stops) + lencontent = index_nplike.index_as_shape_item( + index_nplike.max(stops) + ) nextinputs.append(x.content[:lencontent]) elif isinstance(x, RegularArray): nextinputs.append(x.content[: x.size * x.length]) @@ -683,45 +664,65 @@ def broadcast_any_list(): # General list-handling case: the offsets of each list may be different. else: - fcns = [ - find_custom_broadcast(x, behavior) if isinstance(x, Content) else None - for x in inputs - ] + # We have three possible cases here: + # 1. all-string (nothing to do) + # 2. mixed string-list (strings gain a dimension and broadcast to the non-string offsets) + # 3. no strings (all lists broadcast to a single offsets) + offsets_content = None + all_content_strings = True + input_is_string = [] + for x in inputs: + if isinstance(x, Content): + content_is_string = x.parameter("__array__") in { + "string", + "bytestring", + } + # Don't try and take offsets from strings + if not content_is_string: + all_content_strings = False + # Take the offsets from the first irregular list + if x.is_list and not x.is_regular and offsets_content is None: + offsets_content = x + input_is_string.append(content_is_string) + else: + input_is_string.append(False) - # Find first list without custom broadcasting which will define the broadcast offsets - # Don't consider RegularArray (handle case of 1-sized regular broadcasting) - # Do this to prioritise non-custom broadcasting - first = None - - for x, fcn in zip(inputs, fcns): - if ( - isinstance(x, listtypes) - and not isinstance(x, RegularArray) - and fcn is None - ): - first = x - break + # case (1): user getfunctions should exit before this gets called + if all_content_strings: + raise ValueError( + "cannot broadcast all strings: {}{}".format( + ", ".join(repr(type(x)) for x in inputs), in_function(options) + ) + ) - # Did we fail to find a list without custom broadcasting? - secondround = False - # If we failed to find an irregular, non-custom broadcasting list, - # continue search for *any* list. - if first is None: - secondround = True - for x in inputs: - if isinstance(x, listtypes) and not isinstance(x, RegularArray): - first = x + # Didn't find a ragged list, try any list! + if offsets_content is None: + for content in contents: + if content.is_list: + offsets_content = content break + else: + raise AssertionError("no list found in list branch!") - offsets = first._compact_offsets64(True) + offsets = offsets_content._compact_offsets64(True) nextinputs = [] - for x, fcn in zip(inputs, fcns): - if callable(fcn) and not secondround: - nextinputs.append(fcn(x, offsets)) + for x, x_is_string in zip(inputs, input_is_string): + if x_is_string: + offsets_data = backend.index_nplike.asarray(offsets) + counts = offsets_data[1:] - offsets_data[:-1] + if ak._util.win or ak._util.bits32: + counts = index_nplike.astype(counts, dtype=np.int32) + parents = index_nplike.repeat( + index_nplike.arange(counts.size, dtype=counts.dtype), counts + ) + nextinputs.append( + ak.contents.IndexedArray( + ak.index.Index64(parents, nplike=index_nplike), x + ).project() + ) elif isinstance(x, listtypes): nextinputs.append(x._broadcast_tooffsets64(offsets).content) - # Handle implicit left-broadcasting (non-NumPy-like broadcasting). elif options["left_broadcast"] and isinstance(x, Content): nextinputs.append( @@ -751,52 +752,40 @@ def broadcast_any_list(): ) def broadcast_any_option(): - if backend.nplike.known_data: - mask = None - for x in contents: - if x.is_option: - m = x.mask_as_bool(valid_when=False) - if mask is None: - mask = m - else: - mask = backend.index_nplike.logical_or(mask, m, maybe_out=mask) - - nextmask = Index8(mask.view(np.int8)) - index = backend.index_nplike.full(mask.shape[0], -1, dtype=np.int64) - index[~mask] = backend.index_nplike.arange( - mask.shape[0] - backend.index_nplike.count_nonzero(mask), + mask = None + for x in contents: + if x.is_option: + m = x.mask_as_bool(valid_when=False) + if mask is None: + mask = m + else: + mask = backend.index_nplike.logical_or(mask, m, maybe_out=mask) + + nextmask = Index8(mask.view(np.int8)) + index = backend.index_nplike.full(mask.shape[0], -1, dtype=np.int64) + index[~mask] = backend.index_nplike.arange( + backend.index_nplike.shape_item_as_index(mask.shape[0]) + - backend.index_nplike.count_nonzero(mask), + dtype=np.int64, + ) + index = Index64(index) + if any(not x.is_option for x in contents): + nextindex = backend.index_nplike.arange( + backend.index_nplike.shape_item_as_index(mask.shape[0]), dtype=np.int64, ) - index = Index64(index) - if any(not x.is_option for x in contents): - nextindex = backend.index_nplike.arange(mask.shape[0], dtype=np.int64) - nextindex[mask] = -1 - nextindex = Index64(nextindex) - - nextinputs = [] - for x in inputs: - if isinstance(x, optiontypes): - nextinputs.append(x.project(nextmask)) - elif isinstance(x, Content): - nextinputs.append( - IndexedOptionArray(nextindex, x).project(nextmask) - ) - else: - nextinputs.append(x) + nextindex[mask] = -1 + nextindex = Index64(nextindex) + + nextinputs = [] + for x in inputs: + if isinstance(x, optiontypes): + nextinputs.append(x.project(nextmask)) + elif isinstance(x, Content): + nextinputs.append(IndexedOptionArray(nextindex, x).project(nextmask)) + else: + nextinputs.append(x) - else: - index = None - nextinputs = [] - for x in inputs: - if isinstance(x, optiontypes): - x._touch_data(recursive=False) - index = Index64( - backend.index_nplike.empty(x.length, dtype=np.int64) - ) - nextinputs.append(x.content) - else: - nextinputs.append(x) - assert index is not None outcontent = apply_step( backend, nextinputs, @@ -817,14 +806,14 @@ def broadcast_any_option(): def broadcast_any_union(): if not backend.nplike.known_data: # assert False - union_num_contents, length = [], None + union_num_contents = [] + length = None for x in contents: if x.is_union: x._touch_data(recursive=False) union_num_contents.append(len(x.contents)) if length is None: - length = x.tags.data.shape[0] - assert length is not unknown_length + length = x.length all_combos = list( itertools.product(*[range(x) for x in union_num_contents]) @@ -832,7 +821,8 @@ def broadcast_any_union(): tags = backend.index_nplike.empty(length, dtype=np.int8) index = backend.index_nplike.empty(length, dtype=np.int64) - numoutputs, outcontents = None, [] + numoutputs = None + outcontents = [] for combo in all_combos: nextinputs = [] i = 0 @@ -856,13 +846,9 @@ def broadcast_any_union(): ) ) assert isinstance(outcontents[-1], tuple) - if numoutputs is None: - numoutputs = outcontents[-1].length - else: - assert ( - numoutputs is unknown_length - or outcontents[-1].length is unknown_length - ) or numoutputs == outcontents[-1].length + if numoutputs is not None: + assert numoutputs == len(outcontents[-1]) + numoutputs = len(outcontents[-1]) assert numoutputs is not None @@ -948,7 +934,13 @@ def broadcast_any_union(): ) def broadcast_any_indexed(): - nextinputs = [x.project() if isinstance(x, IndexedArray) else x for x in inputs] + # The `apply` function may exit at the level of a `RecordArray`. We can avoid projection + # of the record array in such cases, in favour of a deferred carry. This can be done by + # "pushing" the `IndexedArray` _into_ the record (i.e., wrapping each `content`). + nextinputs = [ + x._push_inside_record_or_project() if isinstance(x, IndexedArray) else x + for x in inputs + ] return apply_step( backend, nextinputs, diff --git a/src/awkward/_connect/cling.py b/src/awkward/_connect/cling.py index fd702d748c..4c6c9d381d 100644 --- a/src/awkward/_connect/cling.py +++ b/src/awkward/_connect/cling.py @@ -446,7 +446,7 @@ class ArrayBuilder {{ def togenerator(form, flatlist_as_rvec): if isinstance(form, ak.forms.EmptyForm): - return togenerator(form.to_NumpyForm(np.dtype(np.float64)), flatlist_as_rvec) + return togenerator(form.to_NumpyForm(primitive="float64"), flatlist_as_rvec) elif isinstance(form, ak.forms.NumpyForm): if len(form.inner_shape) == 0: diff --git a/src/awkward/_connect/cuda/cuda_kernels/awkward_ListOffsetArray_compact_offsets.cu b/src/awkward/_connect/cuda/cuda_kernels/awkward_ListOffsetArray_compact_offsets.cu deleted file mode 100644 index f3e3249c28..0000000000 --- a/src/awkward/_connect/cuda/cuda_kernels/awkward_ListOffsetArray_compact_offsets.cu +++ /dev/null @@ -1,20 +0,0 @@ -// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE - -template -__global__ void -awkward_ListOffsetArray_compact_offsets(T* tooffsets, - const C* fromoffsets, - int64_t length, - uint64_t invocation_index, - uint64_t* err_code) { - if (err_code[0] == NO_ERROR) { - int64_t thread_id = blockIdx.x * blockDim.x + threadIdx.x; - if (thread_id < length) { - int64_t diff = (int64_t)fromoffsets[0]; - if (thread_id == 0) { - tooffsets[0] = 0; - } - tooffsets[thread_id + 1] = fromoffsets[thread_id + 1] - diff; - } - } -} diff --git a/src/awkward/_connect/cuda/cuda_kernels/awkward_RegularArray_broadcast_tooffsets.cu b/src/awkward/_connect/cuda/cuda_kernels/awkward_RegularArray_broadcast_tooffsets.cu deleted file mode 100644 index 3d7205e96e..0000000000 --- a/src/awkward/_connect/cuda/cuda_kernels/awkward_RegularArray_broadcast_tooffsets.cu +++ /dev/null @@ -1,28 +0,0 @@ -// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE - -enum class REGULARARRAY_BROADCAST_TOOFFSETS_ERRRORS { - OFFSETS_MON_INCR, // message: "broadcast's offsets must be monotonically increasing" - BROAD_NEST_LIST // message: "cannot broadcast nested list" -}; - -template -__global__ void -awkward_RegularArray_broadcast_tooffsets(const T* fromoffsets, - int64_t offsetslength, - int64_t size, - uint64_t invocation_index, - uint64_t* err_code) { - if (err_code[0] == NO_ERROR) { - int64_t thread_id = blockIdx.x * blockDim.x + threadIdx.x; - if (thread_id < (offsetslength - 1)) { - int64_t count = - (int64_t)(fromoffsets[(thread_id + 1)] - fromoffsets[thread_id]); - if (count < 0) { - RAISE_ERROR(REGULARARRAY_BROADCAST_TOOFFSETS_ERRRORS::OFFSETS_MON_INCR) - } - if (size != count) { - RAISE_ERROR(REGULARARRAY_BROADCAST_TOOFFSETS_ERRRORS::BROAD_NEST_LIST) - } - } - } -} diff --git a/src/awkward/_connect/cuda/cuda_kernels/awkward_RegularArray_compact_offsets.cu b/src/awkward/_connect/cuda/cuda_kernels/awkward_RegularArray_compact_offsets.cu deleted file mode 100644 index bcd5643073..0000000000 --- a/src/awkward/_connect/cuda/cuda_kernels/awkward_RegularArray_compact_offsets.cu +++ /dev/null @@ -1,17 +0,0 @@ -// BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE - -template -__global__ void -awkward_RegularArray_compact_offsets(T* tooffsets, - int64_t length, - int64_t size, - uint64_t invocation_index, - uint64_t* err_code) { - if (err_code[0] == NO_ERROR) { - int64_t thread_id = blockIdx.x * blockDim.x + threadIdx.x; - tooffsets[0] = 0; - if (thread_id < length) { - tooffsets[thread_id + 1] = (thread_id + 1) * size; - } - } -} diff --git a/src/awkward/_connect/jax/reducers.py b/src/awkward/_connect/jax/reducers.py index 6837d72f21..7ba7fce03f 100644 --- a/src/awkward/_connect/jax/reducers.py +++ b/src/awkward/_connect/jax/reducers.py @@ -1,74 +1,163 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations + +from abc import abstractmethod import jax import awkward as ak +from awkward import _reducers from awkward._nplikes.numpylike import NumpyMetadata +from awkward._nplikes.shape import ShapeItem from awkward._reducers import Reducer +from awkward._typing import Final, Self, TypeVar np = NumpyMetadata.instance() -class ArgMin(Reducer): - name = "argmin" - needs_position = True - preferred_dtype = np.int64 +_overloads: dict[type[Reducer], type[JAXReducer]] = {} + + +R = TypeVar("R", bound=Reducer) + + +def overloads(cls: type[Reducer]): + def registrar(new_cls: type[R]) -> type[R]: + _overloads[cls] = new_cls + return new_cls + return registrar + + +class JAXReducer(Reducer): @classmethod - def return_dtype(cls, given_dtype): - return np.int64 + @abstractmethod + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + raise NotImplementedError + + +@overloads(_reducers.ArgMin) +class ArgMin(JAXReducer): + name: Final = "argmin" + needs_position: Final = True + preferred_dtype: Final = np.int64 + + @classmethod + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + raise NotImplementedError @classmethod - def apply(cls, array, parents, outlength): + def _return_dtype(cls, given_dtype): + return np.int64 + + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: raise RuntimeError("Cannot differentiate through argmin") -class ArgMax(Reducer): - name = "argmax" - needs_position = True - preferred_dtype = np.int64 +@overloads(_reducers.ArgMax) +class ArgMax(JAXReducer): + name: Final = "argmax" + needs_position: Final = True + preferred_dtype: Final = np.int64 @classmethod - def return_dtype(cls, given_dtype): - return np.int64 + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + assert isinstance(reducer, _reducers.ArgMax) + return cls() @classmethod - def apply(cls, array, parents, outlength): + def _return_dtype(cls, given_dtype): + return np.int64 + + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: raise RuntimeError("Cannot differentiate through argmax") -class Count(Reducer): - name = "count" - preferred_dtype = np.float64 +@overloads(_reducers.Count) +class Count(JAXReducer): + name: Final = "count" + preferred_dtype: Final = np.float64 + needs_position: Final = False @classmethod - def return_dtype(cls, given_dtype): - return np.int64 + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + assert isinstance(reducer, _reducers.Count) + return cls() @classmethod - def apply(cls, array, parents, outlength): + def _return_dtype(cls, given_dtype): + return np.int64 + + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: raise RuntimeError("Cannot differentiate through count_zero") -class CountNonzero(Reducer): - name = "count_nonzero" - preferred_dtype = np.float64 +@overloads(_reducers.CountNonzero) +class CountNonzero(JAXReducer): + name: Final = "count_nonzero" + preferred_dtype: Final = np.float64 + needs_position: Final = False @classmethod - def return_dtype(cls, given_dtype): - return np.int64 + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + assert isinstance(reducer, _reducers.CountNonzero) + return cls() @classmethod - def apply(cls, array, parents, outlength): + def _return_dtype(cls, given_dtype): + return np.int64 + + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: raise RuntimeError("Cannot differentiate through count_nonzero") -class Sum(Reducer): - name = "sum" - preferred_dtype = np.float64 +@overloads(_reducers.Sum) +class Sum(JAXReducer): + name: Final = "sum" + preferred_dtype: Final = np.float64 + needs_position: Final = False @classmethod - def apply(cls, array, parents, outlength): + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + assert isinstance(reducer, _reducers.Sum) + return cls() + + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) if array.dtype.kind == "M": raise TypeError(f"cannot compute the sum (ak.sum) of {array.dtype!r}") @@ -85,12 +174,25 @@ def apply(cls, array, parents, outlength): return ak.contents.NumpyArray(result, backend=array.backend) -class Prod(Reducer): - name = "prod" - preferred_dtype = np.int64 +@overloads(_reducers.Prod) +class Prod(JAXReducer): + name: Final = "prod" + preferred_dtype: Final = np.int64 + needs_position: Final = False @classmethod - def apply(cls, array, parents, outlength): + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + assert isinstance(reducer, _reducers.Prod) + return cls() + + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) # See issue https://github.com/google/jax/issues/9296 result = jax.numpy.exp( @@ -105,16 +207,29 @@ def apply(cls, array, parents, outlength): return ak.contents.NumpyArray(result, backend=array.backend) -class Any(Reducer): - name = "any" - preferred_dtype = np.bool_ +@overloads(_reducers.Any) +class Any(JAXReducer): + name: Final = "any" + preferred_dtype: Final = np.bool_ + needs_position: Final = False @classmethod - def return_dtype(cls, given_dtype): - return np.bool_ + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + assert isinstance(reducer, _reducers.Any) + return cls() @classmethod - def apply(cls, array, parents, outlength): + def _return_dtype(cls, given_dtype): + return np.bool_ + + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) result = jax.ops.segment_max(array.data, parents.data) result = jax.numpy.asarray(result, dtype=bool) @@ -122,16 +237,29 @@ def apply(cls, array, parents, outlength): return ak.contents.NumpyArray(result, backend=array.backend) -class All(Reducer): - name = "all" - preferred_dtype = np.bool_ +@overloads(_reducers.All) +class All(JAXReducer): + name: Final = "all" + preferred_dtype: Final = np.bool_ + needs_position: Final = False @classmethod - def return_dtype(cls, given_dtype): - return np.bool_ + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + assert isinstance(reducer, _reducers.All) + return cls() @classmethod - def apply(cls, array, parents, outlength): + def _return_dtype(cls, given_dtype): + return np.bool_ + + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) result = jax.ops.segment_min(array.data, parents.data) result = jax.numpy.asarray(result, dtype=bool) @@ -139,16 +267,23 @@ def apply(cls, array, parents, outlength): return ak.contents.NumpyArray(result, backend=array.backend) -class Min(Reducer): - name = "min" - preferred_dtype = np.float64 - initial = None +@overloads(_reducers.Min) +class Min(JAXReducer): + name: Final = "min" + preferred_dtype: Final = np.float64 + needs_position: Final = False def __init__(self, initial): - type(self).initial = initial + self._initial = initial - def __del__(self): - type(self).initial = None + @property + def initial(self): + return self._initial + + @classmethod + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + assert isinstance(reducer, _reducers.Min) + return cls(reducer.initial) @staticmethod def _min_initial(initial, type): @@ -169,12 +304,18 @@ def _min_initial(initial, type): return initial - @classmethod - def apply(cls, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) result = jax.ops.segment_min(array.data, parents.data) - result = jax.numpy.minimum(result, cls._min_initial(cls.initial, array.dtype)) + result = jax.numpy.minimum(result, self._min_initial(self.initial, array.dtype)) if array.dtype.type in (np.complex128, np.complex64): return ak.contents.NumpyArray( @@ -187,16 +328,23 @@ def apply(cls, array, parents, outlength): return ak.contents.NumpyArray(result, backend=array.backend) -class Max(Reducer): - name = "max" - preferred_dtype = np.float64 - initial = None +@overloads(_reducers.Max) +class Max(JAXReducer): + name: Final = "max" + preferred_dtype: Final = np.float64 + needs_position: Final = False def __init__(self, initial): - type(self).initial = initial + self._initial = initial + + @property + def initial(self): + return self._initial - def __del__(self): - type(self).initial = None + @classmethod + def from_kernel_reducer(cls, reducer: Reducer) -> Self: + assert isinstance(reducer, _reducers.Max) + return cls(reducer.initial) @staticmethod def _max_initial(initial, type): @@ -217,13 +365,19 @@ def _max_initial(initial, type): return initial - @classmethod - def apply(cls, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) result = jax.ops.segment_max(array.data, parents.data) - result = jax.numpy.maximum(result, cls._max_initial(cls.initial, array.dtype)) + result = jax.numpy.maximum(result, self._max_initial(self.initial, array.dtype)) if array.dtype.type in (np.complex128, np.complex64): return ak.contents.NumpyArray( array.backend.nplike.asarray( @@ -236,7 +390,4 @@ def apply(cls, array, parents, outlength): def get_jax_reducer(reducer: Reducer) -> Reducer: - if isinstance(reducer, type): - return globals()[reducer.__name__] - else: - return globals()[type(reducer).__name__] + return _overloads[type(reducer)].from_kernel_reducer(reducer) diff --git a/src/awkward/_connect/numba/arrayview.py b/src/awkward/_connect/numba/arrayview.py index f72ae8b2b6..7311815007 100644 --- a/src/awkward/_connect/numba/arrayview.py +++ b/src/awkward/_connect/numba/arrayview.py @@ -104,15 +104,15 @@ def code_to_function(code, function_name, externals=None, debug=False): return namespace[function_name] -def tonumbatype(form): +def to_numbatype(form): if isinstance(form, ak.forms.EmptyForm): - return tonumbatype(form.to_NumpyForm(np.dtype(np.float64))) + return to_numbatype(form.to_NumpyForm(primitive="float64")) elif isinstance(form, ak.forms.NumpyForm): if len(form.inner_shape) == 0: return ak._connect.numba.layout.NumpyArrayType.from_form(form) else: - return tonumbatype(form.to_RegularForm()) + return to_numbatype(form.to_RegularForm()) elif isinstance(form, ak.forms.RegularForm): return ak._connect.numba.layout.RegularArrayType.from_form(form) @@ -196,7 +196,7 @@ def fromarray(cls, array): ) return ArrayView( - tonumbatype(layout.form), + to_numbatype(layout.form), behavior, ak._lookup.Lookup(layout), 0, @@ -585,7 +585,7 @@ def fromrecord(cls, record): arraylayout = layout.array return RecordView( ArrayView( - tonumbatype(arraylayout.form), + to_numbatype(arraylayout.form), behavior, ak._lookup.Lookup(arraylayout), 0, diff --git a/src/awkward/_connect/numba/builder.py b/src/awkward/_connect/numba/builder.py index 91769a09f0..0ee99208c6 100644 --- a/src/awkward/_connect/numba/builder.py +++ b/src/awkward/_connect/numba/builder.py @@ -16,7 +16,7 @@ def globalstring(context, builder, pyvalue): if pyvalue not in dynamic_addrs: buf = dynamic_addrs[pyvalue] = numpy.array(pyvalue.encode("utf-8") + b"\x00") - context.add_dynamic_addr(builder, buf.ctypes.data, info=f"str({repr(pyvalue)})") + context.add_dynamic_addr(builder, buf.ctypes.data, info=f"str({pyvalue!r})") ptr = context.get_constant(numba.types.uintp, dynamic_addrs[pyvalue].ctypes.data) return builder.inttoptr(ptr, llvmlite.ir.PointerType(llvmlite.ir.IntType(8))) diff --git a/src/awkward/_connect/numba/growablebuffer.py b/src/awkward/_connect/numba/growablebuffer.py index 213734bb56..cffe06fa37 100644 --- a/src/awkward/_connect/numba/growablebuffer.py +++ b/src/awkward/_connect/numba/growablebuffer.py @@ -6,114 +6,7 @@ import numba.core.typing.npydecl import numpy - -class GrowableBuffer: - def __init__(self, dtype, *, initial=1024, resize=8.0): - # all mutable data are in arrays that can be in-place shared with Numba - self._panels = numba.typed.List([numpy.empty((initial,), dtype=dtype)]) - self._length_pos = numpy.zeros((2,), dtype=numpy.int64) - self._resize = resize - - @classmethod - def _from_data(cls, panels, length_pos, resize): - out = cls.__new__(cls) - out._panels = panels - out._length_pos = length_pos - out._resize = resize - return out - - @property - def dtype(self): - return self._panels[0].dtype - - def __repr__(self): - return f"" - - @property - def _length(self): - return self._length_pos[0] - - @_length.setter - def _length(self, value): - self._length_pos[0] = value - - def _length_inc(self, value): - self._length_pos[0] += value - - @property - def _pos(self): - return self._length_pos[1] - - @_pos.setter - def _pos(self, value): - self._length_pos[1] = value - - def _pos_inc(self, value): - self._length_pos[1] += value - - def __len__(self): - return self._length - - def append(self, datum): - if self._pos == len(self._panels[-1]): - self._add_panel() - - self._panels[-1][self._pos] = datum - self._pos_inc(1) - self._length_inc(1) - - def extend(self, data): - panel_index = len(self._panels) - 1 - pos = self._pos - - available = len(self._panels[-1]) - pos - remaining = len(data) - - if remaining > available: - panel_length = int(math.ceil(len(self._panels[0]) * self._resize)) - - self._panels.append( - numpy.empty((max(remaining, panel_length),), dtype=self.dtype) - ) - self._pos = 0 - available += len(self._panels[-1]) - - while remaining > 0: - panel = self._panels[panel_index] - available_in_panel = len(panel) - pos - to_write = min(remaining, available_in_panel) - - start = len(data) - remaining - panel[pos : pos + to_write] = data[start : start + to_write] - - if panel_index == len(self._panels) - 1: - self._pos_inc(to_write) - remaining -= to_write - pos = 0 - panel_index += 1 - - self._length_inc(len(data)) - - def _add_panel(self): - panel_length = int(math.ceil(len(self._panels[0]) * self._resize)) - - self._panels.append(numpy.empty((panel_length,), dtype=self.dtype)) - self._pos = 0 - - def snapshot(self): - out = numpy.empty((self._length,), dtype=self.dtype) - - start = 0 - stop = 0 - for panel in self._panels[:-1]: # full panels, not including the last - stop += len(panel) - out[start:stop] = panel - start = stop - - stop += self._pos - out[start:stop] = self._panels[-1][: self._pos] - - return out +from awkward.numba import GrowableBuffer class GrowableBufferType(numba.types.Type): diff --git a/src/awkward/_connect/numba/layout.py b/src/awkward/_connect/numba/layout.py index df5b1c14d1..739c110b47 100644 --- a/src/awkward/_connect/numba/layout.py +++ b/src/awkward/_connect/numba/layout.py @@ -116,7 +116,7 @@ def getitem_field(self, viewtype, key): self, viewtype, (*viewtype.fields, key) ) else: - raise TypeError(f"array does not have a field with key {repr(key)}") + raise TypeError(f"array does not have a field with key {key!r}") def lower_getitem_at_check( self, @@ -227,7 +227,7 @@ def castint(context, builder, fromtype, totype, val): elif fromtype.width == 64: fromtype = numba.int64 if not isinstance(fromtype, numba.types.Integer): - raise AssertionError(f"unrecognized integer type: {repr(fromtype)}") + raise AssertionError(f"unrecognized integer type: {fromtype!r}") if fromtype.bitwidth < totype.bitwidth: if fromtype.signed: @@ -369,7 +369,7 @@ class RegularArrayType(ContentType, ak._lookup.RegularLookup): @classmethod def from_form(cls, form): return RegularArrayType( - ak._connect.numba.arrayview.tonumbatype(form.content), + ak._connect.numba.arrayview.to_numbatype(form.content), form.size, form.parameters, ) @@ -449,7 +449,7 @@ def from_form(cls, form): return ListArrayType( cls.from_form_index(index_string), - ak._connect.numba.arrayview.tonumbatype(form.content), + ak._connect.numba.arrayview.to_numbatype(form.content), form.parameters, ) @@ -535,7 +535,7 @@ class IndexedArrayType(ContentType, ak._lookup.IndexedLookup): def from_form(cls, form): return IndexedArrayType( cls.from_form_index(form.index), - ak._connect.numba.arrayview.tonumbatype(form.content), + ak._connect.numba.arrayview.to_numbatype(form.content), form.parameters, ) @@ -629,7 +629,7 @@ class IndexedOptionArrayType(ContentType, ak._lookup.IndexedOptionLookup): def from_form(cls, form): return IndexedOptionArrayType( cls.from_form_index(form.index), - ak._connect.numba.arrayview.tonumbatype(form.content), + ak._connect.numba.arrayview.to_numbatype(form.content), form.parameters, ) @@ -740,7 +740,7 @@ class ByteMaskedArrayType(ContentType, ak._lookup.ByteMaskedLookup): def from_form(cls, form): return ByteMaskedArrayType( cls.from_form_index(form.mask), - ak._connect.numba.arrayview.tonumbatype(form.content), + ak._connect.numba.arrayview.to_numbatype(form.content), form.valid_when, form.parameters, ) @@ -852,7 +852,7 @@ class BitMaskedArrayType(ContentType, ak._lookup.BitMaskedLookup): def from_form(cls, form): return BitMaskedArrayType( cls.from_form_index(form.mask), - ak._connect.numba.arrayview.tonumbatype(form.content), + ak._connect.numba.arrayview.to_numbatype(form.content), form.valid_when, form.lsb_order, form.parameters, @@ -984,7 +984,7 @@ class UnmaskedArrayType(ContentType, ak._lookup.UnmaskedLookup): @classmethod def from_form(cls, form): return UnmaskedArrayType( - ak._connect.numba.arrayview.tonumbatype(form.content), + ak._connect.numba.arrayview.to_numbatype(form.content), form.parameters, ) @@ -1073,7 +1073,7 @@ class RecordArrayType(ContentType, ak._lookup.RecordLookup): @classmethod def from_form(cls, form): return RecordArrayType( - [ak._connect.numba.arrayview.tonumbatype(x) for x in form.contents], + [ak._connect.numba.arrayview.to_numbatype(x) for x in form.contents], None if form.is_tuple else form.fields, form.parameters, ) @@ -1364,7 +1364,7 @@ def from_form(cls, form): return UnionArrayType( cls.from_form_index(form.tags), cls.from_form_index(form.index), - [ak._connect.numba.arrayview.tonumbatype(x) for x in form.contents], + [ak._connect.numba.arrayview.to_numbatype(x) for x in form.contents], form.parameters, ) diff --git a/src/awkward/_connect/numpy.py b/src/awkward/_connect/numpy.py index 375826e9b7..fb20da8ddb 100644 --- a/src/awkward/_connect/numpy.py +++ b/src/awkward/_connect/numpy.py @@ -20,7 +20,7 @@ from awkward._nplikes import to_nplike from awkward._regularize import is_non_string_like_iterable from awkward._typing import Iterator -from awkward._util import numpy_at_least +from awkward._util import Sentinel, numpy_at_least from awkward.contents.numpyarray import NumpyArray # NumPy 1.13.1 introduced NEP13, without which Awkward ufuncs won't work, which @@ -30,13 +30,7 @@ raise ImportError("NumPy 1.13.1 or later required") -# FIXME: introduce sentinel type for this -class _Unsupported: - def __repr__(self): - return f"{__name__}.unsupported" - - -unsupported = _Unsupported() +UNSUPPORTED = Sentinel("UNSUPPORTED", __name__) def convert_to_array(layout, args, kwargs): @@ -124,7 +118,7 @@ def implements(numpy_function): def decorator(function): signature = inspect.signature(function) unsupported_names = { - p.name for p in signature.parameters.values() if p.default is unsupported + p.name for p in signature.parameters.values() if p.default is UNSUPPORTED } @functools.wraps(function) @@ -213,7 +207,7 @@ def _array_ufunc_signature(ufunc, inputs): else: signature.append(type(x)) - return signature + return tuple(signature) def array_ufunc(ufunc, method, inputs, kwargs): @@ -256,7 +250,11 @@ def action(inputs, **ignore): else: args.append(x) - result = backend.apply_ufunc(ufunc, method, args, kwargs) + # Give backend a chance to change the ufunc implementation + impl = backend.prepare_ufunc(ufunc) + + # Invoke ufunc + result = impl(*args, **kwargs) return (NumpyArray(result, backend=backend, parameters=parameters),) diff --git a/src/awkward/_do.py b/src/awkward/_do.py index acefcdbda8..a8a1ed0b9c 100644 --- a/src/awkward/_do.py +++ b/src/awkward/_do.py @@ -7,6 +7,7 @@ import awkward as ak from awkward._backends.backend import Backend +from awkward._errors import AxisError from awkward._nplikes.numpylike import NumpyMetadata from awkward._typing import Any, AxisMaybeNone, Literal from awkward.contents.content import ActionType, Content @@ -154,13 +155,13 @@ def unique(layout: Content, axis=None): branch, depth = layout.branch_depth if branch: if negaxis <= 0: - raise np.AxisError( + raise AxisError( "cannot use non-negative axis on a nested list structure " "of variable depth (negative axis counts from the leaves " "of the tree; non-negative from the root)" ) if negaxis > depth: - raise np.AxisError( + raise AxisError( "cannot use axis={} on a nested list structure that splits into " "different depths, the minimum of which is depth={} from the leaves".format( axis, depth @@ -170,7 +171,7 @@ def unique(layout: Content, axis=None): if negaxis <= 0: negaxis = negaxis + depth if not (0 < negaxis and negaxis <= depth): - raise np.AxisError( + raise AxisError( "axis={} exceeds the depth of this array ({})".format( axis, depth ) @@ -183,7 +184,7 @@ def unique(layout: Content, axis=None): return layout._unique(negaxis, starts, parents, 1) - raise np.AxisError( + raise AxisError( "unique expects axis 'None' or '-1', got axis={} that is not supported yet".format( axis ) @@ -203,6 +204,7 @@ def remove_structure( function_name: str | None = None, drop_nones: bool = True, keepdims: bool = False, + allow_records: bool = False, ): if isinstance(layout, Record): return remove_structure( @@ -212,6 +214,7 @@ def remove_structure( function_name, drop_nones, keepdims, + allow_records, ) else: @@ -224,6 +227,7 @@ def remove_structure( "function_name": function_name, "drop_nones": drop_nones, "keepdims": keepdims, + "allow_records": allow_records, }, ) return tuple(arrays) @@ -263,9 +267,15 @@ def reduce( keepdims: bool = False, behavior: dict | None = None, ): + reducer = layout.backend.prepare_reducer(reducer) + if axis is None: parts = remove_structure( - layout, flatten_records=False, drop_nones=False, keepdims=keepdims + layout, + flatten_records=False, + drop_nones=False, + keepdims=keepdims, + allow_records=True, ) if len(parts) > 1: @@ -275,9 +285,9 @@ def reduce( "cannot use axis=None on an array containing irreducible unions" ) elif len(parts) == 0: - parts = [ak.contents.EmptyArray()] - - (layout,) = parts + layout = ak.contents.EmptyArray() + else: + (layout,) = parts starts = ak.index.Index64.zeros(1, layout.backend.index_nplike) parents = ak.index.Index64.zeros(layout.length, layout.backend.index_nplike) diff --git a/src/awkward/_errors.py b/src/awkward/_errors.py index ff46393ee2..45181ba375 100644 --- a/src/awkward/_errors.py +++ b/src/awkward/_errors.py @@ -1,13 +1,17 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE from __future__ import annotations +import builtins import sys import threading import warnings -from collections.abc import Mapping, Sequence +from collections.abc import Callable, Collection, Iterable, Mapping +from functools import wraps + +import numpy # noqa: TID251 from awkward._nplikes.numpylike import NumpyMetadata -from awkward._typing import TypeVar +from awkward._typing import Any, TypeVar np = NumpyMetadata.instance() @@ -29,6 +33,11 @@ def __call__(self): return self.func(*self.args, **self.kwargs) +class KeyError(builtins.KeyError): + def __str__(self): + return super(Exception, self).__str__() + + class ErrorContext: # Any other threads should get a completely independent _slate. _slate = threading.local() @@ -53,6 +62,11 @@ def __exit__(self, exception_type, exception_value, traceback): if exception_type is not None and self.primary() is self: self.handle_exception(exception_type, exception_value) finally: + # `_kwargs` may hold cyclic references, that we really want to avoid + # as this can lead to large buffers remaining in memory for longer than absolutely necessary + # Let's just clear this, now. + self._kwargs.clear() + # Step out of the way so that another ErrorContext can become primary. if self.primary() is self: self._slate.__dict__.clear() @@ -80,6 +94,9 @@ def decorate_exception(self, cls: type[E], exception: E) -> E: + "\n\nSee if this has been reported at https://github.com/scikit-hep/awkward/issues" ) new_exception.__cause__ = exception + elif issubclass(cls, builtins.KeyError): + new_exception = KeyError(self.format_exception(exception)) + new_exception.__cause__ = exception else: new_exception = cls(self.format_exception(exception)) new_exception.__cause__ = exception @@ -123,8 +140,6 @@ def format_argument(self, width, value): valuestr = f"repr-raised-{type(err).__name__}" elif isinstance(value, np.ndarray): - import numpy # noqa: TID251 - if not numpy.__version__.startswith("1.13."): # 'threshold' argument prefix = f"{type(value).__module__}.{type(value).__name__}(" suffix = ")" @@ -147,7 +162,7 @@ def format_argument(self, width, value): if len(valuestr) > width: valuestr = valuestr[: width - 3] + "..." - elif isinstance(value, (Sequence, Mapping)) and len(value) < 10000: + elif isinstance(value, (Collection, Mapping)) and len(value) < 10000: valuestr = repr(value) if len(valuestr) > width: valuestr = valuestr[: width - 3] + "..." @@ -168,36 +183,65 @@ def note(self) -> str: class OperationErrorContext(ErrorContext): _width = 80 - 8 - def __init__(self, name, arguments): + def any_backend_is_delayed( + self, iterable: Iterable, *, depth: int = 1, depth_limit: int = 2 + ) -> bool: from awkward._backends.dispatch import backend_of - from awkward._backends.numpy import NumpyBackend - numpy_backend = NumpyBackend.instance() - if self.primary() is not None or all( - backend_of(x, default=numpy_backend).nplike.is_eager for x in arguments + for obj in iterable: + backend = backend_of(obj, default=None) + # Do we not recognise this as an object with a backend? + if backend is None: + # Is this an iterable object, and are we permitted to recurse? + if isinstance(obj, Collection) and depth != depth_limit: + return self.any_backend_is_delayed( + obj, depth=depth + 1, depth_limit=depth_limit + ) + # Assume not delayed! + else: + return False + # Eager backends aren't delayed! + elif backend.nplike.is_eager: + continue + else: + return True + return False + + def __init__(self, name, args: Iterable[Any], kwargs: Mapping[str, Any]): + if self.primary() is None and ( + self.any_backend_is_delayed(args) + or self.any_backend_is_delayed(kwargs.values()) ): + string_args = self._format_args(args) + string_kwargs = self._format_kwargs(kwargs) + else: # if primary is not None: we won't be setting an ErrorContext # if all nplikes are eager: no accumulation of large arrays # --> in either case, delay string generation - string_arguments = PartialFunction(self._string_arguments, arguments) - else: - string_arguments = self._string_arguments(arguments) + string_args = PartialFunction(self._format_args, args) + string_kwargs = PartialFunction(self._format_kwargs, kwargs) super().__init__( name=name, - arguments=string_arguments, + args=string_args, + kwargs=string_kwargs, ) - def _string_arguments(self, arguments): + def _format_args(self, arguments: Iterable) -> list[str]: + string_arguments = [] + for value in arguments: + string_arguments.append(self.format_argument(self._width, value)) + + return string_arguments + + def _format_kwargs(self, arguments: Mapping[str, Any]) -> dict[str, str]: string_arguments = {} for key, value in arguments.items(): if isinstance(key, str): width = self._width - len(key) - 3 else: width = self._width - string_arguments[key] = self.format_argument(width, value) - return string_arguments @property @@ -205,29 +249,39 @@ def name(self): return self._kwargs["name"] @property - def arguments(self): - out = self._kwargs["arguments"] + def args(self) -> list: + out = self._kwargs["args"] if isinstance(out, PartialFunction): - out = self._kwargs["arguments"] = out() + out = self._kwargs["args"] = out() return out - def format_exception(self, exception): + @property + def kwargs(self) -> dict: + out = self._kwargs["kwargs"] + if isinstance(out, PartialFunction): + out = self._kwargs["kwargs"] = out() + return out + + def format_exception(self, exception: Exception) -> str: return f"{exception}\n{self.note}" @property def note(self) -> str: arguments = [] - for name, valuestr in self.arguments.items(): + for valuestr in self.args: + arguments.append(f"\n {valuestr}") + for name, valuestr in self.kwargs.items(): if isinstance(name, str): arguments.append(f"\n {name} = {valuestr}") else: arguments.append(f"\n {valuestr}") extra_line = "" if len(arguments) == 0 else "\n " + calling_note = f'{self.name}({"".join(arguments)}{extra_line})' return f""" This error occurred while calling - {self.name}({"".join(arguments)}{extra_line})""" + {calling_note}""" class SlicingErrorContext(ErrorContext): @@ -364,3 +418,19 @@ def deprecate( class FieldNotFoundError(IndexError): ... + + +AxisError = numpy.AxisError + + +T = TypeVar("T", bound=Callable) + + +def with_operation_context(func: T) -> T: + @wraps(func) + def wrapper(*args, **kwargs): + # NOTE: this decorator assumes that the operation is exposed under `ak.` + with OperationErrorContext(f"ak.{func.__qualname__}", args, kwargs): + return func(*args, **kwargs) + + return wrapper diff --git a/src/awkward/_kernels.py b/src/awkward/_kernels.py index 890ed7afff..b0f418a052 100644 --- a/src/awkward/_kernels.py +++ b/src/awkward/_kernels.py @@ -10,6 +10,7 @@ from awkward._nplikes.jax import Jax from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyMetadata +from awkward._nplikes.typetracer import try_touch_data from awkward._typing import Protocol, TypeAlias KernelKeyType: TypeAlias = tuple # Tuple[str, Unpack[Tuple[metadata.dtype, ...]]] @@ -22,7 +23,6 @@ class KernelError(Protocol): filename: str | None # pylint: disable=E0602 str: str | None - pass_through: bool attempt: int id: int @@ -173,7 +173,6 @@ class TypeTracerKernelError(KernelError): def __init__(self): self.str = None self.filename = None - self.pass_through = False self.attempt = ak._util.kSliceNone self.id = ak._util.kSliceNone @@ -183,6 +182,8 @@ def __init__(self, index): self._name_and_types = index def __call__(self, *args) -> TypeTracerKernelError: + for arg in args: + try_touch_data(arg) return TypeTracerKernelError() def __repr__(self): diff --git a/src/awkward/_layout.py b/src/awkward/_layout.py index e6f99d766d..c03de0d51f 100644 --- a/src/awkward/_layout.py +++ b/src/awkward/_layout.py @@ -5,6 +5,7 @@ from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import AxisError from awkward._nplikes.dispatch import nplike_of from awkward._nplikes.jax import Jax from awkward._nplikes.numpy import Numpy @@ -156,7 +157,7 @@ def maybe_posaxis(layout, axis, depth): if isinstance(layout, Record): if axis == 0: - raise np.AxisError("Record type at axis=0 is a scalar, not an array") + raise AxisError("Record type at axis=0 is a scalar, not an array") return maybe_posaxis(layout._array, axis, depth) if axis >= 0: diff --git a/src/awkward/_nplikes/array_module.py b/src/awkward/_nplikes/array_module.py index 89526f1918..39e4f2381b 100644 --- a/src/awkward/_nplikes/array_module.py +++ b/src/awkward/_nplikes/array_module.py @@ -5,7 +5,14 @@ import numpy -from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyLike, NumpyMetadata +from awkward._nplikes.numpylike import ( + ArrayLike, + IndexType, + NumpyLike, + NumpyMetadata, + UniqueAllResult, +) +from awkward._nplikes.placeholder import PlaceholderArray from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._typing import Final, Literal @@ -24,7 +31,10 @@ def asarray( dtype: numpy.dtype | None = None, copy: bool | None = None, ) -> ArrayLike: - if copy: + if isinstance(obj, PlaceholderArray): + assert obj.dtype == dtype or dtype is None + return obj + elif copy: return self._module.array(obj, dtype=dtype, copy=True) elif copy is None: return self._module.asarray(obj, dtype=dtype) @@ -37,14 +47,16 @@ def asarray( return self._module.asarray(obj, dtype=dtype) def ascontiguousarray(self, x: ArrayLike) -> ArrayLike: - # Allow buffers to _pretend_ to be contiguous already - if x.dtype.metadata is not None and x.dtype.metadata.get("pretend_contiguous"): + if isinstance(x, PlaceholderArray): return x - return self._module.ascontiguousarray(x) + else: + return self._module.ascontiguousarray(x) def frombuffer( self, buffer, *, dtype: np.dtype | None = None, count: int = -1 ) -> ArrayLike: + assert not isinstance(buffer, PlaceholderArray) + assert not isinstance(count, PlaceholderArray) return self._module.frombuffer(buffer, dtype=dtype, count=count) def zeros( @@ -68,14 +80,17 @@ def full( return self._module.full(shape, fill_value, dtype=dtype) def zeros_like(self, x: ArrayLike, *, dtype: np.dtype | None = None) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.zeros_like(x, dtype=dtype) def ones_like(self, x: ArrayLike, *, dtype: np.dtype | None = None) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.ones_like(x, dtype=dtype) def full_like( self, x: ArrayLike, fill_value, *, dtype: np.dtype | None = None ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.full_like(x, fill_value, dtype=dtype) def arange( @@ -86,6 +101,9 @@ def arange( *, dtype: np.dtype | None = None, ) -> ArrayLike: + assert not isinstance(start, PlaceholderArray) + assert not isinstance(stop, PlaceholderArray) + assert not isinstance(step, PlaceholderArray) return self._module.arange(start, stop, step, dtype=dtype) def meshgrid( @@ -98,6 +116,8 @@ def meshgrid( def array_equal( self, x1: ArrayLike, x2: ArrayLike, *, equal_nan: bool = False ) -> ArrayLike: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) return self._module.asarray( self._module.array_equal(x1, x2, equal_nan=equal_nan) ) @@ -110,16 +130,21 @@ def searchsorted( side: Literal["left", "right"] = "left", sorter: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) + assert not isinstance(values, PlaceholderArray) + assert not isinstance(sorter, PlaceholderArray) return self._module.searchsorted(x, values, side=side, sorter=sorter) ############################ manipulation def broadcast_arrays(self, *arrays: ArrayLike) -> list[ArrayLike]: + assert not any(isinstance(x, PlaceholderArray) for x in arrays) return self._module.broadcast_arrays(*arrays) def reshape( self, x: ArrayLike, shape: tuple[ShapeItem, ...], *, copy: bool | None = None ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) if copy is None: return self._module.reshape(x, shape) elif copy: @@ -178,12 +203,17 @@ def regularize_index_for_length( raise IndexError(f"index value out of bounds (0, {length}): {index}") def nonzero(self, x: ArrayLike) -> tuple[ArrayLike, ...]: + assert not isinstance(x, PlaceholderArray) return self._module.nonzero(x) def where(self, condition: ArrayLike, x1: ArrayLike, x2: ArrayLike) -> ArrayLike: + assert not isinstance(condition, PlaceholderArray) + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) return self._module.where(condition, x1, x2) def unique_values(self, x: ArrayLike) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.unique( x, return_counts=False, @@ -192,12 +222,40 @@ def unique_values(self, x: ArrayLike) -> ArrayLike: equal_nan=False, ) + def unique_all(self, x: ArrayLike) -> UniqueAllResult: + assert not isinstance(x, PlaceholderArray) + values, indices, inverse_indices, counts = self._module.unique( + x, return_counts=True, return_index=True, return_inverse=True + ) + # np.unique() flattens inverse indices, but they need to share x's shape + # See https://github.com/numpy/numpy/issues/20638 + inverse_indices = inverse_indices.reshape(x.shape) + return UniqueAllResult(values, indices, inverse_indices, counts) + + def sort( + self, + x: ArrayLike, + *, + axis: int = -1, + descending: bool = False, + stable: bool = True, + ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) + # Note: this keyword argument is different, and the default is different. + kind = "stable" if stable else "quicksort" + res = self._module.sort(x, axis=axis, kind=kind) + if descending: + return self._module.flip(res, axis=axis) + else: + return res + def concat( self, arrays: list[ArrayLike] | tuple[ArrayLike, ...], *, axis: int | None = 0, ) -> ArrayLike: + assert not any(isinstance(x, PlaceholderArray) for x in arrays) return self._module.concatenate(arrays, axis=axis, casting="same_kind") def repeat( @@ -207,17 +265,17 @@ def repeat( *, axis: int | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) + assert not isinstance(repeats, PlaceholderArray) return self._module.repeat(x, repeats=repeats, axis=axis) - def tile(self, x: ArrayLike, reps: int) -> ArrayLike: - return self._module.tile(x, reps) - def stack( self, arrays: list[ArrayLike] | tuple[ArrayLike, ...], *, axis: int = 0, ) -> ArrayLike: + assert not any(isinstance(x, PlaceholderArray) for x in arrays) arrays = list(arrays) return self._module.stack(arrays, axis=axis) @@ -228,6 +286,7 @@ def packbits( axis: int | None = None, bitorder: Literal["big", "little"] = "big", ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.packbits(x, axis=axis, bitorder=bitorder) def unpackbits( @@ -238,42 +297,58 @@ def unpackbits( count: int | None = None, bitorder: Literal["big", "little"] = "big", ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.unpackbits(x, axis=axis, count=count, bitorder=bitorder) def broadcast_to(self, x: ArrayLike, shape: tuple[ShapeItem, ...]) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.broadcast_to(x, shape) + def strides(self, x: ArrayLike) -> tuple[ShapeItem, ...]: + return x.strides + ############################ ufuncs def add( self, x1: ArrayLike, x2: ArrayLike, maybe_out: ArrayLike | None = None ) -> ArrayLike: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) return self._module.add(x1, x2, out=maybe_out) def logical_or( self, x1: ArrayLike, x2: ArrayLike, *, maybe_out: ArrayLike | None = None ) -> ArrayLike: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) return self._module.logical_or(x1, x2, out=maybe_out) def logical_and( self, x1: ArrayLike, x2: ArrayLike, *, maybe_out: ArrayLike | None = None ) -> ArrayLike: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) return self._module.logical_and(x1, x2, out=maybe_out) def logical_not( self, x: ArrayLike, maybe_out: ArrayLike | None = None ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.logical_not(x, out=maybe_out) def sqrt(self, x: ArrayLike, maybe_out: ArrayLike | None = None) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.sqrt(x, out=maybe_out) def exp(self, x: ArrayLike, maybe_out: ArrayLike | None = None) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.exp(x, out=maybe_out) def divide( self, x1: ArrayLike, x2: ArrayLike, maybe_out: ArrayLike | None = None ) -> ArrayLike: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) return self._module.divide(x1, x2, out=maybe_out) ############################ almost-ufuncs @@ -287,6 +362,7 @@ def nan_to_num( posinf: int | float | None = None, neginf: int | float | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.nan_to_num( x, copy=copy, nan=nan, posinf=posinf, neginf=neginf ) @@ -300,9 +376,12 @@ def isclose( atol: float = 1e-8, equal_nan: bool = False, ) -> ArrayLike: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) return self._module.isclose(x1, x2, rtol=rtol, atol=atol, equal_nan=equal_nan) def isnan(self, x: ArrayLike) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.isnan(x) def all( @@ -313,6 +392,7 @@ def all( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.all(x, axis=axis, keepdims=keepdims, out=maybe_out) def any( @@ -323,6 +403,7 @@ def any( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.any(x, axis=axis, keepdims=keepdims, out=maybe_out) def min( @@ -333,6 +414,7 @@ def min( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.min(x, axis=axis, keepdims=keepdims, out=maybe_out) def max( @@ -343,11 +425,13 @@ def max( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.max(x, axis=axis, keepdims=keepdims, out=maybe_out) def count_nonzero( self, x: ArrayLike, *, axis: int | None = None, keepdims: bool = False ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.count_nonzero(x, axis=axis, keepdims=keepdims) def cumsum( @@ -357,6 +441,7 @@ def cumsum( axis: int | None = None, maybe_out: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return self._module.cumsum(x, axis=axis, out=maybe_out) def array_str( @@ -367,6 +452,7 @@ def array_str( precision: int | None = None, suppress_small: bool | None = None, ): + assert not isinstance(x, PlaceholderArray) return self._module.array_str( x, max_line_width=max_line_width, @@ -377,6 +463,7 @@ def array_str( def astype( self, x: ArrayLike, dtype: numpy.dtype, *, copy: bool | None = True ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) return x.astype(dtype, copy=copy) def can_cast(self, from_: np.dtype | ArrayLike, to: np.dtype | ArrayLike) -> bool: diff --git a/src/awkward/_nplikes/cupy.py b/src/awkward/_nplikes/cupy.py index 7a86ea4e50..fbc6335356 100644 --- a/src/awkward/_nplikes/cupy.py +++ b/src/awkward/_nplikes/cupy.py @@ -7,6 +7,7 @@ from awkward._nplikes.array_module import ArrayModuleNumpyLike from awkward._nplikes.dispatch import register_nplike from awkward._nplikes.numpylike import ArrayLike +from awkward._nplikes.placeholder import PlaceholderArray from awkward._typing import Final @@ -40,10 +41,14 @@ def ndarray(self): def frombuffer( self, buffer, *, dtype: numpy.dtype | None = None, count: int = -1 ) -> ArrayLike: + assert not isinstance(buffer, PlaceholderArray) + assert not isinstance(count, PlaceholderArray) np_array = numpy.frombuffer(buffer, dtype=dtype, count=count) return self._module.asarray(np_array) def array_equal(self, x1: ArrayLike, x2: ArrayLike, *, equal_nan: bool = False): + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) if x1.shape != x2.shape: return False else: @@ -52,6 +57,8 @@ def array_equal(self, x1: ArrayLike, x2: ArrayLike, *, equal_nan: bool = False): def repeat( self, x: ArrayLike, repeats: ArrayLike | int, *, axis: int | None = None ): + assert not isinstance(x, PlaceholderArray) + assert not isinstance(repeats, PlaceholderArray) if axis is not None: raise NotImplementedError(f"repeat for CuPy with axis={axis!r}") # https://github.com/cupy/cupy/issues/3849 @@ -75,6 +82,7 @@ def all( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) out = self._module.all(x, axis=axis, out=maybe_out) if axis is None and isinstance(out, self._module.ndarray): return out.item() @@ -89,6 +97,7 @@ def any( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) out = self._module.any(x, axis=axis, out=maybe_out) if axis is None and isinstance(out, self._module.ndarray): return out.item() @@ -102,6 +111,7 @@ def count_nonzero( axis: int | tuple[int, ...] | None = None, keepdims: bool = False, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) out = self._module.count_nonzero(x, axis=axis) if axis is None and isinstance(out, self._module.ndarray): return out.item() @@ -116,6 +126,7 @@ def min( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) out = self._module.min(x, axis=axis, out=maybe_out) if axis is None and isinstance(out, self._module.ndarray): return out.item() @@ -130,17 +141,13 @@ def max( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) out = self._module.max(x, axis=axis, out=maybe_out) if axis is None and isinstance(out, self._module.ndarray): return out.item() else: return out - def array_str( - self, array, max_line_width=None, precision=None, suppress_small=None - ): - return self._module.array_str(array, max_line_width, precision, suppress_small) - @classmethod def is_own_array_type(cls, type_: type) -> bool: """ @@ -154,6 +161,7 @@ def is_own_array_type(cls, type_: type) -> bool: return module == "cupy" def is_c_contiguous(self, x: ArrayLike) -> bool: - return x.flags["C_CONTIGUOUS"] or ( - x.dtype.metadata is not None and x.dtype.metadata.get("pretend_contiguous") - ) + if isinstance(x, PlaceholderArray): + return True + else: + return x.flags["C_CONTIGUOUS"] diff --git a/src/awkward/_nplikes/dispatch.py b/src/awkward/_nplikes/dispatch.py index 12959d58a6..fbb4db967c 100644 --- a/src/awkward/_nplikes/dispatch.py +++ b/src/awkward/_nplikes/dispatch.py @@ -2,7 +2,7 @@ from awkward._nplikes.numpylike import NumpyLike from awkward._typing import TypeVar -from awkward._util import unset +from awkward._util import UNSET D = TypeVar("D") @@ -19,7 +19,7 @@ def register_nplike(cls: N) -> N: return cls -def nplike_of(obj, *, default: D = unset) -> NumpyLike | D: +def nplike_of(obj, *, default: D = UNSET) -> NumpyLike | D: """ Args: *arrays: iterable of possible array objects @@ -41,7 +41,7 @@ def nplike_of(obj, *, default: D = unset) -> NumpyLike | D: nplike = nplike_cls.instance() break else: - if default is unset: + if default is UNSET: raise TypeError(f"cannot find nplike for {cls.__name__}") else: return default diff --git a/src/awkward/_nplikes/jax.py b/src/awkward/_nplikes/jax.py index 3e2c865057..31b6467aba 100644 --- a/src/awkward/_nplikes/jax.py +++ b/src/awkward/_nplikes/jax.py @@ -5,6 +5,7 @@ from awkward._nplikes.array_module import ArrayModuleNumpyLike from awkward._nplikes.dispatch import register_nplike from awkward._nplikes.numpylike import ArrayLike +from awkward._nplikes.shape import ShapeItem from awkward._typing import Final @@ -74,3 +75,10 @@ def is_c_contiguous(self, x: ArrayLike) -> bool: def ascontiguousarray(self, x: ArrayLike) -> ArrayLike: return x + + def strides(self, x: ArrayLike) -> tuple[ShapeItem, ...]: + x.touch_shape() + out = (x._dtype.itemsize,) + for item in reversed(x._shape): + out = (item * out[0], *out) + return out diff --git a/src/awkward/_nplikes/numpy.py b/src/awkward/_nplikes/numpy.py index 4515c66e5b..3490d8f75c 100644 --- a/src/awkward/_nplikes/numpy.py +++ b/src/awkward/_nplikes/numpy.py @@ -7,6 +7,7 @@ from awkward._nplikes.array_module import ArrayModuleNumpyLike from awkward._nplikes.dispatch import register_nplike from awkward._nplikes.numpylike import ArrayLike, NumpyMetadata +from awkward._nplikes.placeholder import PlaceholderArray from awkward._typing import Final, Literal np = NumpyMetadata.instance() @@ -43,9 +44,10 @@ def is_own_array_type(cls, type_) -> bool: return issubclass(type_, numpy.ndarray) def is_c_contiguous(self, x: ArrayLike) -> bool: - return x.flags["C_CONTIGUOUS"] or ( - x.dtype.metadata is not None and x.dtype.metadata.get("pretend_contiguous") - ) + if isinstance(x, PlaceholderArray): + return True + else: + return x.flags["C_CONTIGUOUS"] def packbits( self, @@ -54,6 +56,7 @@ def packbits( axis: int | None = None, bitorder: Literal["big", "little"] = "big", ): + assert not isinstance(x, PlaceholderArray) if ak._util.numpy_at_least("1.17.0"): return numpy.packbits(x, axis=axis, bitorder=bitorder) else: @@ -81,6 +84,7 @@ def unpackbits( count: int | None = None, bitorder: Literal["big", "little"] = "big", ): + assert not isinstance(x, PlaceholderArray) if ak._util.numpy_at_least("1.17.0"): return numpy.unpackbits(x, axis=axis, count=count, bitorder=bitorder) else: diff --git a/src/awkward/_nplikes/numpylike.py b/src/awkward/_nplikes/numpylike.py index 6a2c715d8d..573c65e8bc 100644 --- a/src/awkward/_nplikes/numpylike.py +++ b/src/awkward/_nplikes/numpylike.py @@ -9,6 +9,7 @@ from awkward._singleton import Singleton from awkward._typing import ( Literal, + NamedTuple, Protocol, Self, SupportsIndex, @@ -19,6 +20,13 @@ IndexType: TypeAlias = "int | ArrayLike" +class UniqueAllResult(NamedTuple): + values: ArrayLike + indices: ArrayLike + inverse_indices: ArrayLike + counts: ArrayLike + + class ArrayLike(Protocol): @property @abstractmethod @@ -402,6 +410,21 @@ def where(self, condition: ArrayLike, x1: ArrayLike, x2: ArrayLike) -> ArrayLike def unique_values(self, x: ArrayLike) -> ArrayLike: ... + @abstractmethod + def unique_all(self, x: ArrayLike) -> UniqueAllResult: + ... + + @abstractmethod + def sort( + self, + x: ArrayLike, + *, + axis: int = -1, + descending: bool = False, + stable: bool = True, + ) -> ArrayLike: + ... + @abstractmethod def concat( self, @@ -421,10 +444,6 @@ def repeat( ) -> ArrayLike: ... - @abstractmethod - def tile(self, x: ArrayLike, reps: int) -> ArrayLike: - ... - @abstractmethod def stack( self, @@ -455,6 +474,10 @@ def unpackbits( ) -> ArrayLike: ... + @abstractmethod + def strides(self, x: ArrayLike) -> tuple[ShapeItem, ...]: + ... + ############################ ufuncs @abstractmethod diff --git a/src/awkward/_nplikes/placeholder.py b/src/awkward/_nplikes/placeholder.py new file mode 100644 index 0000000000..03ea693145 --- /dev/null +++ b/src/awkward/_nplikes/placeholder.py @@ -0,0 +1,134 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations + +from functools import reduce +from operator import mul + +from awkward._nplikes.numpylike import ArrayLike, NumpyLike, NumpyMetadata +from awkward._nplikes.shape import ShapeItem, unknown_length +from awkward._typing import Self + +np = NumpyMetadata.instance() + + +class PlaceholderArray(ArrayLike): + def __init__( + self, nplike: NumpyLike, shape: tuple[ShapeItem, ...], dtype: np.dtype + ): + self._nplike = nplike + self._shape = shape + self._dtype = dtype + + @property + def dtype(self) -> np.dtype: + return self._dtype + + @property + def shape(self) -> tuple[ShapeItem, ...]: + return self._shape + + @property + def ndim(self) -> int: + return len(self._shape) + + @property + def size(self) -> ShapeItem: + return reduce(mul, self._shape) + + @property + def strides(self) -> tuple[ShapeItem, ...]: + out = (self._dtype.itemsize,) + for item in reversed(self._shape): + out = (item * out[0], *out) + return out + + @property + def itemsize(self) -> int: + return self._dtype.itemsize + + @property + def T(self): + return type(self)(self._nplike, self._shape[::-1], self._dtype) + + def view(self, dtype: dtype) -> Self: + dtype = np.dtype(dtype) + if len(self._shape) >= 1: + last, remainder = divmod(self._shape[-1] * self.itemsize, dtype.itemsize) + if remainder is not unknown_length and remainder != 0: + raise ValueError( + "new size of array with larger dtype must be a " + "divisor of the total size in bytes (of the last axis of the array)" + ) + shape = self._shape[:-1] + (last,) + else: + shape = self._shape + return type(self)(self._nplike, shape, dtype) + + def __getitem__(self, index): + if isinstance(index, slice): + if self._shape[0] is unknown_length: + return type(self)(self._nplike, self._shape, self._dtype) + else: + start, stop, step = index.indices(self._shape[0]) + new_shape = ((stop - start) // step,) + return type(self)(self._nplike, new_shape, self._dtype) + else: + raise TypeError( + f"{type(self).__name__} supports only trivial slices, not {type(index).__name__}" + ) + + def __setitem__(self, key, value): + raise RuntimeError + + def __bool__(self) -> bool: + raise RuntimeError + + def __int__(self) -> int: + raise RuntimeError + + def __index__(self) -> int: + raise RuntimeError + + def __len__(self) -> int: + return self._shape[0] + + def __add__(self, other): + raise RuntimeError + + def __and__(self, other): + raise RuntimeError + + def __eq__(self, other): + raise RuntimeError + + def __floordiv__(self, other): + raise RuntimeError + + def __ge__(self, other): + raise RuntimeError + + def __gt__(self, other): + raise RuntimeError + + def __invert__(self): + raise RuntimeError + + def __le__(self, other): + raise RuntimeError + + def __lt__(self, other): + raise RuntimeError + + def __mul__(self, other): + raise RuntimeError + + def __or__(self, other): + raise RuntimeError + + def __sub__(self, other): + raise RuntimeError + + def __truediv__(self, other): + raise RuntimeError + + __iter__ = None diff --git a/src/awkward/_nplikes/shape.py b/src/awkward/_nplikes/shape.py index e23f1c21fe..394d49e236 100644 --- a/src/awkward/_nplikes/shape.py +++ b/src/awkward/_nplikes/shape.py @@ -3,7 +3,7 @@ from awkward._typing import Self, TypeAlias -ShapeItem: TypeAlias = "int | _UnknownLength" +ShapeItem: TypeAlias = "int | type[unknown_length]" class _UnknownLength: @@ -17,7 +17,7 @@ def _new(cls, name: str) -> Self: def __new__(cls, *args, **kwargs): raise TypeError( - "internal_error: the `TypeTracer` nplike's `TypeTracerArray` object should never be directly instantiated" + "internal_error: the _UnknownLength class should never be directly instantiated" ) def __add__(self, other) -> Self | NotImplemented: @@ -56,6 +56,11 @@ def __floordiv__(self, other) -> Self | NotImplemented: __rfloordiv__ = __floordiv__ __ifloordiv__ = __floordiv__ + def __divmod__(self, other) -> tuple[Self, Self]: + return self, self + + __rdivmod__ = __divmod__ + def __str__(self) -> str: return "##" diff --git a/src/awkward/_nplikes/typetracer.py b/src/awkward/_nplikes/typetracer.py index bcb586ba04..2a7b663fc5 100644 --- a/src/awkward/_nplikes/typetracer.py +++ b/src/awkward/_nplikes/typetracer.py @@ -8,7 +8,14 @@ import awkward as ak from awkward._nplikes.dispatch import register_nplike -from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyLike, NumpyMetadata +from awkward._nplikes.numpylike import ( + ArrayLike, + IndexType, + NumpyLike, + NumpyMetadata, + UniqueAllResult, +) +from awkward._nplikes.placeholder import PlaceholderArray from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._regularize import is_integer, is_non_string_like_sequence from awkward._typing import ( @@ -136,72 +143,6 @@ def touch_data(self, label): self._data_touched.append(label) -def _attach_report(layout, form, report: TypeTracerReport): - if isinstance(layout, (ak.contents.BitMaskedArray, ak.contents.ByteMaskedArray)): - assert isinstance(form, (ak.forms.BitMaskedForm, ak.forms.ByteMaskedForm)) - layout.mask.data.form_key = form.form_key - layout.mask.data.report = report - _attach_report(layout.content, form.content, report) - - elif isinstance(layout, ak.contents.EmptyArray): - assert isinstance(form, ak.forms.EmptyForm) - - elif isinstance(layout, (ak.contents.IndexedArray, ak.contents.IndexedOptionArray)): - assert isinstance(form, (ak.forms.IndexedForm, ak.forms.IndexedOptionForm)) - layout.index.data.form_key = form.form_key - layout.index.data.report = report - _attach_report(layout.content, form.content, report) - - elif isinstance(layout, ak.contents.ListArray): - assert isinstance(form, ak.forms.ListForm) - layout.starts.data.form_key = form.form_key - layout.starts.data.report = report - layout.stops.data.form_key = form.form_key - layout.stops.data.report = report - _attach_report(layout.content, form.content, report) - - elif isinstance(layout, ak.contents.ListOffsetArray): - assert isinstance(form, ak.forms.ListOffsetForm) - layout.offsets.data.form_key = form.form_key - layout.offsets.data.report = report - _attach_report(layout.content, form.content, report) - - elif isinstance(layout, ak.contents.NumpyArray): - assert isinstance(form, ak.forms.NumpyForm) - layout.data.form_key = form.form_key - layout.data.report = report - - elif isinstance(layout, ak.contents.RecordArray): - assert isinstance(form, ak.forms.RecordForm) - for x, y in zip(layout.contents, form.contents): - _attach_report(x, y, report) - - elif isinstance(layout, (ak.contents.RegularArray, ak.contents.UnmaskedArray)): - assert isinstance(form, (ak.forms.RegularForm, ak.forms.UnmaskedForm)) - _attach_report(layout.content, form.content, report) - - elif isinstance(layout, ak.contents.UnionArray): - assert isinstance(form, ak.forms.UnionForm) - layout.tags.data.form_key = form.form_key - layout.tags.data.report = report - layout.index.data.form_key = form.form_key - layout.index.data.report = report - for x, y in zip(layout.contents, form.contents): - _attach_report(x, y, report) - - else: - raise AssertionError(f"unrecognized layout type {type(layout)}") - - -def typetracer_with_report(form, forget_length=True): - layout = form.length_zero_array(highlevel=False).to_typetracer( - forget_length=forget_length - ) - report = TypeTracerReport() - _attach_report(layout, form, report) - return layout, report - - class TypeTracerArray(NDArrayOperatorsMixin, ArrayLike): _dtype: numpy.dtype _shape: tuple[ShapeItem, ...] @@ -258,7 +199,7 @@ def T(self) -> Self: ) @property - def dtype(self): + def dtype(self) -> np.dtype: return self._dtype @property @@ -274,21 +215,21 @@ def shape(self) -> tuple[ShapeItem, ...]: return self._shape @property - def form_key(self): + def form_key(self) -> str | None: return self._form_key @form_key.setter - def form_key(self, value): + def form_key(self, value: str | None): if value is not None and not isinstance(value, str): raise TypeError("form_key must be None or a string") self._form_key = value @property - def report(self): + def report(self) -> TypeTracerReport | None: return self._report @report.setter - def report(self, value): + def report(self, value: TypeTracerReport | None): if value is not None and not isinstance(value, TypeTracerReport): raise TypeError("report must be None or a TypeTracerReport") self._report = value @@ -301,14 +242,6 @@ def touch_data(self): if self._report is not None: self._report.touch_data(self._form_key) - @property - def strides(self): - self.touch_shape() - out = (self._dtype.itemsize,) - for x in self._shape[:0:-1]: - out = (x * out[0], *out) - return out - @property def nplike(self) -> TypeTracer: return TypeTracer.instance() @@ -320,14 +253,13 @@ def ndim(self) -> int: def view(self, dtype: np.dtype) -> Self: dtype = np.dtype(dtype) - if ( - self.itemsize != dtype.itemsize - and self.ndim >= 1 - and self._shape[-1] is not None - ): - last = int( - round(self._shape[-1] * self.itemsize / np.dtype(dtype).itemsize) - ) + if len(self._shape) >= 1: + last, remainder = divmod(self._shape[-1] * self.itemsize, dtype.itemsize) + if remainder is not unknown_length and remainder != 0: + raise ValueError( + "new size of array with larger dtype must be a " + "divisor of the total size in bytes (of the last axis of the array)" + ) shape = self._shape[:-1] + (last,) else: shape = self._shape @@ -354,7 +286,7 @@ def __array__(self, dtype=None): ) @property - def itemsize(self): + def itemsize(self) -> int: return self._dtype.itemsize class _CTypes: @@ -376,7 +308,7 @@ def __getitem__( | Ellipsis | tuple[SupportsIndex | slice | Ellipsis | ArrayLike, ...] | ArrayLike, - ) -> Self: + ) -> Self | int | float | bool | complex: if not isinstance(key, tuple): key = (key,) @@ -450,6 +382,9 @@ def __getitem__( or is_unknown_integer(item) or is_unknown_array(item) ): + try_touch_data(item) + try_touch_data(self) + if is_unknown_scalar(item): item = self.nplike.promote_scalar(item) @@ -475,6 +410,9 @@ def __getitem__( previous_item_is_basic = True # Integer elif isinstance(item, int) or is_unknown_integer(item): + try_touch_data(item) + try_touch_data(self) + item = self.nplike.promote_scalar(item) if is_unknown_length(dimension_length) or is_unknown_integer(item): @@ -565,8 +503,11 @@ class TypeTracer(NumpyLike): def _apply_ufunc(self, ufunc, *inputs): for x in inputs: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) + inputs = [x.content if isinstance(x, MaybeNone) else x for x in inputs] + broadcasted = self.broadcast_arrays(*inputs) placeholders = [numpy.empty(0, x.dtype) for x in broadcasted] @@ -607,6 +548,8 @@ def asarray( dtype: numpy.dtype | None = None, copy: bool | None = None, ) -> TypeTracerArray: + assert not isinstance(obj, PlaceholderArray) + if isinstance(obj, ak.index.Index): obj = obj.data @@ -696,6 +639,7 @@ def populate_shape_and_items(node, dim): raise TypeError def ascontiguousarray(self, x: ArrayLike) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) return TypeTracerArray._new( x.dtype, shape=x.shape, form_key=x.form_key, report=x.report ) @@ -704,6 +648,7 @@ def frombuffer( self, buffer, *, dtype: np.dtype | None = None, count: int = -1 ) -> TypeTracerArray: for x in (buffer, count): + assert not isinstance(x, PlaceholderArray) try_touch_data(x) raise NotImplementedError @@ -735,6 +680,7 @@ def full( *, dtype: np.dtype | None = None, ) -> TypeTracerArray: + assert not isinstance(fill_value, PlaceholderArray) if not isinstance(shape, tuple): shape = (shape,) dtype = _scalar_type_of(fill_value) if dtype is None else dtype @@ -743,6 +689,7 @@ def full( def zeros_like( self, x: ArrayLike, *, dtype: np.dtype | None = None ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_shape(x) if is_unknown_scalar(x): return TypeTracerArray._new(dtype or x.dtype, shape=()) @@ -752,12 +699,14 @@ def zeros_like( def ones_like( self, x: ArrayLike, *, dtype: np.dtype | None = None ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_shape(x) return self.zeros_like(x, dtype=dtype) def full_like( self, x: ArrayLike, fill_value, *, dtype: np.dtype | None = None ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_shape(x) return self.zeros_like(x, dtype=dtype) @@ -769,6 +718,9 @@ def arange( *, dtype: np.dtype | None = None, ) -> TypeTracerArray: + assert not isinstance(start, PlaceholderArray) + assert not isinstance(stop, PlaceholderArray) + assert not isinstance(step, PlaceholderArray) try_touch_data(start) try_touch_data(stop) try_touch_data(step) @@ -787,6 +739,7 @@ def meshgrid( self, *arrays: ArrayLike, indexing: Literal["xy", "ij"] = "xy" ) -> list[TypeTracerArray]: for x in arrays: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) assert x.ndim == 1 @@ -803,6 +756,8 @@ def meshgrid( def array_equal( self, x1: ArrayLike, x2: ArrayLike, *, equal_nan: bool = False ) -> TypeTracerArray: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) try_touch_data(x1) try_touch_data(x2) return TypeTracerArray._new(np.bool_, shape=()) @@ -815,6 +770,9 @@ def searchsorted( side: Literal["left", "right"] = "left", sorter: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) + assert not isinstance(values, PlaceholderArray) + assert not isinstance(sorter, PlaceholderArray) try_touch_data(x) try_touch_data(values) try_touch_data(sorter) @@ -833,6 +791,7 @@ def searchsorted( ############################ manipulation def promote_scalar(self, obj) -> TypeTracerArray: + assert not isinstance(obj, PlaceholderArray) if is_unknown_scalar(obj): return obj elif isinstance(obj, (Number, bool)): @@ -992,6 +951,7 @@ def broadcast_shapes(self, *shapes: tuple[ShapeItem, ...]) -> tuple[ShapeItem, . def broadcast_arrays(self, *arrays: ArrayLike) -> list[TypeTracerArray]: for x in arrays: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) if len(arrays) == 0: @@ -1011,11 +971,29 @@ def broadcast_arrays(self, *arrays: ArrayLike) -> list[TypeTracerArray]: def broadcast_to( self, x: ArrayLike, shape: tuple[ShapeItem, ...] ) -> TypeTracerArray: - raise NotImplementedError + assert not isinstance(x, PlaceholderArray) + try_touch_data(x) + new_shape = self.broadcast_shapes(x.shape, shape) + # broadcast_to is asymmetric, whilst broadcast_shapes is not + # rather than implement broadcasting logic here, let's just santitise the result + # the above broadcasting result can either be equal to `shape`, have greater number dimensions, + # and/or have differing dimensions we only want the case where the shape is equal + if len(new_shape) != len(shape): + raise ValueError + + for result, intended in zip(new_shape, shape): + if intended is unknown_length: + continue + if result is unknown_length: + continue + if intended != result: + raise ValueError + return TypeTracerArray._new(x.dtype, shape=new_shape) def reshape( self, x: ArrayLike, shape: tuple[ShapeItem, ...], *, copy: bool | None = None ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) x.touch_shape() size = x.size @@ -1058,6 +1036,7 @@ def cumsum( axis: int | None = None, maybe_out: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) if axis is None: return TypeTracerArray._new(x.dtype, (x.size,)) @@ -1066,6 +1045,7 @@ def cumsum( return TypeTracerArray._new(x.dtype, x.shape) def nonzero(self, x: ArrayLike) -> tuple[TypeTracerArray, ...]: + assert not isinstance(x, PlaceholderArray) # array try_touch_data(x) return (TypeTracerArray._new(np.int64, (unknown_length,)),) * len(x.shape) @@ -1073,14 +1053,40 @@ def nonzero(self, x: ArrayLike) -> tuple[TypeTracerArray, ...]: def where( self, condition: ArrayLike, x1: ArrayLike, x2: ArrayLike ) -> TypeTracerArray: + assert not isinstance(condition, PlaceholderArray) + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) condition, x1, x2 = self.broadcast_arrays(condition, x1, x2) result_dtype = numpy.result_type(x1, x2) return TypeTracerArray._new(result_dtype, shape=condition.shape) def unique_values(self, x: ArrayLike) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) return TypeTracerArray._new(x.dtype, shape=(unknown_length,)) + def unique_all(self, x: ArrayLike) -> UniqueAllResult: + assert not isinstance(x, PlaceholderArray) + try_touch_data(x) + return UniqueAllResult( + TypeTracerArray._new(x.dtype, shape=(unknown_length,)), + TypeTracerArray._new(np.int64, shape=(unknown_length,)), + TypeTracerArray._new(np.int64, shape=x.shape), + TypeTracerArray._new(np.int64, shape=(unknown_length,)), + ) + + def sort( + self, + x: ArrayLike, + *, + axis: int = -1, + descending: bool = False, + stable: bool = True, + ) -> ArrayLike: + assert not isinstance(x, PlaceholderArray) + try_touch_data(x) + return TypeTracerArray._new(x.dtype, shape=x.shape) + def concat(self, arrays, *, axis: int | None = 0) -> TypeTracerArray: if axis is None: assert all(x.ndim == 1 for x in arrays) @@ -1092,6 +1098,7 @@ def concat(self, arrays, *, axis: int | None = 0) -> TypeTracerArray: inner_shape = None emptyarrays = [] for x in arrays: + assert not isinstance(x, PlaceholderArray) if inner_shape is None: inner_shape = x.shape[1:] elif inner_shape != x.shape[1:]: @@ -1116,13 +1123,25 @@ def repeat( *, axis: int | None = None, ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) + assert not isinstance(repeats, PlaceholderArray) try_touch_data(x) try_touch_data(repeats) - raise NotImplementedError - def tile(self, x: ArrayLike, reps: int) -> TypeTracerArray: - try_touch_data(x) - raise NotImplementedError + if axis is None: + size = x.size + if is_unknown_array(repeats): + size = unknown_length + else: + size = size * self.index_as_shape_item(repeats) + return TypeTracerArray._new(x.dtype, (size,)) + else: + shape = list(x.shape) + if isinstance(repeats, TypeTracerArray) and repeats.ndim > 0: + raise NotImplementedError + else: + shape[axis] = shape[axis] * self.index_as_shape_item(repeats) + return TypeTracerArray._new(x.dtype, shape=tuple(shape)) def stack( self, @@ -1131,6 +1150,7 @@ def stack( axis: int = 0, ) -> TypeTracerArray: for x in arrays: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) raise NotImplementedError @@ -1141,6 +1161,7 @@ def packbits( axis: int | None = None, bitorder: Literal["big", "little"] = "big", ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) raise NotImplementedError @@ -1152,9 +1173,18 @@ def unpackbits( count: int | None = None, bitorder: Literal["big", "little"] = "big", ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) raise NotImplementedError + def strides(self, x: ArrayLike) -> tuple[ShapeItem, ...]: + assert not isinstance(x, PlaceholderArray) + x.touch_shape() + out = (x._dtype.itemsize,) + for item in reversed(x._shape): + out = (item * out[0], *out) + return out + ############################ ufuncs def add( @@ -1163,6 +1193,7 @@ def add( x2: ArrayLike, maybe_out: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x1, PlaceholderArray) return self._apply_ufunc(numpy.add, x1, x2) def logical_and( @@ -1171,6 +1202,7 @@ def logical_and( x2: ArrayLike, maybe_out: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x1, PlaceholderArray) return self._apply_ufunc(numpy.logical_and, x1, x2) def logical_or( @@ -1179,17 +1211,22 @@ def logical_or( x2: ArrayLike, maybe_out: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) return self._apply_ufunc(numpy.logical_or, x1, x2) def logical_not( self, x: ArrayLike, maybe_out: ArrayLike | None = None ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) return self._apply_ufunc(numpy.logical_not, x) def sqrt(self, x: ArrayLike, maybe_out: ArrayLike | None = None) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) return self._apply_ufunc(numpy.sqrt, x) def exp(self, x: ArrayLike, maybe_out: ArrayLike | None = None) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) return self._apply_ufunc(numpy.exp, x) def divide( @@ -1198,6 +1235,8 @@ def divide( x2: ArrayLike, maybe_out: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) return self._apply_ufunc(numpy.divide, x1, x2) ############################ almost-ufuncs @@ -1211,6 +1250,7 @@ def nan_to_num( posinf: int | float | None = None, neginf: int | float | None = None, ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) return TypeTracerArray._new(x.dtype, shape=x.shape) @@ -1223,12 +1263,15 @@ def isclose( atol: float = 1e-8, equal_nan: bool = False, ) -> TypeTracerArray: + assert not isinstance(x1, PlaceholderArray) + assert not isinstance(x2, PlaceholderArray) try_touch_data(x1) try_touch_data(x2) out, _ = self.broadcast_arrays(x1, x2) return TypeTracerArray._new(np.bool_, shape=out.shape) def isnan(self, x: ArrayLike) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) return TypeTracerArray._new(np.bool_, shape=x.shape) @@ -1242,6 +1285,7 @@ def all( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) if axis is None: return TypeTracerArray._new(np.bool_, shape=()) @@ -1256,6 +1300,7 @@ def any( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) if axis is None: return TypeTracerArray._new(np.bool_, shape=()) @@ -1265,8 +1310,12 @@ def any( def count_nonzero( self, x: ArrayLike, *, axis: int | None = None, keepdims: bool = False ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) - raise NotImplementedError + if axis is None: + return TypeTracerArray._new(np.intp, shape=()) + else: + raise NotImplementedError def min( self, @@ -1276,6 +1325,7 @@ def min( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) raise NotImplementedError @@ -1287,8 +1337,12 @@ def max( keepdims: bool = False, maybe_out: ArrayLike | None = None, ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) try_touch_data(x) - raise NotImplementedError + if axis is None: + return TypeTracerArray._new(x.dtype, shape=()) + else: + raise NotImplementedError def array_str( self, @@ -1298,12 +1352,14 @@ def array_str( precision: int | None = None, suppress_small: bool | None = None, ): + assert not isinstance(x, PlaceholderArray) try_touch_data(x) return "[## ... ##]" def astype( self, x: ArrayLike, dtype: numpy.dtype, *, copy: bool | None = True ) -> TypeTracerArray: + assert not isinstance(x, PlaceholderArray) x.touch_data() return TypeTracerArray._new(np.dtype(dtype), x.shape) @@ -1319,4 +1375,75 @@ def is_own_array(cls, obj) -> bool: return cls.is_own_array_type(type(obj)) def is_c_contiguous(self, x: ArrayLike) -> bool: + assert not isinstance(x, PlaceholderArray) return True + + +def _attach_report( + layout: ak.contents.Content, form: ak.forms.Form, report: TypeTracerReport +): + if isinstance(layout, (ak.contents.BitMaskedArray, ak.contents.ByteMaskedArray)): + assert isinstance(form, (ak.forms.BitMaskedForm, ak.forms.ByteMaskedForm)) + layout.mask.data.form_key = form.form_key + layout.mask.data.report = report + _attach_report(layout.content, form.content, report) + + elif isinstance(layout, ak.contents.EmptyArray): + assert isinstance(form, ak.forms.EmptyForm) + + elif isinstance(layout, (ak.contents.IndexedArray, ak.contents.IndexedOptionArray)): + assert isinstance(form, (ak.forms.IndexedForm, ak.forms.IndexedOptionForm)) + layout.index.data.form_key = form.form_key + layout.index.data.report = report + _attach_report(layout.content, form.content, report) + + elif isinstance(layout, ak.contents.ListArray): + assert isinstance(form, ak.forms.ListForm) + layout.starts.data.form_key = form.form_key + layout.starts.data.report = report + layout.stops.data.form_key = form.form_key + layout.stops.data.report = report + _attach_report(layout.content, form.content, report) + + elif isinstance(layout, ak.contents.ListOffsetArray): + assert isinstance(form, ak.forms.ListOffsetForm) + layout.offsets.data.form_key = form.form_key + layout.offsets.data.report = report + _attach_report(layout.content, form.content, report) + + elif isinstance(layout, ak.contents.NumpyArray): + assert isinstance(form, ak.forms.NumpyForm) + layout.data.form_key = form.form_key + layout.data.report = report + + elif isinstance(layout, ak.contents.RecordArray): + assert isinstance(form, ak.forms.RecordForm) + for x, y in zip(layout.contents, form.contents): + _attach_report(x, y, report) + + elif isinstance(layout, (ak.contents.RegularArray, ak.contents.UnmaskedArray)): + assert isinstance(form, (ak.forms.RegularForm, ak.forms.UnmaskedForm)) + _attach_report(layout.content, form.content, report) + + elif isinstance(layout, ak.contents.UnionArray): + assert isinstance(form, ak.forms.UnionForm) + layout.tags.data.form_key = form.form_key + layout.tags.data.report = report + layout.index.data.form_key = form.form_key + layout.index.data.report = report + for x, y in zip(layout.contents, form.contents): + _attach_report(x, y, report) + + else: + raise AssertionError(f"unrecognized layout type {type(layout)}") + + +def typetracer_with_report( + form: ak.forms.Form, forget_length: bool = True +) -> tuple[ak.contents.Content, TypeTracerReport]: + layout = form.length_zero_array(highlevel=False).to_typetracer( + forget_length=forget_length + ) + report = TypeTracerReport() + _attach_report(layout, form, report) + return layout, report diff --git a/src/awkward/_reducers.py b/src/awkward/_reducers.py index 2c539ebb36..04dee1a40f 100644 --- a/src/awkward/_reducers.py +++ b/src/awkward/_reducers.py @@ -1,13 +1,14 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE from __future__ import annotations -from abc import ABC, abstractmethod -from typing import Any as AnyType +from abc import abstractmethod import awkward as ak from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyMetadata -from awkward._typing import Final +from awkward._nplikes.shape import ShapeItem +from awkward._typing import Any as AnyType +from awkward._typing import Final, Protocol np = NumpyMetadata.instance() numpy = Numpy.instance() @@ -15,7 +16,7 @@ DTypeLike = AnyType -class Reducer(ABC): +class Reducer(Protocol): name: str # Does the output correspond to array positions? @@ -33,66 +34,123 @@ def preferred_dtype(self) -> DTypeLike: def highlevel_function(cls): return getattr(ak.operations, cls.name) - @classmethod - def return_dtype(cls, given_dtype: DTypeLike) -> DTypeLike: - if given_dtype in (np.bool_, np.int8, np.int16, np.int32): - return np.int32 if ak._util.win or ak._util.bits32 else np.int64 - - if given_dtype in (np.uint8, np.uint16, np.uint32): - return np.uint32 if ak._util.win or ak._util.bits32 else np.uint64 + @abstractmethod + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: + ... - return given_dtype +class KernelReducer(Reducer): @classmethod - def maybe_double_length(cls, type: DTypeLike, length: int) -> int: + def _length_for_kernel(cls, type: DTypeLike, length: ShapeItem) -> ShapeItem: + # Complex types are implemented as double-wide arrays return 2 * length if type in (np.complex128, np.complex64) else length @classmethod - def maybe_other_type(cls, dtype: DTypeLike) -> DTypeLike: + def _dtype_for_kernel(cls, dtype: DTypeLike) -> DTypeLike: dtype = np.dtype(dtype) - type = np.int64 if dtype.kind.upper() == "M" else dtype.type - if dtype == np.complex128: - type = np.float64 - if dtype == np.complex64: - type = np.float32 - return type + if dtype.kind.upper() == "M": + return np.dtype(np.int64) + elif dtype == np.complex128: + return np.dtype(np.float64) + elif dtype == np.complex64: + return np.dtype(np.float32) + else: + return dtype - @abstractmethod - def identity_for(self, dtype: DTypeLike | None): - raise NotImplementedError + @classmethod + def _promote_integer_rank(cls, given_dtype: DTypeLike) -> DTypeLike: + if given_dtype in (np.bool_, np.int8, np.int16, np.int32): + return np.int32 if ak._util.win or ak._util.bits32 else np.int64 - @abstractmethod - def apply(self, array, parents, outlength: int): - raise NotImplementedError + elif given_dtype in (np.uint8, np.uint16, np.uint32): + return np.uint32 if ak._util.win or ak._util.bits32 else np.uint64 + else: + return given_dtype -class ArgMin(Reducer): - name: Final = "argmin" - needs_position: Final = True - preferred_dtype: Final = np.int64 - @classmethod - def return_dtype(cls, given_dtype): - return np.int64 +def apply_positional_corrections( + reduced: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, +): + if shifts is None: + assert ( + parents.nplike is reduced.backend.index_nplike + and starts.nplike is reduced.backend.index_nplike + ) + reduced.backend.maybe_kernel_error( + reduced.backend[ + "awkward_NumpyArray_reduce_adjust_starts_64", + reduced.dtype.type, + parents.dtype.type, + starts.dtype.type, + ]( + reduced.data, + reduced.length, + parents.data, + starts.data, + ) + ) + else: + assert ( + parents.nplike is reduced.backend.index_nplike + and starts.nplike is reduced.backend.index_nplike + and shifts.nplike is reduced.backend.index_nplike + ) + reduced.backend.maybe_kernel_error( + reduced._backend[ + "awkward_NumpyArray_reduce_adjust_starts_shifts_64", + reduced.dtype.type, + parents.dtype.type, + starts.dtype.type, + shifts.dtype.type, + ]( + reduced.data, + reduced.length, + parents.data, + starts.data, + shifts.data, + ) + ) + - def identity_for(self, dtype: np.dtype | None): - return np.int64(-1) +class ArgMin(KernelReducer): + name: Final = "argmin" + preferred_dtype: Final = np.int64 + needs_position: Final = True - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) - dtype = self.maybe_other_type(array.dtype) + # View array data in kernel-supported dtype + kernel_array_data = array.data.view(self._dtype_for_kernel(array.dtype)) result = array.backend.nplike.empty(outlength, dtype=np.int64) if array.dtype.type in (np.complex128, np.complex64): assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_argmin_complex", result.dtype.type, - dtype, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, @@ -100,50 +158,53 @@ def apply(self, array, parents, outlength): ) else: assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_argmin", result.dtype.type, - dtype, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, ) ) - return ak.contents.NumpyArray(result) + result_array = ak.contents.NumpyArray(result, backend=array.backend) + apply_positional_corrections(result_array, parents, starts, shifts) + return result_array -class ArgMax(Reducer): +class ArgMax(KernelReducer): name: Final = "argmax" - needs_position: Final = True preferred_dtype: Final = np.int64 + needs_position: Final = True - @classmethod - def return_dtype(cls, given_dtype): - return np.int64 - - def identity_for(self, dtype: np.dtype | None): - return np.int64(-1) - - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) - dtype = self.maybe_other_type(array.dtype) + # View array data in kernel-supported dtype + kernel_array_data = array.data.view(self._dtype_for_kernel(array.dtype)) result = array.backend.nplike.empty(outlength, dtype=np.int64) if array.dtype.type in (np.complex128, np.complex64): assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_argmax_complex", result.dtype.type, - dtype, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, @@ -151,37 +212,42 @@ def apply(self, array, parents, outlength): ) else: assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_argmax", result.dtype.type, - dtype, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, ) ) - return ak.contents.NumpyArray(result) + result_array = ak.contents.NumpyArray(result, backend=array.backend) + apply_positional_corrections(result_array, parents, starts, shifts) + return result_array -class Count(Reducer): +class Count(KernelReducer): name: Final = "count" preferred_dtype: Final = np.int64 needs_position: Final = False - @classmethod - def return_dtype(cls, given_dtype): - return np.int64 - - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) result = array.backend.nplike.empty(outlength, dtype=np.int64) assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_count_64", result.dtype.type, parents.dtype.type ]( @@ -191,36 +257,38 @@ def apply(self, array, parents, outlength): outlength, ) ) - return ak.contents.NumpyArray(result) - - def identity_for(self, dtype: np.dtype | None): - return np.int64(0) + return ak.contents.NumpyArray(result, backend=array.backend) -class CountNonzero(Reducer): +class CountNonzero(KernelReducer): name: Final = "count_nonzero" preferred_dtype: Final = np.float64 needs_position: Final = False - @classmethod - def return_dtype(cls, given_dtype): - return np.int64 - - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) - dtype = np.dtype(np.int64) if array.dtype.kind.upper() == "M" else array.dtype + # View array data in kernel-supported dtype + kernel_array_data = array.data.view(self._dtype_for_kernel(array.dtype)) + result = array.backend.nplike.empty(outlength, dtype=np.int64) - if array.dtype.type in (np.complex128, np.complex64): + if np.issubdtype(array.dtype, np.complexfloating): assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_countnonzero_complex", result.dtype.type, - np.float64 if array.dtype.type == np.complex128 else np.float32, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, @@ -228,46 +296,49 @@ def apply(self, array, parents, outlength): ) else: assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_countnonzero", result.dtype.type, - dtype.type, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, ) ) - return ak.contents.NumpyArray(result) - - def identity_for(self, dtype: np.dtype | None): - return np.int64(0) + return ak.contents.NumpyArray(result, backend=array.backend) -class Sum(Reducer): +class Sum(KernelReducer): name: Final = "sum" preferred_dtype: Final = np.float64 needs_position: Final = False - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) if array.dtype.kind == "M": raise ValueError(f"cannot compute the sum (ak.sum) of {array.dtype!r}") - else: - dtype = self.maybe_other_type(array.dtype) - result = array.backend.nplike.empty( - self.maybe_double_length(array.dtype.type, outlength), - dtype=self.return_dtype(dtype), - ) + # Boolean kernels are special; the result is _not_ a boolean if array.dtype == np.bool_: + result = array.backend.nplike.empty( + self._length_for_kernel(array.dtype.type, outlength), + dtype=self._promote_integer_rank(np.bool_), + ) if result.dtype in (np.int64, np.uint64): assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_sum_int64_bool_64", np.int64, @@ -283,7 +354,7 @@ def apply(self, array, parents, outlength): ) elif result.dtype in (np.int32, np.uint32): assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_sum_int32_bool_64", np.int32, @@ -299,74 +370,79 @@ def apply(self, array, parents, outlength): ) else: raise NotImplementedError - elif array.dtype.type in (np.complex128, np.complex64): - assert parents.nplike is array.backend.index_nplike - array._handle_error( - array.backend[ - "awkward_reduce_sum_complex", - np.float64 if array.dtype.type == np.complex128 else np.float32, - np.float64 if array.dtype.type == np.complex128 else np.float32, - parents.dtype.type, - ]( - result, - array.data, - parents.data, - parents.length, - outlength, - ) - ) + return ak.contents.NumpyArray(result, backend=array.backend) else: - assert parents.nplike is array.backend.index_nplike - array._handle_error( - array.backend[ - "awkward_reduce_sum", - result.dtype.type, - np.int64 if array.dtype.kind == "m" else array.dtype.type, - parents.dtype.type, - ]( - result, - array.data, - parents.data, - parents.length, - outlength, - ) + # View array data in kernel-supported dtype + kernel_array_data = array.data.view(self._dtype_for_kernel(array.dtype)) + result = array.backend.nplike.empty( + self._length_for_kernel(array.dtype.type, outlength), + dtype=self._promote_integer_rank(kernel_array_data.dtype), ) + if array.dtype.type in (np.complex128, np.complex64): + assert parents.nplike is array.backend.index_nplike + array.backend.maybe_kernel_error( + array.backend[ + "awkward_reduce_sum_complex", + result.dtype.type, + kernel_array_data.dtype.type, + parents.dtype.type, + ]( + result, + kernel_array_data, + parents.data, + parents.length, + outlength, + ) + ) + else: + assert parents.nplike is array.backend.index_nplike + array.backend.maybe_kernel_error( + array.backend[ + "awkward_reduce_sum", + result.dtype.type, + kernel_array_data.dtype.type, + parents.dtype.type, + ]( + result, + kernel_array_data, + parents.data, + parents.length, + outlength, + ) + ) - if array.dtype.kind == "m": return ak.contents.NumpyArray( - array.backend.nplike.asarray(result, dtype=array.dtype) + result.view(self._promote_integer_rank(array.dtype)), + backend=array.backend, ) - elif array.dtype.type in (np.complex128, np.complex64): - return ak.contents.NumpyArray(result.view(array.dtype)) - else: - return ak.contents.NumpyArray(result) - - def identity_for(self, dtype: np.dtype | None): - if dtype is None: - dtype = self.preferred_dtype - if dtype in {np.timedelta64, np.datetime64}: - return np.timedelta64(0) - else: - return numpy.asarray(0, dtype=dtype)[()] - -class Prod(Reducer): +class Prod(KernelReducer): name: Final = "prod" preferred_dtype: Final = np.int64 needs_position: Final = False - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) if array.dtype.kind.upper() == "M": raise ValueError(f"cannot compute the product (ak.prod) of {array.dtype!r}") + + # Boolean kernels are special; the result is _not_ a boolean if array.dtype == np.bool_: result = array.backend.nplike.empty( - self.maybe_double_length(array.dtype.type, outlength), - dtype=np.dtype(np.bool_), + outlength, + # This kernel, unlike sum, returns bools! + dtype=np.bool_, ) assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_prod_bool", result.dtype.type, @@ -380,88 +456,87 @@ def apply(self, array, parents, outlength): outlength, ) ) - result = array.backend.nplike.astype( - result, dtype=self.return_dtype(array.dtype) - ) - elif array.dtype.type in (np.complex128, np.complex64): - result = array.backend.nplike.empty( - self.maybe_double_length(array.dtype.type, outlength), - dtype=self.return_dtype(array.dtype), - ) - assert parents.nplike is array.backend.index_nplike - array._handle_error( - array.backend[ - "awkward_reduce_prod_complex", - np.float64 if array.dtype.type == np.complex128 else np.float32, - np.float64 if array.dtype.type == np.complex128 else np.float32, - parents.dtype.type, - ]( - result, - array.data, - parents.data, - parents.length, - outlength, - ) + return ak.contents.NumpyArray( + array.backend.nplike.astype( + result, dtype=self._promote_integer_rank(array.dtype) + ), + backend=array.backend, ) else: + # View array data in kernel-supported dtype + kernel_array_data = array.data.view(self._dtype_for_kernel(array.dtype)) result = array.backend.nplike.empty( - self.maybe_double_length(array.dtype.type, outlength), - dtype=self.return_dtype(array.dtype), + self._length_for_kernel(array.dtype.type, outlength), + dtype=self._promote_integer_rank(kernel_array_data.dtype), ) - assert parents.nplike is array.backend.index_nplike - array._handle_error( - array.backend[ - "awkward_reduce_prod", - result.dtype.type, - array.dtype.type, - parents.dtype.type, - ]( - result, - array.data, - parents.data, - parents.length, - outlength, + if array.dtype.type in (np.complex128, np.complex64): + assert parents.nplike is array.backend.index_nplike + array.backend.maybe_kernel_error( + array.backend[ + "awkward_reduce_prod_complex", + result.dtype.type, + kernel_array_data.dtype.type, + parents.dtype.type, + ]( + result, + kernel_array_data, + parents.data, + parents.length, + outlength, + ) + ) + else: + assert parents.nplike is array.backend.index_nplike + array.backend.maybe_kernel_error( + array.backend[ + "awkward_reduce_prod", + result.dtype.type, + kernel_array_data.dtype.type, + parents.dtype.type, + ]( + result, + kernel_array_data, + parents.data, + parents.length, + outlength, + ) ) - ) - if array.dtype.type in (np.complex128, np.complex64): - return ak.contents.NumpyArray(result.view(array.dtype)) - else: - return ak.contents.NumpyArray(result) - - def identity_for(self, dtype: np.dtype | None): - if dtype is None: - dtype = self.preferred_dtype - if dtype in {np.timedelta64, np.datetime64}: - return np.timedelta64(0) - else: - return numpy.asarray(1, dtype=dtype)[()] + return ak.contents.NumpyArray( + result.view(self._promote_integer_rank(array.dtype)), + backend=array.backend, + ) -class Any(Reducer): +class Any(KernelReducer): name: Final = "any" preferred_dtype: Final = np.bool_ needs_position: Final = False - @classmethod - def return_dtype(cls, given_dtype): - return np.bool_ - - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) - dtype = self.maybe_other_type(array.dtype) + # View array data in kernel-supported dtype + kernel_array_data = array.data.view(self._dtype_for_kernel(array.dtype)) result = array.backend.nplike.empty(outlength, dtype=np.bool_) + if array.dtype.type in (np.complex128, np.complex64): assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_sum_bool_complex", result.dtype.type, - dtype, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, @@ -469,50 +544,52 @@ def apply(self, array, parents, outlength): ) else: assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_sum_bool", result.dtype.type, - dtype, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, ) ) - return ak.contents.NumpyArray(result) + return ak.contents.NumpyArray(result, backend=array.backend) - def identity_for(self, dtype: DTypeLike | None) -> float: - return False - -class All(Reducer): +class All(KernelReducer): name: Final = "all" preferred_dtype: Final = np.bool_ needs_position: Final = False - @classmethod - def return_dtype(cls, given_dtype): - return np.bool_ - - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) - dtype = self.maybe_other_type(array.dtype) + # View array data in kernel-supported dtype + kernel_array_data = array.data.view(self._dtype_for_kernel(array.dtype)) result = array.backend.nplike.empty(outlength, dtype=np.bool_) + if array.dtype.type in (np.complex128, np.complex64): assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_prod_bool_complex", result.dtype.type, - dtype, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, @@ -520,27 +597,24 @@ def apply(self, array, parents, outlength): ) else: assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_prod_bool", result.dtype.type, - dtype, + kernel_array_data.dtype.type, parents.dtype.type, ]( result, - array.data, + kernel_array_data, parents.data, parents.length, outlength, ) ) - return ak.contents.NumpyArray(result) - - def identity_for(self, dtype: DTypeLike | None) -> float: - return True + return ak.contents.NumpyArray(result, backend=array.backend) -class Min(Reducer): +class Min(KernelReducer): name: Final = "min" preferred_dtype: Final = np.float64 needs_position: Final = False @@ -552,7 +626,7 @@ def __init__(self, initial: float | None): def initial(self) -> float | None: return self._initial - def identity_for(self, dtype: DTypeLike | None) -> float: + def _identity_for(self, dtype: DTypeLike | None) -> float: dtype = np.dtype(dtype) assert ( @@ -575,15 +649,19 @@ def identity_for(self, dtype: DTypeLike | None) -> float: return self._initial - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) - dtype = self.maybe_other_type(array.dtype) - result = array.backend.nplike.empty( - self.maybe_double_length(array.dtype.type, outlength), dtype=dtype - ) if array.dtype == np.bool_: + result = array.backend.nplike.empty(outlength, dtype=np.bool_) assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_prod_bool", result.dtype.type, @@ -597,53 +675,54 @@ def apply(self, array, parents, outlength): outlength, ) ) - elif array.dtype.type in (np.complex128, np.complex64): - assert parents.nplike is array.backend.index_nplike - array._handle_error( - array.backend[ - "awkward_reduce_min_complex", - result.dtype.type, - dtype, - parents.dtype.type, - ]( - result, - array.data, - parents.data, - parents.length, - outlength, - self.identity_for(dtype), - ) - ) + return ak.contents.NumpyArray(result, backend=array.backend) else: - assert parents.nplike is array.backend.index_nplike - array._handle_error( - array.backend[ - "awkward_reduce_min", - result.dtype.type, - dtype, - parents.dtype.type, - ]( - result, - array.data, - parents.data, - parents.length, - outlength, - self.identity_for(dtype), - ) + # View array data in kernel-supported dtype + kernel_array_data = array.data.view(self._dtype_for_kernel(array.dtype)) + result = array.backend.nplike.empty( + self._length_for_kernel(array.dtype.type, outlength), + dtype=kernel_array_data.dtype, ) - if array.dtype.type in (np.complex128, np.complex64): - return ak.contents.NumpyArray( - array.backend.nplike.asarray( - result.view(array.dtype), dtype=array.dtype + if array.dtype.type in (np.complex128, np.complex64): + assert parents.nplike is array.backend.index_nplike + array.backend.maybe_kernel_error( + array.backend[ + "awkward_reduce_min_complex", + result.dtype.type, + kernel_array_data.dtype.type, + parents.dtype.type, + ]( + result, + kernel_array_data, + parents.data, + parents.length, + outlength, + self._identity_for(result.dtype), + ) + ) + else: + assert parents.nplike is array.backend.index_nplike + array.backend.maybe_kernel_error( + array.backend[ + "awkward_reduce_min", + result.dtype.type, + kernel_array_data.dtype.type, + parents.dtype.type, + ]( + result, + kernel_array_data, + parents.data, + parents.length, + outlength, + self._identity_for(result.dtype), + ) ) - ) - else: return ak.contents.NumpyArray( - array.backend.nplike.asarray(result, dtype=array.dtype) + result.view(array.dtype), backend=array.backend ) -class Max(Reducer): +class Max(KernelReducer): name: Final = "max" preferred_dtype: Final = np.float64 needs_position: Final = False @@ -655,7 +734,7 @@ def __init__(self, initial): def initial(self): return self._initial - def identity_for(self, dtype: DTypeLike | None): + def _identity_for(self, dtype: DTypeLike | None): dtype = np.dtype(dtype) assert ( @@ -678,15 +757,19 @@ def identity_for(self, dtype: DTypeLike | None): return self._initial - def apply(self, array, parents, outlength): + def apply( + self, + array: ak.contents.NumpyArray, + parents: ak.index.Index, + starts: ak.index.Index, + shifts: ak.index.Index | None, + outlength: ShapeItem, + ) -> ak.contents.NumpyArray: assert isinstance(array, ak.contents.NumpyArray) - dtype = self.maybe_other_type(array.dtype) - result = array.backend.nplike.empty( - self.maybe_double_length(array.dtype.type, outlength), dtype=dtype - ) if array.dtype == np.bool_: + result = array.backend.nplike.empty(outlength, dtype=np.bool_) assert parents.nplike is array.backend.index_nplike - array._handle_error( + array.backend.maybe_kernel_error( array.backend[ "awkward_reduce_sum_bool", result.dtype.type, @@ -700,47 +783,48 @@ def apply(self, array, parents, outlength): outlength, ) ) - elif array.dtype.type in (np.complex128, np.complex64): - assert parents.nplike is array.backend.index_nplike - array._handle_error( - array.backend[ - "awkward_reduce_max_complex", - result.dtype.type, - dtype, - parents.dtype.type, - ]( - result, - array.data, - parents.data, - parents.length, - outlength, - self.identity_for(dtype), - ) - ) + return ak.contents.NumpyArray(result, backend=array.backend) else: - assert parents.nplike is array.backend.index_nplike - array._handle_error( - array.backend[ - "awkward_reduce_max", - result.dtype.type, - dtype, - parents.dtype.type, - ]( - result, - array.data, - parents.data, - parents.length, - outlength, - self.identity_for(dtype), - ) + # View array data in kernel-supported dtype + kernel_array_data = array.data.view(self._dtype_for_kernel(array.dtype)) + result = array.backend.nplike.empty( + self._length_for_kernel(array.dtype.type, outlength), + dtype=kernel_array_data.dtype, ) - if array.dtype.type in (np.complex128, np.complex64): - return ak.contents.NumpyArray( - array.backend.nplike.asarray( - result.view(array.dtype), dtype=array.dtype + if array.dtype.type in (np.complex128, np.complex64): + assert parents.nplike is array.backend.index_nplike + array.backend.maybe_kernel_error( + array.backend[ + "awkward_reduce_max_complex", + result.dtype.type, + kernel_array_data.dtype.type, + parents.dtype.type, + ]( + result, + kernel_array_data, + parents.data, + parents.length, + outlength, + self._identity_for(result.dtype), + ) + ) + else: + assert parents.nplike is array.backend.index_nplike + array.backend.maybe_kernel_error( + array.backend[ + "awkward_reduce_max", + result.dtype.type, + kernel_array_data.dtype.type, + parents.dtype.type, + ]( + result, + kernel_array_data, + parents.data, + parents.length, + outlength, + self._identity_for(result.dtype), + ) ) - ) - else: return ak.contents.NumpyArray( - array.backend.nplike.asarray(result, dtype=array.dtype) + result.view(array.dtype), backend=array.backend ) diff --git a/src/awkward/_regularize.py b/src/awkward/_regularize.py index 0b7f09f2dc..a1a472859a 100644 --- a/src/awkward/_regularize.py +++ b/src/awkward/_regularize.py @@ -50,30 +50,6 @@ def is_non_string_like_sequence(obj) -> bool: return not isinstance(obj, (str, bytes)) and isinstance(obj, Sequence) -def regularize_path(path): - """ - Converts pathlib Paths into plain string paths (for all versions of Python). - """ - is_path = False - - if isinstance(path, getattr(os, "PathLike", ())): - is_path = True - path = os.fspath(path) - - elif hasattr(path, "__fspath__"): - is_path = True - path = path.__fspath__() - - elif path.__class__.__module__ == "pathlib": - import pathlib - - if isinstance(path, pathlib.Path): - is_path = True - path = str(path) - - return is_path, path - - def regularize_axis(axis: SupportsInt | None) -> AxisMaybeNone: if axis is None: return None diff --git a/src/awkward/_util.py b/src/awkward/_util.py index 16f35f385e..847ec53089 100644 --- a/src/awkward/_util.py +++ b/src/awkward/_util.py @@ -1,19 +1,18 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE from __future__ import annotations +import base64 import os +import struct import sys from collections.abc import Collection import packaging.version -from awkward._nplikes.numpylike import NumpyMetadata from awkward._typing import TypeVar -np = NumpyMetadata.instance() - win = os.name == "nt" -bits32 = np.iinfo(np.intp).bits == 32 +bits32 = struct.calcsize("P") * 8 == 32 # matches include/awkward/common.h kMaxInt8 = 127 # 2**7 - 1 @@ -68,9 +67,6 @@ def native_to_byteorder(array, byteorder: str): def identifier_hash(str): - import base64 - import struct - return ( base64.encodebytes(struct.pack("q", hash(str))) .rstrip(b"=\n") @@ -80,18 +76,21 @@ def identifier_hash(str): ) -# FIXME: introduce sentinel type for this -class _Unset: - def __repr__(self): - return f"{__name__}.unset" +class Sentinel: + """A class for implementing sentinel types""" + def __init__(self, name, module=None): + self._name = name + self._module = module -unset = _Unset() + def __repr__(self): + if self._module is not None: + return f"{self._module}.{self._name}" + else: + return f"{self._name}" -# Sentinel object for catching pass-through values -class Unspecified: - pass +UNSET = Sentinel("UNSET", __name__) T = TypeVar("T") diff --git a/src/awkward/behaviors/string.py b/src/awkward/behaviors/string.py index 89211a3da2..2360ba8545 100644 --- a/src/awkward/behaviors/string.py +++ b/src/awkward/behaviors/string.py @@ -147,20 +147,6 @@ def _string_notequal(one, two): return ~_string_equal(one, two) -def _string_broadcast(layout, offsets): - index_nplike = layout.backend.index_nplike - offsets = index_nplike.asarray(offsets) - counts = offsets[1:] - offsets[:-1] - if ak._util.win or ak._util.bits32: - counts = index_nplike.astype(counts, dtype=np.int32) - parents = index_nplike.repeat( - index_nplike.arange(counts.size, dtype=counts.dtype), counts - ) - return ak.contents.IndexedArray( - ak.index.Index64(parents, nplike=index_nplike), layout - ).project() - - def _string_numba_typer(viewtype): import numba @@ -267,9 +253,6 @@ def register(behavior): behavior[ufuncs.not_equal, "bytestring", "bytestring"] = _string_notequal behavior[ufuncs.not_equal, "string", "string"] = _string_notequal - behavior["__broadcast__", "bytestring"] = _string_broadcast - behavior["__broadcast__", "string"] = _string_broadcast - behavior["__numba_typer__", "bytestring"] = _string_numba_typer behavior["__numba_lower__", "bytestring"] = _string_numba_lower behavior["__numba_typer__", "string"] = _string_numba_typer diff --git a/src/awkward/contents/bitmaskedarray.py b/src/awkward/contents/bitmaskedarray.py index f286b315ba..39e8e34439 100644 --- a/src/awkward/contents/bitmaskedarray.py +++ b/src/awkward/contents/bitmaskedarray.py @@ -4,27 +4,30 @@ import copy import json import math +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata -from awkward._nplikes.shape import unknown_length +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._nplikes.typetracer import MaybeNone, TypeTracer from awkward._parameters import ( type_parameters_equal, ) from awkward._regularize import is_integer, is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.bytemaskedarray import ByteMaskedArray from awkward.contents.content import Content from awkward.forms.bitmaskedform import BitMaskedForm +from awkward.forms.form import Form from awkward.index import Index if TYPE_CHECKING: from awkward._slicing import SliceItem + from awkward.contents import IndexedOptionArray np = NumpyMetadata.instance() numpy = Numpy.instance() @@ -190,7 +193,7 @@ def mask(self): return self._mask @property - def content(self): + def content(self) -> Content: return self._content @property @@ -205,21 +208,21 @@ def lsb_order(self): def copy( self, - mask=unset, - content=unset, - valid_when=unset, - length=unset, - lsb_order=unset, + mask=UNSET, + content=UNSET, + valid_when=UNSET, + length=UNSET, + lsb_order=UNSET, *, - parameters=unset, + parameters=UNSET, ): return BitMaskedArray( - self._mask if mask is unset else mask, - self._content if content is unset else content, - self._valid_when if valid_when is unset else valid_when, - self._length if length is unset else length, - self._lsb_order if lsb_order is unset else lsb_order, - parameters=self._parameters if parameters is unset else parameters, + self._mask if mask is UNSET else mask, + self._content if content is UNSET else content, + self._valid_when if valid_when is UNSET else valid_when, + self._length if length is UNSET else length, + self._lsb_order if lsb_order is UNSET else lsb_order, + parameters=self._parameters if parameters is UNSET else parameters, ) def __copy__(self): @@ -246,7 +249,7 @@ def simplified( if content.is_union or content.is_indexed or content.is_option: backend = content.backend index = ak.index.Index64.empty(mask.length * 8, backend.index_nplike) - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_BitMaskedArray_to_IndexedOptionArray", index.dtype.type, @@ -275,7 +278,7 @@ def simplified( parameters=parameters, ) - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> BitMaskedForm: form_key = getkey(self) return self.form_cls( self._mask.form, @@ -286,7 +289,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) key = getkey(self, form, "mask") container[key] = ak._util.native_to_byteorder( @@ -305,20 +315,18 @@ def _to_typetracer(self, forget_length: bool) -> Self: parameters=self._parameters, ) - def _touch_data(self, recursive): - if not self._backend.index_nplike.known_data: - self._mask.data.touch_data() + def _touch_data(self, recursive: bool): + self._mask._touch_data() if recursive: self._content._touch_data(recursive) - def _touch_shape(self, recursive): - if not self._backend.index_nplike.known_data: - self._mask.data.touch_shape() + def _touch_shape(self, recursive: bool): + self._mask._touch_shape() if recursive: self._content._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._length def __repr__(self): @@ -340,7 +348,7 @@ def _repr(self, indent, pre, post): out.append(post) return "".join(out) - def to_IndexedOptionArray64(self): + def to_IndexedOptionArray64(self) -> IndexedOptionArray: index = ak.index.Index64.empty( self._mask.length * 8, self._backend.index_nplike ) @@ -348,7 +356,7 @@ def to_IndexedOptionArray64(self): index.nplike is self._backend.nplike and self._mask.nplike is self._backend.nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_BitMaskedArray_to_IndexedOptionArray", index.dtype.type, @@ -373,7 +381,7 @@ def to_ByteMaskedArray(self): bytemask.nplike is self._backend.nplike and self._mask.nplike is self._backend.nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_BitMaskedArray_to_ByteMaskedArray", bytemask.dtype.type, @@ -439,7 +447,7 @@ def mask_as_bool(self, valid_when=None): bytemask.nplike is self._backend.nplike and self._mask.nplike is self._backend.nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_BitMaskedArray_to_ByteMaskedArray", bytemask.dtype.type, @@ -506,7 +514,9 @@ def _carry(self, carry: Index, allow_lazy: bool) -> Content: assert isinstance(carry, ak.index.Index) return self.to_ByteMaskedArray()._carry(carry, allow_lazy) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: return self.to_ByteMaskedArray()._getitem_next_jagged( slicestarts, slicestops, slicecontent, tail ) @@ -546,10 +556,10 @@ def _getitem_next( def project(self, mask=None): return self.to_ByteMaskedArray().project(mask) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: return self.to_ByteMaskedArray._offsets_and_flattened(axis, depth) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -564,7 +574,7 @@ def _mergeable_next(self, other, mergebool): def _reverse_merge(self, other): return self.to_IndexedOptionArray64()._reverse_merge(other) - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -677,7 +687,7 @@ def _remove_structure(self, backend, options): else: return [self] - def _drop_none(self): + def _drop_none(self) -> Content: return self.to_ByteMaskedArray()._drop_none() def _recursively_apply( diff --git a/src/awkward/contents/bytemaskedarray.py b/src/awkward/contents/bytemaskedarray.py index 4bd8bc9ceb..ab1d5d1e0f 100644 --- a/src/awkward/contents/bytemaskedarray.py +++ b/src/awkward/contents/bytemaskedarray.py @@ -4,13 +4,15 @@ import copy import json import math +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend +from awkward._errors import AxisError from awkward._layout import maybe_posaxis from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata -from awkward._nplikes.shape import unknown_length +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._nplikes.typetracer import MaybeNone, TypeTracer from awkward._parameters import ( parameters_intersect, @@ -18,14 +20,17 @@ ) from awkward._regularize import is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content from awkward.forms.bytemaskedform import ByteMaskedForm +from awkward.forms.form import Form from awkward.index import Index if TYPE_CHECKING: from awkward._slicing import SliceItem + from awkward.contents import IndexedOptionArray + np = NumpyMetadata.instance() numpy = Numpy.instance() @@ -137,7 +142,7 @@ def mask(self): return self._mask @property - def content(self): + def content(self) -> Content: return self._content @property @@ -146,12 +151,12 @@ def valid_when(self): form_cls: Final = ByteMaskedForm - def copy(self, mask=unset, content=unset, valid_when=unset, *, parameters=unset): + def copy(self, mask=UNSET, content=UNSET, valid_when=UNSET, *, parameters=UNSET): return ByteMaskedArray( - self._mask if mask is unset else mask, - self._content if content is unset else content, - self._valid_when if valid_when is unset else valid_when, - parameters=self._parameters if parameters is unset else parameters, + self._mask if mask is UNSET else mask, + self._content if content is UNSET else content, + self._valid_when if valid_when is UNSET else valid_when, + parameters=self._parameters if parameters is UNSET else parameters, ) def __copy__(self): @@ -176,7 +181,7 @@ def simplified( if content.is_union or content.is_indexed or content.is_option: backend = content.backend index = ak.index.Index64.empty(mask.length, nplike=backend.index_nplike) - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_ByteMaskedArray_toIndexedOptionArray", index.dtype.type, @@ -197,7 +202,7 @@ def simplified( else: return cls(mask, content, valid_when, parameters=parameters) - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> ByteMaskedForm: form_key = getkey(self) return self.form_cls( self._mask.form, @@ -207,7 +212,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) key = getkey(self, form, "mask") container[key] = ak._util.native_to_byteorder( @@ -225,20 +237,18 @@ def _to_typetracer(self, forget_length: bool) -> Self: parameters=self._parameters, ) - def _touch_data(self, recursive): - if not self._backend.index_nplike.known_data: - self._mask.data.touch_data() + def _touch_data(self, recursive: bool): + self._mask._touch_data() if recursive: self._content._touch_data(recursive) - def _touch_shape(self, recursive): - if not self._backend.index_nplike.known_data: - self._mask.data.touch_shape() + def _touch_shape(self, recursive: bool): + self._mask._touch_shape() if recursive: self._content._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._mask.length def _forget_length(self): @@ -266,7 +276,7 @@ def _repr(self, indent, pre, post): out.append(post) return "".join(out) - def to_IndexedOptionArray64(self): + def to_IndexedOptionArray64(self) -> IndexedOptionArray: index = ak.index.Index64.empty( self._mask.length, nplike=self._backend.index_nplike ) @@ -274,7 +284,7 @@ def to_IndexedOptionArray64(self): index.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_toIndexedOptionArray", index.dtype.type, @@ -422,7 +432,7 @@ def _nextcarry_outindex(self) -> tuple[int, ak.index.Index64, ak.index.Index64]: _numnull.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_numnull", _numnull.dtype.type, @@ -447,7 +457,7 @@ def _nextcarry_outindex(self) -> tuple[int, ak.index.Index64, ak.index.Index64]: and outindex.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_getitem_nextcarry_outindex", nextcarry.dtype.type, @@ -497,7 +507,7 @@ def _getitem_next_jagged_generic(self, slicestarts, slicestops, slicecontent, ta and reducedstarts.nplike is self._backend.nplike and reducedstops.nplike is self._backend.nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_MaskedArray_getitem_next_jagged_project", outindex.dtype.type, @@ -523,7 +533,9 @@ def _getitem_next_jagged_generic(self, slicestarts, slicestops, slicecontent, ta outindex, out, parameters=self._parameters ) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: return self._getitem_next_jagged_generic( slicestarts, slicestops, slicecontent, tail ) @@ -567,7 +579,7 @@ def _getitem_next( def project(self, mask=None): mask_length = self._mask.length - numnull = ak.index.Index64.zeros(1, nplike=self._backend.index_nplike) + _numnull = ak.index.Index64.zeros(1, nplike=self._backend.index_nplike) if mask is not None: if self._backend.nplike.known_data and mask_length != mask.length: @@ -585,7 +597,7 @@ def project(self, mask=None): and mask.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_overlay_mask", nextmask.dtype.type, @@ -607,29 +619,30 @@ def project(self, mask=None): else: assert ( - numnull.nplike is self._backend.index_nplike + _numnull.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_numnull", - numnull.dtype.type, + _numnull.dtype.type, self._mask.dtype.type, ]( - numnull.data, + _numnull.data, self._mask.data, mask_length, self._valid_when, ) ) + numnull = self._backend.index_nplike.index_as_shape_item(_numnull[0]) nextcarry = ak.index.Index64.empty( - mask_length - numnull[0], nplike=self._backend.index_nplike + mask_length - numnull, nplike=self._backend.index_nplike ) assert ( nextcarry.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_getitem_nextcarry", nextcarry.dtype.type, @@ -644,10 +657,10 @@ def project(self, mask=None): return self._content._carry(nextcarry, False) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 == depth: - raise np.AxisError("axis=0 not allowed for flatten") + raise AxisError("axis=0 not allowed for flatten") else: numnull, nextcarry, outindex = self._nextcarry_outindex() @@ -675,7 +688,7 @@ def _offsets_and_flattened(self, axis, depth): and outindex.nplike is self._backend.index_nplike and offsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_flatten_none2empty", outoffsets.dtype.type, @@ -691,7 +704,7 @@ def _offsets_and_flattened(self, axis, depth): ) return (outoffsets, flattened) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -706,7 +719,7 @@ def _mergeable_next(self, other, mergebool): def _reverse_merge(self, other): return self.to_IndexedOptionArray64()._reverse_merge(other) - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -824,7 +837,7 @@ def _reduce_next( _numnull.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_numnull", _numnull.dtype.type, @@ -855,7 +868,7 @@ def _reduce_next( and self._mask.nplike is self._backend.index_nplike and parents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_reduce_next_64", nextcarry.dtype.type, @@ -885,7 +898,7 @@ def _reduce_next( nextshifts.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_reduce_next_nonlocal_nextshifts_64", nextshifts.dtype.type, @@ -902,7 +915,7 @@ def _reduce_next( nextshifts.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ByteMaskedArray_reduce_next_nonlocal_nextshifts_fromshifts_64", nextshifts.dtype.type, @@ -936,10 +949,12 @@ def _reduce_next( if not branch and negaxis == depth: return out else: - if out.is_list: - out_content = out.content[out.starts[0] :] - elif out.is_regular: + if isinstance(out, ak.contents.RegularArray): out_content = out.content + elif isinstance(out, ak.contents.ListOffsetArray): + # The `outindex` that will index into `out_content` is 0-based, so we should ensure that we normalise + # the list content to start at the first offset. + out_content = out.content[out.offsets[0] :] else: raise ValueError( "reduce_next with unbranching depth > negaxis is only " @@ -951,7 +966,7 @@ def _reduce_next( starts.length + 1, nplike=self._backend.index_nplike ) assert outoffsets.nplike is self._backend.nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_reduce_next_fix_offsets_64", outoffsets.dtype.type, @@ -991,7 +1006,7 @@ def _pad_none(self, target, axis, depth, clip): index.nplike is self._backend.index_nplike and self._mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedOptionArray_rpad_and_clip_mask_axis1", index.dtype.type, @@ -1035,7 +1050,7 @@ def _remove_structure(self, backend, options): else: return [self] - def _drop_none(self): + def _drop_none(self) -> Content: return self.project() def _recursively_apply( diff --git a/src/awkward/contents/content.py b/src/awkward/contents/content.py index fd9df57a3d..2dc6b589ef 100644 --- a/src/awkward/contents/content.py +++ b/src/awkward/contents/content.py @@ -3,7 +3,7 @@ import copy import math -from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sized +from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sequence, Sized from numbers import Complex, Real import awkward as ak @@ -13,8 +13,8 @@ register_backend_lookup_factory, regularize_backend, ) -from awkward._backends.numpy import NumpyBackend from awkward._behavior import get_array_class, get_record_class +from awkward._kernels import KernelError from awkward._layout import wrap_layout from awkward._nplikes import to_nplike from awkward._nplikes.dispatch import nplike_of @@ -38,13 +38,16 @@ TypeAlias, TypedDict, ) -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form from awkward.index import Index, Index64 if TYPE_CHECKING: from awkward._nplikes.numpy import NumpyLike from awkward._slicing import SliceItem + from awkward.contents.indexedoptionarray import IndexedOptionArray + from awkward.contents.numpyarray import NumpyArray + from awkward.contents.regulararray import RegularArray np = NumpyMetadata.instance() @@ -63,6 +66,9 @@ ], Content | None, ]""" +JSONValueType: TypeAlias = """ +float | int | str | list[JSONValueType] | dict[str, JSONValueType] +""" class RecursivelyApplyOptionsType(TypedDict): @@ -137,7 +143,7 @@ def _init(self, parameters: dict[str, Any] | None, backend: Backend): self._backend = backend @property - def parameters(self) -> dict[str, Any]: + def parameters(self) -> dict[str, JSONValueType]: """ Free-form parameters associated with every array node as a dict from parameter name to its JSON-like value. Some parameters are special and are used to assign @@ -152,7 +158,7 @@ def parameters(self) -> dict[str, Any]: self._parameters = {} return self._parameters - def parameter(self, key: str): + def parameter(self, key: str) -> JSONValueType | None: """ Returns a parameter's value or None. @@ -171,7 +177,9 @@ def backend(self) -> Backend: def form(self) -> Form: return self.form_with_key(None) - def form_with_key(self, form_key="node{id}", id_start=0): + def form_with_key( + self, form_key: str | None | Callable = "node{id}", id_start: int = 0 + ) -> Form: hold_id = [id_start] if form_key is None: @@ -204,7 +212,7 @@ def getkey(layout): def _form_with_key( self, - getkey: Callable[[Content], Form], + getkey: Callable[[Content], str | None], ) -> Form: raise NotImplementedError @@ -218,10 +226,10 @@ def to_typetracer(self, forget_length: bool = False) -> Self: def _to_typetracer(self, forget_length: bool) -> Self: raise NotImplementedError - def _touch_data(self, recursive): + def _touch_data(self, recursive: bool): raise NotImplementedError - def _touch_shape(self, recursive): + def _touch_shape(self, recursive: bool): raise NotImplementedError @property @@ -255,53 +263,12 @@ def _repr_extra(self, indent: str) -> list[str]: def maybe_to_NumpyArray(self): return None - def _handle_error(self, error, slicer=None): - if error is not None and error.str is not None: - if error.filename is None: - filename = "" - else: - filename = " (in compiled code: " + error.filename.decode( - errors="surrogateescape" - ).lstrip("\n").lstrip("(") - - message = error.str.decode(errors="surrogateescape") - - if error.pass_through: - raise ValueError(message + filename) - - else: - if error.attempt != ak._util.kSliceNone: - message += f" while attempting to get index {error.attempt}" - - message += filename - - if slicer is None: - raise ValueError(message) - else: - raise ak._errors.index_error(self, slicer, message) - - @staticmethod - def _selfless_handle_error(error): - if error.str is not None: - if error.filename is None: - filename = "" - else: - filename = " (in compiled code: " + error.filename.decode( - errors="surrogateescape" - ).lstrip("\n").lstrip("(") - - message = error.str.decode(errors="surrogateescape") - - if error.pass_through: - raise ValueError(message + filename) - - else: - if error.attempt != ak._util.kSliceNone: - message += f" while attempting to get index {error.attempt}" - - message += filename - - raise ValueError(message) + def _maybe_index_error(self, error: KernelError | None, slicer): + if error is None or error.str is None: + return + else: + message = self._backend.format_kernel_error(error) + raise ak._errors.index_error(self, slicer, message) def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): raise TypeError( @@ -334,7 +301,9 @@ def _getitem_next_field( nexthead, nexttail = ak._slicing.head_tail(tail) return self._getitem_field(head)._getitem_next(nexthead, nexttail, advanced) - def _getitem_next_fields(self, head, tail, advanced: Index | None) -> Content: + def _getitem_next_fields( + self, head: SliceItem, tail: tuple[SliceItem, ...], advanced: Index | None + ) -> Content: only_fields, not_fields = [], [] for x in tail: if isinstance(x, (str, list)): @@ -346,13 +315,17 @@ def _getitem_next_fields(self, head, tail, advanced: Index | None) -> Content: nexthead, nexttail, advanced ) - def _getitem_next_newaxis(self, tail, advanced: Index | None): + def _getitem_next_newaxis( + self, tail: tuple[SliceItem, ...], advanced: Index | None + ) -> RegularArray: nexthead, nexttail = ak._slicing.head_tail(tail) return ak.contents.RegularArray( self._getitem_next(nexthead, nexttail, advanced), 1, 0, parameters=None ) - def _getitem_next_ellipsis(self, tail, advanced: Index | None): + def _getitem_next_ellipsis( + self, tail: tuple[SliceItem, ...], advanced: Index | None + ) -> Content: mindepth, maxdepth = self.minmax_depth dimlength = sum( @@ -376,12 +349,12 @@ def _getitem_next_ellipsis(self, tail, advanced: Index | None): def _getitem_next_regular_missing( self, - head: ak.contents.IndexedOptionArray, - tail, + head: IndexedOptionArray, + tail: tuple[SliceItem, ...], advanced: Index | None, raw: Content, length: int, - ): + ) -> RegularArray: # if this is in a tuple-slice and really should be 0, it will be trimmed later length = 1 if length is not unknown_length and length == 0 else length index = head.index @@ -396,7 +369,7 @@ def _getitem_next_regular_missing( outindex.nplike is self._backend.index_nplike and index.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_missing_repeat", outindex.dtype.type, index.dtype.type ]( @@ -418,7 +391,7 @@ def _getitem_next_regular_missing( def _getitem_next_missing_jagged( self, head: Content, tail, advanced: Index | None, that: Content - ): + ) -> RegularArray: head = head.to_backend(self._backend) jagged = head.content.to_ListOffsetArray64() index = head._index @@ -443,7 +416,7 @@ def _getitem_next_missing_jagged( and starts.nplike is self._backend.index_nplike and stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_Content_getitem_next_missing_jagged_getmaskstartstop", index.dtype.type, @@ -472,10 +445,10 @@ def _getitem_next_missing_jagged( def _getitem_next_missing( self, - head: ak.contents.IndexedOptionArray, - tail, + head: IndexedOptionArray, + tail: tuple[SliceItem, ...], advanced: Index | None, - ): + ) -> Content: assert isinstance(head, ak.contents.IndexedOptionArray) if advanced is not None: @@ -731,12 +704,21 @@ def _getitem_next( ) -> Content: raise NotImplementedError + def _getitem_next_jagged( + self, + slicestarts: Index, + slicestops: Index, + slicecontent: Content, + tail: tuple[SliceItem, ...], + ) -> Content: + raise NotImplementedError + def _carry(self, carry: Index, allow_lazy: bool) -> Content: raise NotImplementedError - def _local_index_axis0(self) -> ak.contents.NumpyArray: + def _local_index_axis0(self) -> NumpyArray: localindex = Index64.empty(self.length, self._backend.index_nplike) - self._handle_error( + self._backend.maybe_kernel_error( self._backend["awkward_localindex", np.int64]( localindex.data, localindex.length, @@ -749,10 +731,7 @@ def _local_index_axis0(self) -> ak.contents.NumpyArray: def _mergeable_next(self, other: Content, mergebool: bool) -> bool: raise NotImplementedError - def _mergemany( - self, - others: list[Content], - ) -> Content: + def _mergemany(self, others: Sequence[Content]) -> Content: raise NotImplementedError def _merging_strategy( @@ -886,7 +865,7 @@ def _combinations_axis0( toindex.nplike is self._backend.index_nplike and fromindex.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_RegularArray_combinations_64", np.int64, @@ -903,13 +882,13 @@ def _combinations_axis0( ) ) contents = [] - length = ak._util.unset + length = ak._util.UNSET for ptr in tocarry: contents.append( ak.contents.IndexedArray.simplified(ptr, self, parameters=None) ) length = contents[-1].length - assert not (length is ak._util.unset and self._backend.nplike.known_data) + assert not (length is ak._util.UNSET and self._backend.nplike.known_data) return ak.contents.RecordArray( contents, recordlookup, length, parameters=parameters, backend=self._backend ) @@ -1024,7 +1003,7 @@ def _pad_none_axis0(self, target: int, clip: bool) -> Content: index = Index64.empty(target, self._backend.index_nplike) assert index.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_index_rpad_and_clip_axis0", index.dtype.type, @@ -1079,14 +1058,6 @@ def _to_arrow( ): raise NotImplementedError - def to_numpy(self, allow_missing: bool = True): - ak._errors.deprecate( - "`Content.to_numpy` is deprecated. Please replace calls to " - "`Content.to_numpy(...)` with `Content.to_backend_array(..., backend='cpu')`.", - "2.2.0", - ) - return self.to_backend(NumpyBackend.instance())._to_backend_array(allow_missing) - def to_backend_array( self, allow_missing: bool = True, *, backend: Backend | str | None = None ): @@ -1321,7 +1292,7 @@ def _numbers_to_type(self, name: str, including_unknown: bool) -> Content: def _fill_none(self, value: Content) -> Content: raise NotImplementedError - def copy(self, *, parameters: JSONMapping | None = unset) -> Self: + def copy(self, *, parameters: JSONMapping | None = UNSET) -> Self: raise NotImplementedError diff --git a/src/awkward/contents/emptyarray.py b/src/awkward/contents/emptyarray.py index e5c6072f95..94d4a86525 100644 --- a/src/awkward/contents/emptyarray.py +++ b/src/awkward/contents/emptyarray.py @@ -2,21 +2,24 @@ from __future__ import annotations import copy +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend from awkward._backends.numpy import NumpyBackend from awkward._backends.typetracer import TypeTracerBackend -from awkward._errors import deprecate +from awkward._errors import AxisError, deprecate from awkward._layout import maybe_posaxis from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem from awkward._regularize import is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content from awkward.forms.emptyform import EmptyForm +from awkward.forms.form import Form from awkward.index import Index if TYPE_CHECKING: @@ -79,16 +82,16 @@ def __init__(self, *, parameters=None, backend=None): def copy( self, *, - parameters=unset, - backend=unset, + parameters=UNSET, + backend=UNSET, ): - if not (parameters is unset or parameters is None or len(parameters) == 0): + if not (parameters is UNSET or parameters is None or len(parameters) == 0): deprecate( f"{type(self).__name__} cannot contain parameters", version="2.2.0" ) return EmptyArray( - parameters=self._parameters if parameters is unset else parameters, - backend=self._backend if backend is unset else backend, + parameters=self._parameters if parameters is UNSET else parameters, + backend=self._backend if backend is UNSET else backend, ) def __copy__(self): @@ -103,10 +106,17 @@ def simplified(cls, *, parameters=None, backend=None): deprecate(f"{cls.__name__} cannot contain parameters", version="2.2.0") return cls(parameters=parameters, backend=backend) - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> EmptyForm: return self.form_cls(parameters=self._parameters, form_key=getkey(self)) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) def _to_typetracer(self, forget_length: bool) -> Self: @@ -115,14 +125,14 @@ def _to_typetracer(self, forget_length: bool) -> Self: backend=TypeTracerBackend.instance(), ) - def _touch_data(self, recursive): + def _touch_data(self, recursive: bool): pass - def _touch_shape(self, recursive): + def _touch_shape(self, recursive: bool): pass @property - def length(self): + def length(self) -> ShapeItem: return 0 def __repr__(self): @@ -182,7 +192,9 @@ def _carry(self, carry: Index, allow_lazy: bool) -> EmptyArray: else: raise ak._errors.index_error(self, carry.data, "array is empty") - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: raise ak._errors.index_error( self, ak.contents.ListArray( @@ -233,10 +245,10 @@ def _getitem_next( else: raise AssertionError(repr(head)) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 == depth: - raise np.AxisError(self, "axis=0 not allowed for flatten") + raise AxisError(self, "axis=0 not allowed for flatten") else: offsets = ak.index.Index64.zeros(1, nplike=self._backend.index_nplike) return ( @@ -244,10 +256,10 @@ def _offsets_and_flattened(self, axis, depth): EmptyArray(parameters=self._parameters, backend=self._backend), ) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: return True - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self elif len(others) == 1: @@ -267,7 +279,7 @@ def _local_index(self, axis, depth): backend=self._backend, ) else: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") def _numbers_to_type(self, name, including_unknown): if including_unknown: @@ -331,7 +343,7 @@ def _nbytes_part(self): def _pad_none(self, target, axis, depth, clip): posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 != depth: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") else: return self._pad_none_axis0(target, True) diff --git a/src/awkward/contents/indexedarray.py b/src/awkward/contents/indexedarray.py index 5f5ba40262..97a634b823 100644 --- a/src/awkward/contents/indexedarray.py +++ b/src/awkward/contents/indexedarray.py @@ -2,12 +2,15 @@ from __future__ import annotations import copy +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend +from awkward._errors import AxisError from awkward._layout import maybe_posaxis from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem from awkward._nplikes.typetracer import TypeTracer from awkward._parameters import ( parameters_intersect, @@ -16,14 +19,16 @@ ) from awkward._regularize import is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content +from awkward.forms.form import Form from awkward.forms.indexedform import IndexedForm from awkward.index import Index if TYPE_CHECKING: from awkward._slicing import SliceItem + from awkward.contents.indexedoptionarray import IndexedOptionArray np = NumpyMetadata.instance() numpy = Numpy.instance() @@ -122,16 +127,16 @@ def index(self): return self._index @property - def content(self): + def content(self) -> Content: return self._content form_cls: Final = IndexedForm - def copy(self, index=unset, content=unset, *, parameters=unset): + def copy(self, index=UNSET, content=UNSET, *, parameters=UNSET): return IndexedArray( - self._index if index is unset else index, - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, + self._index if index is UNSET else index, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, ) def __copy__(self): @@ -161,7 +166,7 @@ def simplified(cls, index, content, *, parameters=None): inner = content.to_IndexedOptionArray64().index result = ak.index.Index64.empty(index.length, nplike=backend.index_nplike) - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_IndexedArray_simplify", result.dtype.type, @@ -191,7 +196,7 @@ def simplified(cls, index, content, *, parameters=None): else: return cls(index, content, parameters=parameters) - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> IndexedForm: form_key = getkey(self) return self.form_cls( self._index.form, @@ -200,7 +205,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) key = getkey(self, form, "index") container[key] = ak._util.native_to_byteorder( @@ -216,20 +228,18 @@ def _to_typetracer(self, forget_length: bool) -> Self: parameters=self._parameters, ) - def _touch_data(self, recursive): - if not self._backend.index_nplike.known_data: - self._index.data.touch_data() + def _touch_data(self, recursive: bool): + self._index._touch_data() if recursive: self._content._touch_data(recursive) - def _touch_shape(self, recursive): - if not self._backend.index_nplike.known_data: - self._index.data.touch_shape() + def _touch_shape(self, recursive: bool): + self._index._touch_shape() if recursive: self._content._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._index.length def __repr__(self): @@ -247,7 +257,7 @@ def _repr(self, indent, pre, post): out.append(post) return "".join(out) - def to_IndexedOptionArray64(self): + def to_IndexedOptionArray64(self) -> IndexedOptionArray: return ak.contents.IndexedOptionArray( self._index, self._content, parameters=self._parameters ) @@ -326,7 +336,7 @@ def _getitem_next_jagged_generic(self, slicestarts, slicestops, slicecontent, ta nextcarry.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_IndexedArray_getitem_nextcarry", nextcarry.dtype.type, @@ -343,7 +353,9 @@ def _getitem_next_jagged_generic(self, slicestarts, slicestops, slicecontent, ta next = self._content._carry(nextcarry, False) return next._getitem_next_jagged(slicestarts, slicestops, slicecontent, tail) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: return self._getitem_next_jagged_generic( slicestarts, slicestops, slicecontent, tail ) @@ -369,7 +381,7 @@ def _getitem_next( nextcarry.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_IndexedArray_getitem_nextcarry", nextcarry.dtype.type, @@ -420,7 +432,7 @@ def project(self, mask=None): and mask.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_overlay_mask", nextindex.dtype.type, @@ -444,7 +456,7 @@ def project(self, mask=None): nextcarry.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_getitem_nextcarry", nextcarry.dtype.type, @@ -465,15 +477,15 @@ def project(self, mask=None): ) ) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 == depth: - raise np.AxisError("axis=0 not allowed for flatten") + raise AxisError("axis=0 not allowed for flatten") else: return self.project()._offsets_and_flattened(axis, depth) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -530,7 +542,7 @@ def _reverse_merge(self, other): # Fill `index` with a range starting at zero, up to `theirlength` assert index.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend["awkward_IndexedArray_fill_count", index.dtype.type]( index.data, 0, @@ -541,7 +553,7 @@ def _reverse_merge(self, other): # Fill remaining indices assert index.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_fill", index.dtype.type, @@ -565,7 +577,7 @@ def _reverse_merge(self, other): index, content, parameters=parameters ) - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -608,7 +620,7 @@ def _mergemany(self, others): nextindex.nplike is self._backend.index_nplike and array_index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_fill", nextindex.dtype.type, @@ -626,7 +638,7 @@ def _mergemany(self, others): else: contents.append(array) assert nextindex.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_fill_count", nextindex.dtype.type, @@ -691,7 +703,7 @@ def _unique_index(self, index, sorted=True): next.nplike is self._backend.index_nplike and offsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sort", next.dtype.type, @@ -713,7 +725,7 @@ def _unique_index(self, index, sorted=True): next.nplike is self._backend.index_nplike and length.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend["awkward_unique", next.dtype.type, length.dtype.type]( next.data, self._index.length, @@ -727,7 +739,7 @@ def _unique_index(self, index, sorted=True): and next.nplike is self._backend.index_nplike and length.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_unique_copy", self._index.dtype.type, @@ -782,7 +794,7 @@ def _unique(self, negaxis, starts, parents, outlength): and self._index.nplike is self._backend.index_nplike and parents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_reduce_next_64", nextcarry.dtype.type, @@ -817,7 +829,7 @@ def _unique(self, negaxis, starts, parents, outlength): and parents.nplike is self._backend.index_nplike and nextparents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_local_preparenext", nextoutindex.dtype.type, @@ -860,7 +872,7 @@ def _unique(self, negaxis, starts, parents, outlength): outoffsets.nplike is self._backend.index_nplike and starts.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_reduce_next_fix_offsets_64", outoffsets.dtype.type, @@ -1124,3 +1136,18 @@ def _is_equal_to(self, other, index_dtype, numpyarray): return self.index.is_equal_to( other.index, index_dtype, numpyarray ) and self.content.is_equal_to(other.content, index_dtype, numpyarray) + + def _push_inside_record_or_project(self) -> Self | ak.contents.RecordArray: + if self.content.is_record: + return ak.contents.RecordArray( + contents=[ + ak.contents.IndexedArray.simplified(self._index, c) + for c in self.content.contents + ], + fields=self.content._fields, + length=self.length, + backend=self._backend, + parameters=parameters_union(self.content._parameters, self._parameters), + ) + else: + return self.project() diff --git a/src/awkward/contents/indexedoptionarray.py b/src/awkward/contents/indexedoptionarray.py index b441e56b92..18aa9a9680 100644 --- a/src/awkward/contents/indexedoptionarray.py +++ b/src/awkward/contents/indexedoptionarray.py @@ -2,13 +2,15 @@ from __future__ import annotations import copy +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend +from awkward._errors import AxisError from awkward._layout import maybe_posaxis from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata -from awkward._nplikes.shape import unknown_length +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._nplikes.typetracer import MaybeNone, TypeTracer from awkward._parameters import ( parameters_intersect, @@ -17,9 +19,10 @@ ) from awkward._regularize import is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content +from awkward.forms.form import Form from awkward.forms.indexedoptionform import IndexedOptionForm from awkward.index import Index @@ -120,16 +123,16 @@ def index(self): return self._index @property - def content(self): + def content(self) -> Content: return self._content form_cls: Final = IndexedOptionForm - def copy(self, index=unset, content=unset, *, parameters=unset): + def copy(self, index=UNSET, content=UNSET, *, parameters=UNSET): return IndexedOptionArray( - self._index if index is unset else index, - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, + self._index if index is UNSET else index, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, ) def __copy__(self): @@ -157,7 +160,7 @@ def simplified(cls, index, content, *, parameters=None): inner = content.to_IndexedOptionArray64().index result = ak.index.Index64.empty(index.length, nplike=backend.index_nplike) - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_IndexedArray_simplify", result.dtype.type, @@ -180,7 +183,9 @@ def simplified(cls, index, content, *, parameters=None): else: return cls(index, content, parameters=parameters) - def _form_with_key(self, getkey): + def _form_with_key( + self, getkey: Callable[[Content], str | None] + ) -> IndexedOptionForm: form_key = getkey(self) return self.form_cls( self._index.form, @@ -189,7 +194,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) key = getkey(self, form, "index") container[key] = ak._util.native_to_byteorder( @@ -205,20 +217,18 @@ def _to_typetracer(self, forget_length: bool) -> Self: parameters=self._parameters, ) - def _touch_data(self, recursive): - if not self._backend.index_nplike.known_data: - self._index.data.touch_data() + def _touch_data(self, recursive: bool): + self._index._touch_data() if recursive: self._content._touch_data(recursive) - def _touch_shape(self, recursive): - if not self._backend.index_nplike.known_data: - self._index.data.touch_shape() + def _touch_shape(self, recursive: bool): + self._index._touch_shape() if recursive: self._content._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._index.length def __repr__(self): @@ -236,7 +246,7 @@ def _repr(self, indent, pre, post): out.append(post) return "".join(out) - def to_IndexedOptionArray64(self): + def to_IndexedOptionArray64(self) -> IndexedOptionArray: if self._index.dtype == np.dtype(np.int64): return self else: @@ -340,7 +350,7 @@ def _nextcarry_outindex(self): _numnull = ak.index.Index64.empty(1, nplike=backend.index_nplike) assert _numnull.nplike is index_nplike and self._index.nplike is index_nplike - self._handle_error( + self._backend.maybe_kernel_error( backend[ "awkward_IndexedArray_numnull", _numnull.dtype.type, @@ -367,7 +377,7 @@ def _nextcarry_outindex(self): and outindex.nplike is index_nplike and self._index.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( backend[ "awkward_IndexedArray_getitem_nextcarry_outindex", nextcarry.dtype.type, @@ -416,7 +426,7 @@ def _getitem_next_jagged_generic(self, slicestarts, slicestops, slicecontent, ta and reducedstarts.nplike is self._backend.index_nplike and reducedstops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_MaskedArray_getitem_next_jagged_project", outindex.dtype.type, @@ -441,7 +451,9 @@ def _getitem_next_jagged_generic(self, slicestarts, slicestops, slicecontent, ta outindex, out, parameters=self._parameters ) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: return self._getitem_next_jagged_generic( slicestarts, slicestops, slicecontent, tail ) @@ -502,7 +514,7 @@ def project(self, mask=None): and mask.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_overlay_mask", nextindex.dtype.type, @@ -525,7 +537,7 @@ def project(self, mask=None): _numnull.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_numnull", _numnull.dtype.type, @@ -546,7 +558,7 @@ def project(self, mask=None): nextcarry.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_flatten_nextcarry", nextcarry.dtype.type, @@ -561,10 +573,10 @@ def project(self, mask=None): return self._content._carry(nextcarry, False) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 == depth: - raise np.AxisError("axis=0 not allowed for flatten") + raise AxisError("axis=0 not allowed for flatten") else: numnull, nextcarry, outindex = self._nextcarry_outindex() next = self._content._carry(nextcarry, False) @@ -591,7 +603,7 @@ def _offsets_and_flattened(self, axis, depth): and outindex.nplike is self._backend.index_nplike and offsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_flatten_none2empty", outoffsets.dtype.type, @@ -607,7 +619,7 @@ def _offsets_and_flattened(self, axis, depth): ) return (outoffsets, flattened) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -667,7 +679,7 @@ def _reverse_merge(self, other): content = other._mergemany([self._content]) assert index.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend["awkward_IndexedArray_fill_count", index.dtype.type]( index.data, 0, @@ -684,7 +696,7 @@ def _reverse_merge(self, other): index.nplike is self._backend.index_nplike and reinterpreted_index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_fill", index.dtype.type, @@ -708,7 +720,7 @@ def _reverse_merge(self, other): index, content, parameters=parameters ) - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -749,7 +761,7 @@ def _mergemany(self, others): nextindex.nplike is self._backend.index_nplike and array_index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_fill", nextindex.dtype.type, @@ -769,7 +781,7 @@ def _mergemany(self, others): else: contents.append(array) assert nextindex.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_fill_count", nextindex.dtype.type, @@ -813,7 +825,7 @@ def _fill_none(self, value: Content) -> Content: index.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_fillna", index.dtype.type, self._index.dtype.type ](index.data, self._index.data, tags.length) @@ -854,7 +866,7 @@ def _is_subrange_equal(self, starts, stops, length, sorted=True): and nextstops.nplike is self._backend.index_nplike and subranges_length.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_ranges_next_64", self._index.dtype.type, @@ -883,7 +895,7 @@ def _is_subrange_equal(self, starts, stops, length, sorted=True): and stops.nplike is self._backend.index_nplike and nextcarry.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_ranges_carry_next_64", self._index.dtype.type, @@ -949,7 +961,7 @@ def _unique(self, negaxis, starts, parents, outlength): and parents.nplike is self._backend.index_nplike and nextparents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_local_preparenext", nextoutindex.dtype.type, @@ -980,7 +992,7 @@ def _unique(self, negaxis, starts, parents, outlength): and _len_newnulls.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_numnull_parents", newnulls.dtype.type, @@ -1011,7 +1023,7 @@ def _unique(self, negaxis, starts, parents, outlength): and out._offsets.nplike is self._backend.index_nplike and newnulls.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_unique_next_index_and_offsets_64", newindex.dtype.type, @@ -1044,7 +1056,7 @@ def _unique(self, negaxis, starts, parents, outlength): self._backend.index_nplike, ) assert nextoutindex.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_numnull_unique_64", nextoutindex.dtype.type, @@ -1076,7 +1088,7 @@ def _rearrange_nextshifts(self, nextparents, shifts): nextshifts.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_reduce_next_nonlocal_nextshifts_64", nextshifts.dtype.type, @@ -1093,7 +1105,7 @@ def _rearrange_nextshifts(self, nextparents, shifts): and self._index.nplike is self._backend.index_nplike and shifts.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_reduce_next_nonlocal_nextshifts_fromshifts_64", nextshifts.dtype.type, @@ -1117,7 +1129,7 @@ def _rearrange_prepare_next(self, parents): _numnull = ak.index.Index64.empty(1, self._backend.index_nplike) assert _numnull.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_numnull", _numnull.dtype.type, @@ -1139,7 +1151,7 @@ def _rearrange_prepare_next(self, parents): and nextparents.nplike is self._backend.index_nplike and outindex.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_reduce_next_64", nextcarry.dtype.type, @@ -1188,7 +1200,7 @@ def _argsort_next( nulls_merged = False nulls_index = ak.index.Index64.empty(numnull, self._backend.index_nplike) assert nulls_index.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_index_of_nulls", nulls_index.dtype.type, @@ -1224,7 +1236,7 @@ def _argsort_next( and parents.nplike is self._backend.index_nplike and nextparents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_local_preparenext", nextoutindex.dtype.type, @@ -1248,7 +1260,7 @@ def _argsort_next( # we need to mapping the -1 values to their corresponding indices # in `out` assert nextoutindex.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend["awkward_Index_nones_as_index", nextoutindex.dtype.type]( nextoutindex.data, nextoutindex.length, @@ -1301,7 +1313,7 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): ) assert nextoutindex.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_local_preparenext", nextoutindex.dtype.type, @@ -1375,10 +1387,12 @@ def _reduce_next( if not branch and negaxis == depth: return out else: - if out.is_list: - out_content = out.content[out.starts[0] :] - elif out.is_regular: + if isinstance(out, ak.contents.RegularArray): out_content = out.content + elif isinstance(out, ak.contents.ListOffsetArray): + # The `outindex` that will index into `out_content` is 0-based, so we should ensure that we normalise + # the list content to start at the first offset. + out_content = out.content[out.offsets[0] :] else: raise AssertionError( "reduce_next with unbranching depth > negaxis is only " @@ -1413,7 +1427,7 @@ def _reduce_next( outoffsets.nplike is self._backend.index_nplike and starts.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedArray_reduce_next_fix_offsets_64", outoffsets.dtype.type, @@ -1482,7 +1496,7 @@ def _pad_none(self, target, axis, depth, clip): index.nplike is self._backend.index_nplike and mask.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_IndexedOptionArray_rpad_and_clip_mask_axis1", index.dtype.type, @@ -1585,7 +1599,7 @@ def _remove_structure(self, backend, options): else: return [self] - def _drop_none(self): + def _drop_none(self) -> Content: return self.project() def _recursively_apply( diff --git a/src/awkward/contents/listarray.py b/src/awkward/contents/listarray.py index 6aa0688919..595f463730 100644 --- a/src/awkward/contents/listarray.py +++ b/src/awkward/contents/listarray.py @@ -2,12 +2,13 @@ from __future__ import annotations import copy +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend from awkward._layout import maybe_posaxis -from awkward._nplikes.numpylike import IndexType, NumpyMetadata -from awkward._nplikes.shape import unknown_length +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._nplikes.typetracer import TypeTracer from awkward._parameters import ( parameters_intersect, @@ -15,10 +16,11 @@ ) from awkward._regularize import is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content from awkward.contents.listoffsetarray import ListOffsetArray +from awkward.forms.form import Form from awkward.forms.listform import ListForm from awkward.index import Index @@ -159,25 +161,25 @@ def __init__(self, starts, stops, content, *, parameters=None): self._init(parameters, content.backend) @property - def starts(self): + def starts(self) -> Index: return self._starts @property - def stops(self): + def stops(self) -> Index: return self._stops @property - def content(self): + def content(self) -> Content: return self._content form_cls: Final = ListForm - def copy(self, starts=unset, stops=unset, content=unset, *, parameters=unset): + def copy(self, starts=UNSET, stops=UNSET, content=UNSET, *, parameters=UNSET): return ListArray( - self._starts if starts is unset else starts, - self._stops if stops is unset else stops, - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, + self._starts if starts is UNSET else starts, + self._stops if stops is UNSET else stops, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, ) def __copy__(self): @@ -195,7 +197,7 @@ def __deepcopy__(self, memo): def simplified(cls, starts, stops, content, *, parameters=None): return cls(starts, stops, content, parameters=parameters) - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> ListForm: form_key = getkey(self) return self.form_cls( self._starts.form, @@ -205,7 +207,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) key1 = getkey(self, form, "starts") key2 = getkey(self, form, "stops") @@ -227,22 +236,20 @@ def _to_typetracer(self, forget_length: bool) -> Self: parameters=self._parameters, ) - def _touch_data(self, recursive): - if not self._backend.index_nplike.known_data: - self._starts.data.touch_data() - self._stops.data.touch_data() + def _touch_data(self, recursive: bool): + self._starts._touch_data() + self._stops._touch_data() if recursive: self._content._touch_data(recursive) - def _touch_shape(self, recursive): - if not self._backend.index_nplike.known_data: - self._starts.data.touch_shape() - self._stops.data.touch_shape() + def _touch_shape(self, recursive: bool): + self._starts._touch_shape() + self._stops._touch_shape() if recursive: self._content._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._starts.length def __repr__(self): @@ -261,24 +268,18 @@ def _repr(self, indent, pre, post): out.append(post) return "".join(out) - def to_ListOffsetArray64(self, start_at_zero=False): + def to_ListOffsetArray64(self, start_at_zero: bool = False) -> ListOffsetArray: + index_nplike = self._backend.index_nplike + starts = self._starts.data stops = self._stops.data - lenoffsets = None if (starts.shape[0] is None) else (starts.shape[0] + 1) - if not self._backend.nplike.known_data: - self._touch_data(recursive=False) - self._content._touch_data(recursive=False) - offsets = self._backend.index_nplike.empty(lenoffsets, dtype=starts.dtype) - return ListOffsetArray( - ak.index.Index(offsets, nplike=self._backend.index_nplike), - self._content, - parameters=self._parameters, - ) - - elif self._backend.index_nplike.array_equal(starts[1:], stops[:-1]): - offsets = self._backend.index_nplike.empty(lenoffsets, dtype=starts.dtype) - if offsets.shape[0] == 1: + lenoffsets = self._starts.length + 1 + if (not index_nplike.known_data) or index_nplike.array_equal( + starts[1:], stops[:-1] + ): + offsets = index_nplike.empty(lenoffsets, dtype=starts.dtype) + if lenoffsets is not unknown_length and lenoffsets == 1: offsets[0] = 0 else: offsets[:-1] = starts @@ -368,7 +369,7 @@ def _compact_offsets64(self, start_at_zero): and self._starts.nplike is self._backend.index_nplike and self._stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_compact_offsets", out.dtype.type, @@ -383,10 +384,65 @@ def _compact_offsets64(self, start_at_zero): ) return out - def _broadcast_tooffsets64(self, offsets): - return ListOffsetArray._broadcast_tooffsets64(self, offsets) + def _broadcast_tooffsets64(self, offsets: Index) -> ListOffsetArray: + self._touch_data(recursive=False) + offsets._touch_data() + + index_nplike = self._backend.index_nplike + assert offsets.nplike is index_nplike + if offsets.length is not unknown_length and offsets.length == 0: + raise AssertionError( + "broadcast_tooffsets64 can only be used with non-empty offsets" + ) + elif index_nplike.known_data and offsets[0] != 0: + raise AssertionError( + f"broadcast_tooffsets64 can only be used with offsets that start at 0, not {offsets[0]}" + ) + elif ( + offsets.length is not unknown_length + and self._starts.length is not unknown_length + and offsets.length - 1 != self._starts.length + ): + raise AssertionError( + "cannot broadcast RegularArray of length {} to length {}".format( + self._starts.length, offsets.length - 1 + ) + ) + + nextcarry = ak.index.Index64.empty( + self._backend.index_nplike.index_as_shape_item(offsets[-1]), + self._backend.index_nplike, + ) + assert ( + nextcarry.nplike is self._backend.index_nplike + and offsets.nplike is self._backend.index_nplike + and self._starts.nplike is self._backend.index_nplike + and self._stops.nplike is self._backend.index_nplike + ) + self._backend.maybe_kernel_error( + self._backend[ + "awkward_ListArray_broadcast_tooffsets", + nextcarry.dtype.type, + offsets.dtype.type, + self._starts.dtype.type, + self._stops.dtype.type, + ]( + nextcarry.data, + offsets.data, + offsets.length, + self._starts.data, + self._stops.data, + self._content.length, + ) + ) + + nextcontent = self._content._carry(nextcarry, True) + + return ListOffsetArray(offsets, nextcontent, parameters=self._parameters) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: slicestarts = slicestarts.to_nplike(self._backend.index_nplike) slicestops = slicestops.to_nplike(self._backend.index_nplike) if self._backend.nplike.known_data and slicestarts.length != self.length: @@ -412,7 +468,7 @@ def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): and self._starts.nplike is self._backend.index_nplike and self._stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_jagged_descend", outoffsets.dtype.type, @@ -453,7 +509,7 @@ def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): and slicestarts.nplike is self._backend.index_nplike and slicestops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_jagged_carrylen", _carrylen.dtype.type, @@ -485,7 +541,7 @@ def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): and self._starts.nplike is self._backend.index_nplike and self._stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_jagged_apply", outoffsets.dtype.type, @@ -536,7 +592,7 @@ def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): and slicestops.nplike is self._backend.index_nplike and missing.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_jagged_numvalid", _numvalid.dtype.type, @@ -574,7 +630,7 @@ def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): and slicestops.nplike is self._backend.index_nplike and missing.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_jagged_shrink", nextcarry.dtype.type, @@ -664,7 +720,7 @@ def _getitem_next( and self._starts.nplike is self._backend.index_nplike and self._stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_at", nextcarry.dtype.type, @@ -700,7 +756,7 @@ def _getitem_next( and self._starts.nplike is self._backend.index_nplike and self._stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_range_carrylength", carrylength.dtype.type, @@ -746,7 +802,7 @@ def _getitem_next( and self._starts.nplike is self._backend.index_nplike and self._stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_range", nextoffsets.dtype.type, @@ -783,7 +839,7 @@ def _getitem_next( total.nplike is self._backend.index_nplike and nextoffsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_range_counts", total.dtype.type, @@ -809,7 +865,7 @@ def _getitem_next( and advanced.nplike is self._backend.index_nplike and nextoffsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_range_spreadadvanced", nextadvanced.dtype.type, @@ -869,7 +925,7 @@ def _getitem_next( and self._stops.nplike is self._backend.index_nplike and regular_flathead.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_array", nextcarry.dtype.type, @@ -915,7 +971,7 @@ def _getitem_next( and regular_flathead.nplike is self._backend.index_nplike and advanced.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_array_advanced", nextcarry.dtype.type, @@ -970,7 +1026,7 @@ def _getitem_next( and self._starts.nplike is self._backend.index_nplike and self._stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_jagged_expand", multistarts.dtype.type, @@ -1006,10 +1062,10 @@ def _getitem_next( else: raise AssertionError(repr(head)) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: return self.to_ListOffsetArray64(True)._offsets_and_flattened(axis, depth) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -1033,7 +1089,7 @@ def _mergeable_next(self, other, mergebool): else: return False - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -1096,7 +1152,7 @@ def _mergemany(self, others): and array_starts.nplike is self._backend.index_nplike and array_stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_fill", nextstarts.dtype.type, @@ -1130,7 +1186,7 @@ def _mergemany(self, others): and array_starts.nplike is self._backend.index_nplike and array_stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_fill", nextstarts.dtype.type, @@ -1190,7 +1246,7 @@ def _local_index(self, axis, depth): localindex.nplike is self._backend.index_nplike and offsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_localindex", localindex.dtype.type, @@ -1326,7 +1382,7 @@ def _pad_none(self, target, axis, depth, clip): and self._starts.nplike is self._backend.index_nplike and self._stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_min_range", _min.dtype.type, @@ -1351,7 +1407,7 @@ def _pad_none(self, target, axis, depth, clip): and self._starts.nplike is self._backend.index_nplike and self._stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_rpad_and_clip_length_axis1", _tolength.dtype.type, @@ -1383,7 +1439,7 @@ def _pad_none(self, target, axis, depth, clip): and starts_.nplike is self._backend.index_nplike and stops_.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_rpad_axis1", index.dtype.type, @@ -1428,12 +1484,18 @@ def _to_arrow(self, pyarrow, mask_node, validbytes, length, options): ) def _to_backend_array(self, allow_missing, backend): - return self.to_RegularArray()._to_backend_array(allow_missing, backend) + array_param = self.parameter("__array__") + if array_param in {"bytestring", "string"}: + # As our array-of-strings _may_ be empty, we should pass the dtype + dtype = np.str_ if array_param == "string" else np.bytes_ + return backend.nplike.asarray(self.to_list(), dtype=dtype) + else: + return self.to_RegularArray()._to_backend_array(allow_missing, backend) def _remove_structure(self, backend, options): return self.to_ListOffsetArray64(False)._remove_structure(backend, options) - def _drop_none(self): + def _drop_none(self) -> Content: return self.to_ListOffsetArray64()._drop_none() def _rebuild_without_nones(self, none_indexes, new_content): diff --git a/src/awkward/contents/listoffsetarray.py b/src/awkward/contents/listoffsetarray.py index d171bcc1db..4cd5d2595b 100644 --- a/src/awkward/contents/listoffsetarray.py +++ b/src/awkward/contents/listoffsetarray.py @@ -2,24 +2,27 @@ from __future__ import annotations import copy +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend +from awkward._errors import AxisError from awkward._layout import maybe_posaxis from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata -from awkward._nplikes.shape import unknown_length +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._nplikes.typetracer import TypeTracer, is_unknown_scalar from awkward._parameters import ( type_parameters_equal, ) from awkward._regularize import is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content +from awkward.forms.form import Form from awkward.forms.listoffsetform import ListOffsetForm -from awkward.index import Index +from awkward.index import Index, Index64 if TYPE_CHECKING: from awkward._slicing import SliceItem @@ -140,20 +143,20 @@ def __init__(self, offsets, content, *, parameters=None): self._init(parameters, content.backend) @property - def offsets(self): + def offsets(self) -> Index: return self._offsets @property - def content(self): + def content(self) -> Content: return self._content form_cls: Final = ListOffsetForm - def copy(self, offsets=unset, content=unset, *, parameters=unset): + def copy(self, offsets=UNSET, content=UNSET, *, parameters=UNSET): return ListOffsetArray( - self._offsets if offsets is unset else offsets, - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, + self._offsets if offsets is UNSET else offsets, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, ) def __copy__(self): @@ -171,14 +174,14 @@ def simplified(cls, offsets, content, *, parameters=None): return cls(offsets, content, parameters=parameters) @property - def starts(self): + def starts(self) -> Index: return self._offsets[:-1] @property def stops(self): return self._offsets[1:] - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> ListOffsetForm: form_key = getkey(self) return self.form_cls( self._offsets.form, @@ -187,7 +190,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) key = getkey(self, form, "offsets") container[key] = ak._util.native_to_byteorder( @@ -203,20 +213,18 @@ def _to_typetracer(self, forget_length: bool) -> Self: parameters=self._parameters, ) - def _touch_data(self, recursive): - if not self._backend.index_nplike.known_data: - self._offsets.data.touch_data() + def _touch_data(self, recursive: bool): + self._offsets._touch_data() if recursive: self._content._touch_data(recursive) - def _touch_shape(self, recursive): - if not self._backend.index_nplike.known_data: - self._offsets.data.touch_shape() + def _touch_shape(self, recursive: bool): + self._offsets._touch_shape() if recursive: self._content._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._offsets.length - 1 def __repr__(self): @@ -234,45 +242,32 @@ def _repr(self, indent, pre, post): out.append(post) return "".join(out) - def to_ListOffsetArray64(self, start_at_zero=False): - if not self._backend.nplike.known_data and ( - start_at_zero or self._offsets.dtype != np.dtype(np.int64) - ): - self._touch_data(recursive=False) - self._content._touch_data(recursive=False) - - if issubclass(self._offsets.dtype.type, np.int64): - if ( - not self._backend.nplike.known_data - or self._offsets[0] == 0 - or not start_at_zero - ): - return self - - if start_at_zero: - offsets = ak.index.Index64( - self._offsets.raw(self._backend.nplike) - self._offsets[0], - nplike=self._backend.index_nplike, - ) - content = self._content[self._offsets[0] :] - else: - offsets, content = self._offsets, self._content - - return ListOffsetArray(offsets, content, parameters=self._parameters) - + def to_ListOffsetArray64(self, start_at_zero: bool = False) -> ListOffsetArray: + known_starts_at_zero = ( + self._backend.index_nplike.known_data and self._offsets[0] == 0 + ) + if start_at_zero and not known_starts_at_zero: + offsets = Index64( + self._offsets.data - self._offsets[0], + nplike=self._backend.index_nplike, + ) + return ListOffsetArray( + offsets, self._content[self._offsets[0] :], parameters=self._parameters + ) else: - offsets = self._compact_offsets64(start_at_zero) - return self._broadcast_tooffsets64(offsets) + return ListOffsetArray( + self._offsets.to64(), self._content, parameters=self._parameters + ) def to_RegularArray(self): start, stop = self._offsets[0], self._offsets[self._offsets.length - 1] content = self._content._getitem_range(start, stop) - _size = ak.index.Index64.empty(1, self._backend.index_nplike) + _size = Index64.empty(1, self._backend.index_nplike) assert ( _size.nplike is self._backend.index_nplike and self._offsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_toRegularArray", _size.dtype.type, @@ -315,7 +310,7 @@ def _getitem_range(self, start: SupportsIndex, stop: IndexType) -> Content: offsets = self._offsets[start : stop + 1] if offsets.length is not unknown_length and offsets.length == 0: offsets = Index( - self._backend.index_nplike.asarray([0], dtype=self._offsets.dtype), + self._backend.index_nplike.zeros(1, dtype=self._offsets.dtype), nplike=self._backend.index_nplike, ) return ListOffsetArray(offsets, self._content, parameters=self._parameters) @@ -351,68 +346,63 @@ def _carry(self, carry: Index, allow_lazy: bool) -> Content: nextstarts, nextstops, self._content, parameters=self._parameters ) - def _compact_offsets64(self, start_at_zero): - offsets_len = self._offsets.length - 1 - out = ak.index.Index64.empty(self._offsets.length, self._backend.index_nplike) - assert ( - out.nplike is self._backend.index_nplike - and self._offsets.nplike is self._backend.index_nplike - ) - self._handle_error( - self._backend[ - "awkward_ListOffsetArray_compact_offsets", - out.dtype.type, - self._offsets.dtype.type, - ](out.data, self._offsets.data, offsets_len) - ) - return out + def _compact_offsets64(self, start_at_zero: bool) -> Index64: + if not start_at_zero or ( + self._backend.index_nplike.known_data and self._offsets[0] == 0 + ): + return self._offsets + else: + return Index64( + self._offsets.data - self._offsets[0], + nplike=self._backend.index_nplike, + ) - def _broadcast_tooffsets64(self, offsets): - if offsets.nplike.known_data and (offsets.length == 0 or offsets[0] != 0): + def _broadcast_tooffsets64(self, offsets: Index) -> ListOffsetArray: + self._touch_data(recursive=False) + offsets._touch_data() + + index_nplike = self._backend.index_nplike + assert offsets.nplike is index_nplike + if offsets.length is not unknown_length and offsets.length == 0: raise AssertionError( - "broadcast_tooffsets64 can only be used with offsets that start at 0, not {}".format( - "(empty)" if offsets.length == 0 else str(offsets[0]) - ) + "broadcast_tooffsets64 can only be used with non-empty offsets" ) - - if offsets.nplike.known_data and offsets.length - 1 != self.length: + elif index_nplike.known_data and offsets[0] != 0: raise AssertionError( - "cannot broadcast {} of length {} to length {}".format( - type(self).__name__, self.length, offsets.length - 1 + f"broadcast_tooffsets64 can only be used with offsets that start at 0, not {offsets[0]}" + ) + elif ( + offsets.length is not unknown_length + and self._offsets.length is not unknown_length + and offsets.length != self._offsets.length + ): + raise AssertionError( + "cannot broadcast RegularArray of length {} to length {}".format( + self.length, offsets.length - 1 ) ) - starts, stops = self.starts, self.stops - - nextcarry = ak.index.Index64.empty(offsets[-1], self._backend.index_nplike) - assert ( - nextcarry.nplike is self._backend.index_nplike - and offsets.nplike is self._backend.index_nplike - and starts.nplike is self._backend.index_nplike - and stops.nplike is self._backend.index_nplike - ) - self._handle_error( - self._backend[ - "awkward_ListArray_broadcast_tooffsets", - nextcarry.dtype.type, - offsets.dtype.type, - starts.dtype.type, - stops.dtype.type, - ]( - nextcarry.data, - offsets.data, - offsets.length, - starts.data, - stops.data, - self._content.length, - ) - ) + # Check whether we need to slice the content, shift our offsets + this_start = self._offsets[0] + this_zero_offsets = self._offsets.data + if index_nplike.known_data and this_start == 0: + next_content = self._content + else: + this_zero_offsets = this_zero_offsets - this_start + next_content = self._content[this_start:] - nextcontent = self._content._carry(nextcarry, True) + if index_nplike.known_data and not index_nplike.array_equal( + this_zero_offsets, offsets + ): + raise ValueError("cannot broadcast nested list") - return ListOffsetArray(offsets, nextcontent, parameters=self._parameters) + return ListOffsetArray( + offsets, next_content[: offsets[-1]], parameters=self._parameters + ) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: out = ak.contents.ListArray( self.starts, self.stops, self._content, parameters=self._parameters ) @@ -433,14 +423,14 @@ def _getitem_next( lenstarts = self._offsets.length - 1 starts, stops = self.starts, self.stops nexthead, nexttail = ak._slicing.head_tail(tail) - nextcarry = ak.index.Index64.empty(lenstarts, self._backend.index_nplike) + nextcarry = Index64.empty(lenstarts, self._backend.index_nplike) assert ( nextcarry.nplike is self._backend.index_nplike and starts.nplike is self._backend.index_nplike and stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_at", nextcarry.dtype.type, @@ -467,13 +457,13 @@ def _getitem_next( start = ak._util.kSliceNone if start is None else start stop = ak._util.kSliceNone if stop is None else stop - carrylength = ak.index.Index64.empty(1, self._backend.index_nplike) + carrylength = Index64.empty(1, self._backend.index_nplike) assert ( carrylength.nplike is self._backend.index_nplike and self.starts.nplike is self._backend.index_nplike and self.stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_range_carrylength", carrylength.dtype.type, @@ -492,7 +482,7 @@ def _getitem_next( ) if self._starts.dtype == "int64": - nextoffsets = ak.index.Index64.empty( + nextoffsets = Index64.empty( lenstarts + 1, nplike=self._backend.index_nplike ) elif self._starts.dtype == "int32": @@ -503,9 +493,7 @@ def _getitem_next( nextoffsets = ak.index.IndexU32.empty( lenstarts + 1, nplike=self._backend.index_nplike ) - nextcarry = ak.index.Index64.empty( - carrylength[0], self._backend.index_nplike - ) + nextcarry = Index64.empty(carrylength[0], self._backend.index_nplike) assert ( nextoffsets.nplike is self._backend.index_nplike @@ -513,7 +501,7 @@ def _getitem_next( and self.starts.nplike is self._backend.index_nplike and self.stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_range", nextoffsets.dtype.type, @@ -545,12 +533,12 @@ def _getitem_next( ) else: - total = ak.index.Index64.empty(1, self._backend.index_nplike) + total = Index64.empty(1, self._backend.index_nplike) assert ( total.nplike is self._backend.index_nplike and nextoffsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_range_counts", total.dtype.type, @@ -563,15 +551,13 @@ def _getitem_next( slicer=head, ) - nextadvanced = ak.index.Index64.empty( - total[0], self._backend.index_nplike - ) + nextadvanced = Index64.empty(total[0], self._backend.index_nplike) assert ( nextadvanced.nplike is self._backend.index_nplike and advanced.nplike is self._backend.index_nplike and nextoffsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_range_spreadadvanced", nextadvanced.dtype.type, @@ -604,20 +590,20 @@ def _getitem_next( elif head is Ellipsis: return self._getitem_next_ellipsis(tail, advanced) - elif isinstance(head, ak.index.Index64): + elif isinstance(head, Index64): nexthead, nexttail = ak._slicing.head_tail(tail) flathead = self._backend.index_nplike.reshape( self._backend.index_nplike.asarray(head.data), (-1,) ) lenstarts = self.starts.length - regular_flathead = ak.index.Index64(flathead) + regular_flathead = Index64(flathead) if advanced is None or ( advanced.length is not unknown_length and advanced.length == 0 ): - nextcarry = ak.index.Index64.empty( + nextcarry = Index64.empty( lenstarts * flathead.length, self._backend.index_nplike ) - nextadvanced = ak.index.Index64.empty( + nextadvanced = Index64.empty( lenstarts * flathead.length, self._backend.index_nplike ) assert ( @@ -625,7 +611,7 @@ def _getitem_next( and nextadvanced.nplike is self._backend.index_nplike and regular_flathead.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_array", nextcarry.dtype.type, @@ -654,12 +640,8 @@ def _getitem_next( return out else: - nextcarry = ak.index.Index64.empty( - self.length, self._backend.index_nplike - ) - nextadvanced = ak.index.Index64.empty( - self.length, self._backend.index_nplike - ) + nextcarry = Index64.empty(self.length, self._backend.index_nplike) + nextadvanced = Index64.empty(self.length, self._backend.index_nplike) assert ( nextcarry.nplike is self._backend.index_nplike and nextadvanced.nplike is self._backend.index_nplike @@ -668,7 +650,7 @@ def _getitem_next( and regular_flathead.nplike is self._backend.index_nplike and advanced.nplike is self._backend.index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_ListArray_getitem_next_array_advanced", nextcarry.dtype.type, @@ -705,12 +687,21 @@ def _getitem_next( else: raise AssertionError(repr(head)) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 == depth: - raise np.AxisError("axis=0 not allowed for flatten") + raise AxisError("axis=0 not allowed for flatten") elif posaxis is not None and posaxis + 1 == depth + 1: + if ( + self.parameter("__array__") == "string" + or self.parameter("__array__") == "bytestring" + ): + raise ValueError( + "array of strings cannot be directly flattened. " + 'To flatten this array, drop the `"__array__"="string"` parameter using ' + "`ak.enforce_type`, `ak.with_parameter`, or `ak.without_parameters`/" + ) listoffsetarray = self.to_ListOffsetArray64(True) stop = listoffsetarray.offsets[-1] content = listoffsetarray.content._getitem_range(0, stop) @@ -720,7 +711,7 @@ def _offsets_and_flattened(self, axis, depth): inneroffsets, flattened = self._content._offsets_and_flattened( axis, depth + 1 ) - offsets = ak.index.Index64.zeros( + offsets = Index64.zeros( 0, nplike=self._backend.index_nplike, dtype=np.int64, @@ -737,14 +728,14 @@ def _offsets_and_flattened(self, axis, depth): elif ( self._offsets.length is not unknown_length and self._offsets.length == 1 ): - tooffsets = ak.index.Index64([inneroffsets[0]]) + tooffsets = Index64([inneroffsets[0]]) return ( offsets, ListOffsetArray(tooffsets, flattened, parameters=self._parameters), ) else: - tooffsets = ak.index.Index64.empty( + tooffsets = Index64.empty( self._offsets.length, self._backend.index_nplike, dtype=np.int64, @@ -754,7 +745,7 @@ def _offsets_and_flattened(self, axis, depth): and self._offsets.nplike is self._backend.index_nplike and inneroffsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_flatten_offsets", tooffsets.dtype.type, @@ -773,7 +764,7 @@ def _offsets_and_flattened(self, axis, depth): ListOffsetArray(tooffsets, flattened, parameters=self._parameters), ) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -797,7 +788,7 @@ def _mergeable_next(self, other, mergebool): else: return False - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self listarray = ak.contents.ListArray( @@ -832,9 +823,9 @@ def _local_index(self, axis, depth): else: self._touch_data(recursive=False) innerlength = unknown_length - localindex = ak.index.Index64.empty(innerlength, index_nplike) + localindex = Index64.empty(innerlength, index_nplike) assert localindex.nplike is index_nplike and offsets.nplike is index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_localindex", localindex.dtype.type, @@ -890,7 +881,7 @@ def _is_unique(self, negaxis, starts, parents, outlength): if not branch and (negaxis == depth): return self._content._is_unique(negaxis - 1, starts, parents, outlength) else: - nextparents = ak.index.Index64.empty( + nextparents = Index64.empty( self._offsets[-1] - self._offsets[0], self._backend.index_nplike ) @@ -898,7 +889,7 @@ def _is_unique(self, negaxis, starts, parents, outlength): nextparents.nplike is self._backend.index_nplike and self._offsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_local_nextparents_64", nextparents.dtype.type, @@ -924,7 +915,7 @@ def _unique(self, negaxis, starts, parents, outlength): or self.parameter("__array__") == "bytestring" ): if branch or (negaxis != depth): - raise np.AxisError("array with strings can only be sorted with axis=-1") + raise AxisError("array with strings can only be sorted with axis=-1") # FIXME: check validity error @@ -939,7 +930,7 @@ def _unique(self, negaxis, starts, parents, outlength): self.parameter("__array__") == "string" or self.parameter("__array__") == "bytestring" ): - raise np.AxisError("array with strings can only be sorted with axis=-1") + raise AxisError("array with strings can only be sorted with axis=-1") if self._backend.nplike.known_data and parents.nplike.known_data: assert self._offsets.length - 1 == parents.length @@ -961,14 +952,12 @@ def _unique(self, negaxis, starts, parents, outlength): maxnextparents[0] + 1, ) - outcarry = ak.index.Index64.empty( - nextcarry.length, self._backend.index_nplike - ) + outcarry = Index64.empty(nextcarry.length, self._backend.index_nplike) assert ( outcarry.nplike is self._backend.index_nplike and nextcarry.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_local_preparenext_64", outcarry.dtype.type, @@ -987,7 +976,7 @@ def _unique(self, negaxis, starts, parents, outlength): ) else: - nextparents = ak.index.Index64.empty( + nextparents = Index64.empty( self._offsets[-1] - self._offsets[0], self._backend.index_nplike ) @@ -995,7 +984,7 @@ def _unique(self, negaxis, starts, parents, outlength): nextparents.nplike is self._backend.index_nplike and self._offsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_local_nextparents_64", nextparents.dtype.type, @@ -1040,12 +1029,12 @@ def _argsort_next( or self.parameter("__array__") == "bytestring" ): if branch or (negaxis != depth): - raise np.AxisError("array with strings can only be sorted with axis=-1") + raise AxisError("array with strings can only be sorted with axis=-1") # FIXME: check validity error if isinstance(self._content, ak.contents.NumpyArray): - nextcarry = ak.index.Index64.empty( + nextcarry = Index64.empty( self._offsets.length - 1, self._backend.index_nplike ) @@ -1057,7 +1046,7 @@ def _argsort_next( and self_starts.nplike is self._backend.index_nplike and self_stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_argsort_strings", nextcarry.dtype.type, @@ -1086,7 +1075,7 @@ def _argsort_next( self.parameter("__array__") == "string" or self.parameter("__array__") == "bytestring" ): - raise np.AxisError("array with strings can only be sorted with axis=-1") + raise AxisError("array with strings can only be sorted with axis=-1") if self._backend.nplike.known_data and parents.nplike.known_data: assert self._offsets.length - 1 == parents.length @@ -1100,13 +1089,9 @@ def _argsort_next( nextstarts, ) = self._rearrange_prepare_next(outlength, parents) - nummissing = ak.index.Index64.empty(maxcount, self._backend.index_nplike) - missing = ak.index.Index64.empty( - self._offsets[-1], self._backend.index_nplike - ) - nextshifts = ak.index.Index64.empty( - nextcarry.length, self._backend.index_nplike - ) + nummissing = Index64.empty(maxcount, self._backend.index_nplike) + missing = Index64.empty(self._offsets[-1], self._backend.index_nplike) + nextshifts = Index64.empty(nextcarry.length, self._backend.index_nplike) assert ( nummissing.nplike is self._backend.index_nplike and missing.nplike is self._backend.index_nplike @@ -1117,7 +1102,7 @@ def _argsort_next( and nextcarry.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_nonlocal_nextshifts_64", nummissing.dtype.type, @@ -1152,14 +1137,12 @@ def _argsort_next( stable, ) - outcarry = ak.index.Index64.empty( - nextcarry.length, self._backend.index_nplike - ) + outcarry = Index64.empty(nextcarry.length, self._backend.index_nplike) assert ( outcarry.nplike is self._backend.index_nplike and nextcarry.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_local_preparenext_64", outcarry.dtype.type, @@ -1177,7 +1160,7 @@ def _argsort_next( out_offsets, out, parameters=self._parameters ) else: - nextparents = ak.index.Index64.empty( + nextparents = Index64.empty( self._backend.index_nplike.index_as_shape_item( self._offsets[-1] - self._offsets[0] ), @@ -1188,7 +1171,7 @@ def _argsort_next( nextparents.nplike is self._backend.index_nplike and self._offsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_local_nextparents_64", nextparents.dtype.type, @@ -1225,14 +1208,12 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): or self.parameter("__array__") == "bytestring" ): if branch or (negaxis != depth): - raise np.AxisError("array with strings can only be sorted with axis=-1") + raise AxisError("array with strings can only be sorted with axis=-1") # FIXME: check validity error if isinstance(self._content, ak.contents.NumpyArray): - nextcarry = ak.index.Index64.empty( - self._offsets.length - 1, index_nplike - ) + nextcarry = Index64.empty(self._offsets.length - 1, index_nplike) starts, stops = self._offsets[:-1], self._offsets[1:] assert ( @@ -1242,7 +1223,7 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): and starts.nplike is index_nplike and stops.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_argsort_strings", nextcarry.dtype.type, @@ -1269,7 +1250,7 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): self.parameter("__array__") == "string" or self.parameter("__array__") == "bytestring" ): - raise np.AxisError("array with strings can only be sorted with axis=-1") + raise AxisError("array with strings can only be sorted with axis=-1") if self._backend.nplike.known_data and parents.nplike.known_data: assert self._offsets.length - 1 == parents.length @@ -1293,9 +1274,9 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): stable, ) - outcarry = ak.index.Index64.empty(nextcarry.length, index_nplike) + outcarry = Index64.empty(nextcarry.length, index_nplike) assert outcarry.nplike is index_nplike and nextcarry.nplike is index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_local_preparenext_64", outcarry.dtype.type, @@ -1313,7 +1294,7 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): parameters=self._parameters, ) else: - nextparents = ak.index.Index64.empty( + nextparents = Index64.empty( index_nplike.index_as_shape_item(self._offsets[-1] - self._offsets[0]), index_nplike, ) @@ -1323,7 +1304,7 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): nextparents.nplike is index_nplike and self._offsets.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_local_nextparents_64", nextparents.dtype.type, @@ -1367,8 +1348,8 @@ def _combinations(self, n, replacement, recordlookup, parameters, axis, depth): starts = self.starts stops = self.stops - _totallen = ak.index.Index64.empty(1, index_nplike, dtype=np.int64) - offsets = ak.index.Index64.empty( + _totallen = Index64.empty(1, index_nplike, dtype=np.int64) + offsets = Index64.empty( self.length + 1, index_nplike, dtype=np.int64, @@ -1378,7 +1359,7 @@ def _combinations(self, n, replacement, recordlookup, parameters, axis, depth): and starts.nplike is index_nplike and stops.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_combinations_length", _totallen.data.dtype.type, @@ -1401,7 +1382,7 @@ def _combinations(self, n, replacement, recordlookup, parameters, axis, depth): tocarry = [] for i in range(n): - ptr = ak.index.Index64.empty( + ptr = Index64.empty( totallen, nplike=index_nplike, dtype=np.int64, @@ -1410,15 +1391,15 @@ def _combinations(self, n, replacement, recordlookup, parameters, axis, depth): if self._backend.nplike.known_data: tocarryraw[i] = ptr.ptr - toindex = ak.index.Index64.empty(n, index_nplike, dtype=np.int64) - fromindex = ak.index.Index64.empty(n, index_nplike, dtype=np.int64) + toindex = Index64.empty(n, index_nplike, dtype=np.int64) + fromindex = Index64.empty(n, index_nplike, dtype=np.int64) assert ( toindex.nplike is index_nplike and fromindex.nplike is index_nplike and starts.nplike is index_nplike and stops.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListArray_combinations", np.int64, @@ -1503,14 +1484,14 @@ def _reduce_next( nextstarts, ) = self._rearrange_prepare_next(outlength, parents) - outstarts = ak.index.Index64.empty(outlength, index_nplike) - outstops = ak.index.Index64.empty(outlength, index_nplike) + outstarts = Index64.empty(outlength, index_nplike) + outstops = Index64.empty(outlength, index_nplike) assert ( outstarts.nplike is index_nplike and outstops.nplike is index_nplike and distincts.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_nonlocal_outstartsstops_64", outstarts.dtype.type, @@ -1526,9 +1507,9 @@ def _reduce_next( ) if reducer.needs_position: - nextshifts = ak.index.Index64.empty(nextcarry.length, index_nplike) - nummissing = ak.index.Index64.empty(maxcount, index_nplike) - missing = ak.index.Index64.empty( + nextshifts = Index64.empty(nextcarry.length, index_nplike) + nummissing = Index64.empty(maxcount, index_nplike) + missing = Index64.empty( index_nplike.index_as_shape_item(self._offsets[-1]), index_nplike, ) @@ -1542,7 +1523,7 @@ def _reduce_next( and nextcarry.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_nonlocal_nextshifts_64", nummissing.dtype.type, @@ -1594,13 +1575,15 @@ def _reduce_next( nextlen = index_nplike.index_as_shape_item( self._offsets[-1] - self._offsets[0] ) - nextparents = ak.index.Index64.empty(nextlen, index_nplike) + nextparents = Index64.empty(nextlen, index_nplike) + # n.b. awkward_ListOffsetArray_reduce_local_nextparents_64 always returns parents that are + # monotonically increasing (because it is local) assert ( nextparents.nplike is index_nplike and self._offsets.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_local_nextparents_64", nextparents.dtype.type, @@ -1627,9 +1610,9 @@ def _reduce_next( behavior, ) - outoffsets = ak.index.Index64.empty(outlength + 1, index_nplike) + outoffsets = Index64.empty(outlength + 1, index_nplike) assert outoffsets.nplike is index_nplike and parents.nplike is index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_local_outoffsets_64", outoffsets.dtype.type, @@ -1662,14 +1645,14 @@ def _rearrange_prepare_next(self, outlength, parents): index_nplike = self._backend.index_nplike nextlen = index_nplike.index_as_shape_item(self._offsets[-1] - self._offsets[0]) lenstarts = self._offsets.length - 1 - _maxcount = ak.index.Index64.empty(1, index_nplike) - offsetscopy = ak.index.Index64.empty(self.offsets.length, index_nplike) + _maxcount = Index64.empty(1, index_nplike) + offsetscopy = Index64.empty(self.offsets.length, index_nplike) assert ( _maxcount.nplike is index_nplike and offsetscopy.nplike is index_nplike and self._offsets.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_nonlocal_maxcount_offsetscopy_64", _maxcount.dtype.type, @@ -1684,14 +1667,13 @@ def _rearrange_prepare_next(self, outlength, parents): ) maxcount = index_nplike.index_as_shape_item(_maxcount[0]) - # A "stable" sort is essential for the subsequent steps. - nextcarry = ak.index.Index64.empty(nextlen, nplike=index_nplike) - nextparents = ak.index.Index64.empty(nextlen, nplike=index_nplike) - _maxnextparents = ak.index.Index64.empty(1, index_nplike) + nextcarry = Index64.empty(nextlen, nplike=index_nplike) + nextparents = Index64.empty(nextlen, nplike=index_nplike) + _maxnextparents = Index64.empty(1, index_nplike) if maxcount is unknown_length or outlength is unknown_length: - distincts = ak.index.Index64.empty(unknown_length, index_nplike) + distincts = Index64.empty(unknown_length, index_nplike) else: - distincts = ak.index.Index64.empty(outlength * maxcount, index_nplike) + distincts = Index64.empty(outlength * maxcount, index_nplike) assert ( _maxnextparents.nplike is index_nplike @@ -1700,7 +1682,7 @@ def _rearrange_prepare_next(self, outlength, parents): and offsetscopy.nplike is index_nplike and parents.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_nonlocal_preparenext_64", nextcarry.dtype.type, @@ -1724,10 +1706,11 @@ def _rearrange_prepare_next(self, outlength, parents): maxcount, ) ) + maxnextparents = index_nplike.index_as_shape_item(_maxnextparents[0]) - nextstarts = ak.index.Index64.empty(maxnextparents + 1, index_nplike) + nextstarts = Index64.empty(maxnextparents + 1, index_nplike) assert nextstarts.nplike is index_nplike and nextparents.nplike is index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_nonlocal_nextstarts_64", nextstarts.dtype.type, @@ -1787,14 +1770,14 @@ def _pad_none(self, target, axis, depth, clip): return self._pad_none_axis0(target, clip) if posaxis is not None and posaxis + 1 == depth + 1: if not clip: - _tolength = ak.index.Index64.empty(1, index_nplike) - offsets_ = ak.index.Index64.empty(self._offsets.length, index_nplike) + _tolength = Index64.empty(1, index_nplike) + offsets_ = Index64.empty(self._offsets.length, index_nplike) assert ( offsets_.nplike is index_nplike and self._offsets.nplike is index_nplike and _tolength.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_rpad_length_axis1", offsets_.dtype.type, @@ -1809,12 +1792,12 @@ def _pad_none(self, target, axis, depth, clip): ) ) tolength = index_nplike.index_as_shape_item(_tolength[0]) - outindex = ak.index.Index64.empty(tolength, index_nplike) + outindex = Index64.empty(tolength, index_nplike) assert ( outindex.nplike is index_nplike and self._offsets.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_rpad_axis1", outindex.dtype.type, @@ -1833,16 +1816,16 @@ def _pad_none(self, target, axis, depth, clip): offsets_, next, parameters=self._parameters ) else: - starts_ = ak.index.Index64.empty( + starts_ = Index64.empty( self._offsets.length - 1, index_nplike, ) - stops_ = ak.index.Index64.empty( + stops_ = Index64.empty( self._offsets.length - 1, index_nplike, ) assert starts_.nplike is index_nplike and stops_.nplike is index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_index_rpad_and_clip_axis1", starts_.dtype.type, @@ -1855,7 +1838,7 @@ def _pad_none(self, target, axis, depth, clip): ) ) - outindex = ak.index.Index64.empty( + outindex = Index64.empty( target * (self._offsets.length - 1), index_nplike, ) @@ -1863,7 +1846,7 @@ def _pad_none(self, target, axis, depth, clip): outindex.nplike is index_nplike and self._offsets.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_rpad_and_clip_axis1", outindex.dtype.type, @@ -2003,9 +1986,11 @@ def _to_arrow(self, pyarrow, mask_node, validbytes, length, options): def _to_backend_array(self, allow_missing, backend): array_param = self.parameter("__array__") if array_param in {"bytestring", "string"}: - return backend.nplike.asarray(self.to_list()) - - return self.to_RegularArray()._to_backend_array(allow_missing, backend) + # As our array-of-strings _may_ be empty, we should pass the dtype + dtype = np.str_ if array_param == "string" else np.bytes_ + return backend.nplike.asarray(self.to_list(), dtype=dtype) + else: + return self.to_RegularArray()._to_backend_array(allow_missing, backend) def _remove_structure(self, backend, options): if ( @@ -2019,7 +2004,7 @@ def _remove_structure(self, backend, options): if options["keepdims"]: return [ ListOffsetArray( - ak.index.Index64( + Index64( backend.index_nplike.asarray( [0, backend.index_nplike.shape_item_as_index(c.length)] ) @@ -2032,7 +2017,7 @@ def _remove_structure(self, backend, options): else: return contents - def _drop_none(self): + def _drop_none(self) -> Content: if self._content.is_option: _, _, none_indexes = self._content._nextcarry_outindex() new_content = self._content._drop_none() @@ -2041,7 +2026,7 @@ def _drop_none(self): return self def _rebuild_without_nones(self, none_indexes, new_content): - new_offsets = ak.index.Index64.empty(self._offsets.length, self._backend.nplike) + new_offsets = Index64.empty(self._offsets.length, self._backend.nplike) assert ( new_offsets.nplike is self._backend.index_nplike @@ -2049,7 +2034,7 @@ def _rebuild_without_nones(self, none_indexes, new_content): and none_indexes.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_drop_none_indexes", new_offsets.dtype.type, @@ -2126,17 +2111,8 @@ def continuation(): def to_packed(self) -> Self: next = self.to_ListOffsetArray64(True) - content = next._content.to_packed() - packed_length = self._backend.index_nplike.index_as_shape_item( - next._offsets[-1] - ) - if ( - content.length is not unknown_length - and packed_length is not unknown_length - and content.length != packed_length - ): - content = content[: next._offsets[-1]] - return ListOffsetArray(next._offsets, content, parameters=next._parameters) + next_content = next._content[: next._offsets[-1]].to_packed() + return ListOffsetArray(next._offsets, next_content, parameters=next._parameters) def _to_list(self, behavior, json_conversions): if not self._backend.nplike.known_data: @@ -2228,7 +2204,7 @@ def _awkward_strings_to_nonfinite(self, nonfinit_dict): content.length, nplike=self._backend.index_nplike ) content.backend.nplike.isnan(content._data, union_tags._data) - union_index = ak.index.Index64( + union_index = Index64( self._backend.index_nplike.arange( content.length, dtype=np.int64 ), diff --git a/src/awkward/contents/numpyarray.py b/src/awkward/contents/numpyarray.py index 005558bbe3..476bc208f0 100644 --- a/src/awkward/contents/numpyarray.py +++ b/src/awkward/contents/numpyarray.py @@ -2,17 +2,20 @@ from __future__ import annotations import copy +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._backends.typetracer import TypeTracerBackend +from awkward._errors import AxisError from awkward._layout import maybe_posaxis from awkward._nplikes import to_nplike from awkward._nplikes.jax import Jax from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem from awkward._nplikes.typetracer import TypeTracerArray from awkward._parameters import ( parameters_intersect, @@ -20,9 +23,10 @@ ) from awkward._regularize import is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content +from awkward.forms.form import Form from awkward.forms.numpyform import NumpyForm from awkward.index import Index from awkward.types.numpytype import primitive_to_dtype @@ -127,15 +131,15 @@ def data(self) -> ArrayLike: def copy( self, - data=unset, + data=UNSET, *, - parameters=unset, - backend=unset, + parameters=UNSET, + backend=UNSET, ): return NumpyArray( - self._data if data is unset else data, - parameters=self._parameters if parameters is unset else parameters, - backend=self._backend if backend is unset else backend, + self._data if data is UNSET else data, + parameters=self._parameters if parameters is UNSET else parameters, + backend=self._backend if backend is UNSET else backend, ) def __copy__(self): @@ -152,25 +156,25 @@ def simplified(cls, data, *, parameters=None, backend=None): return cls(data, parameters=parameters, backend=backend) @property - def shape(self): + def shape(self) -> tuple[ShapeItem, ...]: return self._data.shape @property - def inner_shape(self): + def inner_shape(self) -> tuple[ShapeItem, ...]: return self._data.shape[1:] @property - def strides(self): - return self._data.strides + def strides(self) -> tuple[ShapeItem, ...]: + return self._backend.nplike.strides(self._data) @property - def dtype(self): + def dtype(self) -> np.dtype: return self._data.dtype def _raw(self, nplike=None): return to_nplike(self.data, nplike, from_nplike=self._backend.nplike) - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> NumpyForm: return self.form_cls( ak.types.numpytype.dtype_to_primitive(self._data.dtype), self._data.shape[1:], @@ -178,7 +182,14 @@ def _form_with_key(self, getkey): form_key=getkey(self), ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) key = getkey(self, form, "data") container[key] = ak._util.native_to_byteorder( @@ -194,16 +205,16 @@ def _to_typetracer(self, forget_length: bool) -> Self: backend=backend, ) - def _touch_data(self, recursive): + def _touch_data(self, recursive: bool): if not self._backend.nplike.known_data: self._data.touch_data() - def _touch_shape(self, recursive): + def _touch_shape(self, recursive: bool): if not self._backend.nplike.known_data: self._data.touch_shape() @property - def length(self): + def length(self) -> ShapeItem: return self._data.shape[0] def __repr__(self): @@ -319,7 +330,9 @@ def _carry(self, carry: Index, allow_lazy: bool) -> Content: raise ak._errors.index_error(self, carry.data, str(err)) from err return NumpyArray(nextdata, parameters=self._parameters, backend=self._backend) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: if self._data.ndim == 1: raise ak._errors.index_error( self, @@ -404,18 +417,18 @@ def _getitem_next( else: raise AssertionError(repr(head)) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 == depth: - raise np.AxisError("axis=0 not allowed for flatten") + raise AxisError("axis=0 not allowed for flatten") elif len(self.shape) != 1: return self.to_RegularArray()._offsets_and_flattened(axis, depth) else: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -464,7 +477,7 @@ def _mergeable_next(self, other, mergebool): else: return False - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -514,7 +527,7 @@ def _local_index(self, axis, depth): if posaxis is not None and posaxis + 1 == depth: return self._local_index_axis0() elif len(self.shape) <= 1: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") else: return self.to_RegularArray()._local_index(axis, depth) @@ -536,7 +549,7 @@ def _subranges_equal(self, starts, stops, length, sorted=True): is_equal = ak.index.Index64.zeros(1, nplike=self._backend.nplike) tmp = self._backend.nplike.empty(length, dtype=self.dtype) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_NumpyArray_fill", self.dtype.type, @@ -563,7 +576,7 @@ def _subranges_equal(self, starts, stops, length, sorted=True): and starts.nplike is self._backend.index_nplike and stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_quick_sort", self.dtype.type, @@ -586,7 +599,7 @@ def _subranges_equal(self, starts, stops, length, sorted=True): starts.nplike is self._backend.index_nplike and stops.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_NumpyArray_subrange_equal", self.dtype.type, @@ -615,7 +628,7 @@ def _as_unique_strings(self, offsets): offsets.nplike is self._backend.index_nplike and outoffsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_NumpyArray_sort_asstrings_uint8", self.dtype.type, @@ -640,7 +653,7 @@ def _as_unique_strings(self, offsets): and nextoffsets.nplike is self._backend.index_nplike and outlength.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_NumpyArray_unique_strings", self.dtype.type, @@ -678,10 +691,15 @@ def _numbers_to_type(self, name, including_unknown): def _is_unique(self, negaxis, starts, parents, outlength): if self.length == 0: return True - - elif len(self.shape) != 1 or not self.is_contiguous: - contiguous_self = self.to_contiguous() - return contiguous_self.to_RegularArray()._is_unique( + elif len(self.shape) != 1: + return self.to_RegularArray()._is_unique( + negaxis, + starts, + parents, + outlength, + ) + elif not self.is_contiguous: + return self.to_contiguous()._is_unique( negaxis, starts, parents, @@ -691,17 +709,17 @@ def _is_unique(self, negaxis, starts, parents, outlength): out = self._unique(negaxis, starts, parents, outlength) if isinstance(out, ak.contents.ListOffsetArray): return out.content.length == self.length - - return out.length == self.length + else: + return out.length == self.length def _unique(self, negaxis, starts, parents, outlength): if self.shape[0] == 0: return self - if len(self.shape) == 0: + elif len(self.shape) == 0: return self - if negaxis is None: + elif negaxis is None: contiguous_self = self.to_contiguous() offsets = ak.index.Index64.zeros(2, self._backend.index_nplike) @@ -713,7 +731,7 @@ def _unique(self, negaxis, starts, parents, outlength): ) out = self._backend.nplike.empty(self._data.size, dtype=dtype) assert offsets.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sort", dtype.type, @@ -733,7 +751,7 @@ def _unique(self, negaxis, starts, parents, outlength): nextlength = ak.index.Index64.empty(1, self._backend.index_nplike) assert nextlength.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_unique", out.dtype.type, @@ -752,9 +770,8 @@ def _unique(self, negaxis, starts, parents, outlength): ) # axis is not None - if len(self.shape) != 1 or not self.is_contiguous: - contiguous_self = self.to_contiguous() - return contiguous_self.to_RegularArray()._unique( + elif len(self.shape) != 1: + return self.to_RegularArray()._unique( negaxis, starts, parents, @@ -767,7 +784,7 @@ def _unique(self, negaxis, starts, parents, outlength): offsets_length.nplike is self._backend.index_nplike and parents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sorting_ranges_length", offsets_length.dtype.type, @@ -786,7 +803,7 @@ def _unique(self, negaxis, starts, parents, outlength): offsets.nplike is self._backend.index_nplike and parents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sorting_ranges", offsets.dtype.type, @@ -801,7 +818,7 @@ def _unique(self, negaxis, starts, parents, outlength): out = self._backend.nplike.empty(self.length, dtype=self.dtype) assert offsets.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sort", out.dtype.type, @@ -826,7 +843,7 @@ def _unique(self, negaxis, starts, parents, outlength): offsets.nplike is self._backend.index_nplike and nextoffsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_unique_ranges", out.dtype.type, @@ -850,7 +867,7 @@ def _unique(self, negaxis, starts, parents, outlength): and nextoffsets.nplike is self._backend.index_nplike and starts.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_unique_offsets", outoffsets.dtype.type, @@ -872,14 +889,14 @@ def _unique(self, negaxis, starts, parents, outlength): def _argsort_next( self, negaxis, starts, shifts, parents, outlength, ascending, stable ): - if len(self.shape) == 0: - raise TypeError(f"{type(self).__name__} attempting to argsort a scalar ") - elif len(self.shape) != 1 or not self.is_contiguous: - contiguous_self = self.to_contiguous() - return contiguous_self.to_RegularArray()._argsort_next( + if len(self.shape) != 1: + return self.to_RegularArray()._argsort_next( + negaxis, starts, shifts, parents, outlength, ascending, stable + ) + elif not self.is_contiguous: + return self.to_contiguous()._argsort_next( negaxis, starts, shifts, parents, outlength, ascending, stable ) - else: parents_length = parents.length _offsets_length = ak.index.Index64.empty(1, self._backend.index_nplike) @@ -887,7 +904,7 @@ def _argsort_next( _offsets_length.nplike is self._backend.index_nplike and parents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sorting_ranges_length", _offsets_length.dtype.type, @@ -907,7 +924,7 @@ def _argsort_next( offsets.nplike is self._backend.index_nplike and parents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sorting_ranges", offsets.dtype.type, @@ -930,7 +947,7 @@ def _argsort_next( nextcarry.nplike is self._backend.index_nplike and offsets.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_argsort", nextcarry.dtype.type, @@ -955,7 +972,7 @@ def _argsort_next( and parents.nplike is self._backend.index_nplike and starts.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_NumpyArray_rearrange_shifted", nextcarry.dtype.type, @@ -979,12 +996,12 @@ def _argsort_next( return out def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): - if len(self.shape) == 0: - raise TypeError(f"{type(self).__name__} attempting to sort a scalar ") - - elif len(self.shape) != 1 or not self.is_contiguous: - contiguous_self = self.to_contiguous() - return contiguous_self.to_RegularArray()._sort_next( + if len(self.shape) != 1: + return self.to_RegularArray()._sort_next( + negaxis, starts, parents, outlength, ascending, stable + ) + elif not self.is_contiguous: + return self.to_contiguous()._sort_next( negaxis, starts, parents, outlength, ascending, stable ) @@ -995,7 +1012,7 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): _offsets_length.nplike is self._backend.index_nplike and parents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sorting_ranges_length", _offsets_length.dtype.type, @@ -1016,7 +1033,7 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): offsets.nplike is self._backend.index_nplike and parents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sorting_ranges", offsets.dtype.type, @@ -1036,7 +1053,7 @@ def _sort_next(self, negaxis, starts, parents, outlength, ascending, stable): ) out = self._backend.nplike.empty(self.length, dtype=dtype) assert offsets.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_sort", dtype.type, @@ -1064,7 +1081,7 @@ def _combinations(self, n, replacement, recordlookup, parameters, axis, depth): if posaxis is not None and posaxis + 1 == depth: return self._combinations_axis0(n, replacement, recordlookup, parameters) elif len(self.shape) <= 1: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") else: return self.to_RegularArray()._combinations( n, replacement, recordlookup, parameters, axis, depth @@ -1111,50 +1128,7 @@ def _reduce_next( assert self.is_contiguous assert self._data.ndim == 1 - out = self._backend.apply_reducer(reducer, self, parents, outlength) - - if reducer.needs_position: - if shifts is None: - assert ( - out.backend is self._backend - and parents.nplike is self._backend.index_nplike - and starts.nplike is self._backend.index_nplike - ) - self._handle_error( - self._backend[ - "awkward_NumpyArray_reduce_adjust_starts_64", - out.data.dtype.type, - parents.dtype.type, - starts.dtype.type, - ]( - out.data, - outlength, - parents.data, - starts.data, - ) - ) - else: - assert ( - out.backend is self._backend - and parents.nplike is self._backend.index_nplike - and starts.nplike is self._backend.index_nplike - and shifts.nplike is self._backend.index_nplike - ) - self._handle_error( - self._backend[ - "awkward_NumpyArray_reduce_adjust_starts_shifts_64", - out.data.dtype.type, - parents.dtype.type, - starts.dtype.type, - shifts.dtype.type, - ]( - out.data, - outlength, - parents.data, - starts.data, - shifts.data, - ) - ) + out = reducer.apply(self, parents, starts, shifts, outlength) if mask: outmask = ak.index.Index8.empty(outlength, self._backend.index_nplike) @@ -1162,7 +1136,7 @@ def _reduce_next( outmask.nplike is self._backend.index_nplike and parents.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_NumpyArray_reduce_mask_ByteMaskedArray_64", outmask.dtype.type, @@ -1174,7 +1148,6 @@ def _reduce_next( outlength, ) ) - out = ak.contents.ByteMaskedArray(outmask, out, False, parameters=None) if keepdims: @@ -1196,11 +1169,13 @@ def _validity_error(self, path): def _pad_none(self, target, axis, depth, clip): if len(self.shape) == 0: raise ValueError("cannot apply ak.pad_none to a scalar") - elif len(self.shape) > 1 or not self.is_contiguous: + elif len(self.shape) > 1: return self.to_RegularArray()._pad_none(target, axis, depth, clip) + elif not self.is_contiguous: + return self.to_contiguous()._pad_none(target, axis, depth, clip) posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 != depth: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") if not clip: if target < self.length: return self @@ -1376,7 +1351,6 @@ def _is_equal_to(self, other, index_dtype, numpyarray): return ( self._backend.nplike.array_equal(self.data, other.data) and self.dtype == other.dtype - and self.is_contiguous == other.is_contiguous and self.shape == other.shape ) else: diff --git a/src/awkward/contents/recordarray.py b/src/awkward/contents/recordarray.py index 202cab48ea..2ba17c77f2 100644 --- a/src/awkward/contents/recordarray.py +++ b/src/awkward/contents/recordarray.py @@ -3,26 +3,28 @@ import copy import json -from collections.abc import Iterable +from collections.abc import Iterable, MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend from awkward._backends.numpy import NumpyBackend from awkward._backends.typetracer import TypeTracerBackend from awkward._behavior import find_record_reducer -from awkward._layout import maybe_posaxis +from awkward._errors import AxisError +from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata -from awkward._nplikes.shape import unknown_length +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._parameters import ( parameters_intersect, type_parameters_equal, ) from awkward._regularize import is_integer from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content +from awkward.forms.form import Form from awkward.forms.recordform import RecordForm from awkward.index import Index from awkward.record import Record @@ -34,6 +36,13 @@ numpy = Numpy.instance() +def _apply_record_reducer(reducer, layout: Content, mask: bool, behavior) -> Content: + # Build a 1D list over these contents + array = wrap_layout(layout, behavior=behavior) + # Perform the reduction + return ak.to_layout(reducer(array, mask)) + + @final class RecordArray(Content): """ @@ -259,19 +268,19 @@ def fields(self): def copy( self, - contents=unset, - fields=unset, - length=unset, + contents=UNSET, + fields=UNSET, + length=UNSET, *, - parameters=unset, - backend=unset, + parameters=UNSET, + backend=UNSET, ): return RecordArray( - self._contents if contents is unset else contents, - self._fields if fields is unset else fields, - self._length if length is unset else length, - parameters=self._parameters if parameters is unset else parameters, - backend=self._backend if backend is unset else backend, + self._contents if contents is UNSET else contents, + self._fields if fields is UNSET else fields, + self._length if length is UNSET else length, + parameters=self._parameters if parameters is UNSET else parameters, + backend=self._backend if backend is UNSET else backend, ) def __copy__(self): @@ -305,7 +314,7 @@ def to_tuple(self) -> Self: self._contents, None, self._length, parameters=None, backend=self._backend ) - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> RecordForm: form_key = getkey(self) return self.form_cls( [x._form_with_key(getkey) for x in self._contents], @@ -314,7 +323,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) if self._fields is None: for i, content in enumerate(self._contents): @@ -338,18 +354,18 @@ def _to_typetracer(self, forget_length: bool) -> Self: backend=backend, ) - def _touch_data(self, recursive): + def _touch_data(self, recursive: bool): if recursive: for x in self._contents: x._touch_data(recursive) - def _touch_shape(self, recursive): + def _touch_shape(self, recursive: bool): if recursive: for x in self._contents: x._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._length def __repr__(self): @@ -366,7 +382,7 @@ def _repr(self, indent, pre, post): if self._fields is None: for i, x in enumerate(self._contents): - out.append(f"{indent} \n") + out.append(f"{indent} \n") out.append(x._repr(indent + " ", "", "\n")) out.append(indent + " \n") else: @@ -428,10 +444,6 @@ def _getitem_at(self, where: IndexType): def _getitem_range(self, start: SupportsIndex, stop: IndexType) -> Content: if not self._backend.nplike.known_data: self._touch_shape(recursive=False) - return self - - if self._length is unknown_length: - return self start, stop, _, length = self._backend.index_nplike.derive_slice_for_length( slice(start, stop), self._length @@ -533,7 +545,9 @@ def _carry(self, carry: Index, allow_lazy: bool) -> Content: backend=self._backend, ) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: contents = [] for i in range(len(self._contents)): contents.append( @@ -592,10 +606,10 @@ def _getitem_next( ) return next._getitem_next(nexthead, nexttail, advanced) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 == depth: - raise np.AxisError("axis=0 not allowed for flatten") + raise AxisError("axis=0 not allowed for flatten") elif posaxis is not None and posaxis + 1 == depth + 1: raise ValueError( @@ -628,7 +642,7 @@ def _offsets_and_flattened(self, axis, depth): ), ) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -664,7 +678,7 @@ def _mergeable_next(self, other, mergebool): else: return False - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -741,13 +755,13 @@ def _mergemany(self, others): ) nextcontents = [] - minlength = ak._util.unset + minlength = ak._util.UNSET for forfield in for_each_field: merged = forfield[0]._mergemany(forfield[1:]) nextcontents.append(merged) - if minlength is ak._util.unset or ( + if minlength is ak._util.UNSET or ( not (merged.length is unknown_length or minlength is unknown_length) and merged.length < minlength ): @@ -888,13 +902,133 @@ def _reduce_next( if reducer_recordclass is None: raise TypeError( "no ak.{} overloads for custom types: {}".format( - reducer.name, ", ".join(self._fields) + reducer.name, ", ".join(self.fields) ) ) else: - raise NotImplementedError( - "overloading reducers for RecordArrays has not been implemented yet" + # Positional reducers ultimately need to do more work when rebuilding the result + # so asking for a mask doesn't help us! + reducer_should_mask = mask and not reducer.needs_position + + # Convert parents into offsets to build a list for axis=1 reduction + offsets = ak.index.Index64.empty(outlength + 1, self._backend.index_nplike) + assert ( + offsets.nplike is self._backend.index_nplike + and parents.nplike is self._backend.index_nplike ) + # `parents` are possibly non monotonic increasing, so we must re-order the result + # This happens naturally for the `NumpyArray` reducers. + carry = ak.index.Index64.empty(outlength, self._backend.index_nplike) + + # Note: if we knew that `negaxis == depth` exclusively for this layout, we could use + # the simpler `ListOffsetArray_reduce_local_outoffsets_64`. However, if our parent was reduced, + # we would still see `negaxis == depth`, so this kernel has to be used instead. + assert carry.nplike is self._backend.index_nplike + self._backend.maybe_kernel_error( + self._backend[ + "awkward_RecordArray_reduce_nonlocal_outoffsets_64", + offsets.dtype.type, + carry.dtype.type, + parents.dtype.type, + ]( + offsets.data, + carry.data, + parents.data, + parents.length, + outlength, + ) + ) + out = _apply_record_reducer( + reducer_recordclass, + ak.contents.ListOffsetArray(offsets, self), + reducer_should_mask, + behavior, + ) + out = out._carry(carry, allow_lazy=True) + + if out.is_option and not reducer_should_mask: + reason = ( + "reducer is positional" + if reducer.needs_position + else "mask is False" + ) + raise TypeError( + f"a custom implementation of the reducer {reducer.name} for {self.parameter('__record__')!r} " + f"returned an option when it was not expected ({reason})" + ) + + if reducer.needs_position: + assert isinstance(out, ak.contents.NumpyArray) + + if shifts is None: + assert ( + out.backend is self._backend + and parents.nplike is self._backend.index_nplike + and starts.nplike is self._backend.index_nplike + ) + self._backend.maybe_kernel_error( + self._backend[ + "awkward_NumpyArray_reduce_adjust_starts_64", + out.data.dtype.type, + parents.dtype.type, + starts.dtype.type, + ]( + out.data, + outlength, + parents.data, + starts.data, + ) + ) + else: + assert ( + out.backend is self._backend + and parents.nplike is self._backend.index_nplike + and starts.nplike is self._backend.index_nplike + and shifts.nplike is self._backend.index_nplike + ) + self._backend.maybe_kernel_error( + self._backend[ + "awkward_NumpyArray_reduce_adjust_starts_shifts_64", + out.data.dtype.type, + parents.dtype.type, + starts.dtype.type, + shifts.dtype.type, + ]( + out.data, + outlength, + parents.data, + starts.data, + shifts.data, + ) + ) + + if mask: + outmask = ak.index.Index8.empty(outlength, self._backend.index_nplike) + assert ( + outmask.nplike is self._backend.index_nplike + and parents.nplike is self._backend.index_nplike + ) + self._backend.maybe_kernel_error( + self._backend[ + "awkward_NumpyArray_reduce_mask_ByteMaskedArray_64", + outmask.dtype.type, + parents.dtype.type, + ]( + outmask.data, + parents.data, + parents.length, + outlength, + ) + ) + + out = ak.contents.ByteMaskedArray.simplified( + outmask, out, False, parameters=None + ) + + if keepdims: + out = ak.contents.RegularArray(out, 1, self.length, parameters=None) + + return out def _validity_error(self, path): for i, cont in enumerate(self.contents): @@ -904,6 +1038,14 @@ def _validity_error(self, path): sub = cont._validity_error(f"{path}.field({i})") if sub != "": return sub + + # Check for duplicate fields + if not self.is_tuple: + seen_fields = set() + for field in self._fields: + if field in seen_fields: + return f"at {path} ({type(self)!r}): duplicate field {field!r}" + seen_fields.add(field) return "" def _nbytes_part(self): @@ -999,6 +1141,8 @@ def _remove_structure(self, backend, options): for content in self._contents: out.extend(content[: self._length]._remove_structure(backend, options)) return out + elif options["allow_records"]: + return [self] else: in_function = "" if options["function_name"] is not None: diff --git a/src/awkward/contents/regulararray.py b/src/awkward/contents/regulararray.py index 25af054a50..be180ef9ab 100644 --- a/src/awkward/contents/regulararray.py +++ b/src/awkward/contents/regulararray.py @@ -2,13 +2,14 @@ from __future__ import annotations import copy +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend from awkward._layout import maybe_posaxis from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata -from awkward._nplikes.shape import unknown_length +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._parameters import ( parameters_intersect, parameters_union, @@ -16,14 +17,16 @@ ) from awkward._regularize import is_integer, is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content +from awkward.forms.form import Form from awkward.forms.regularform import RegularForm from awkward.index import Index if TYPE_CHECKING: from awkward._slicing import SliceItem + from awkward.contents.listoffsetarray import ListOffsetArray np = NumpyMetadata.instance() numpy = Numpy.instance() @@ -166,7 +169,7 @@ def __init__(self, content, size, zeros_length=0, *, parameters=None): self._init(parameters, content.backend) @property - def content(self): + def content(self) -> Content: return self._content @property @@ -175,12 +178,12 @@ def size(self): form_cls: Final = RegularForm - def copy(self, content=unset, size=unset, zeros_length=unset, *, parameters=unset): + def copy(self, content=UNSET, size=UNSET, zeros_length=UNSET, *, parameters=UNSET): return RegularArray( - self._content if content is unset else content, - self._size if size is unset else size, - self._length if zeros_length is unset else zeros_length, - parameters=self._parameters if parameters is unset else parameters, + self._content if content is UNSET else content, + self._size if size is UNSET else size, + self._length if zeros_length is UNSET else zeros_length, + parameters=self._parameters if parameters is UNSET else parameters, ) def __copy__(self): @@ -197,18 +200,18 @@ def simplified(cls, content, size, zeros_length=0, *, parameters=None): return cls(content, size, zeros_length, parameters=parameters) @property - def offsets(self): + def offsets(self) -> Index: return self._compact_offsets64(True) @property - def starts(self): + def starts(self) -> Index: return self._compact_offsets64(True)[:-1] @property def stops(self): return self._compact_offsets64(True)[1:] - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> RegularForm: form_key = getkey(self) return self.form_cls( self._content._form_with_key(getkey), @@ -217,7 +220,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) self._content._to_buffers(form.content, getkey, container, backend, byteorder) @@ -229,16 +239,16 @@ def _to_typetracer(self, forget_length: bool) -> Self: parameters=self._parameters, ) - def _touch_data(self, recursive): + def _touch_data(self, recursive: bool): if recursive: self._content._touch_data(recursive) - def _touch_shape(self, recursive): + def _touch_shape(self, recursive: bool): if recursive: self._content._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._length def __repr__(self): @@ -257,7 +267,7 @@ def _repr(self, indent, pre, post): out.append(post) return "".join(out) - def to_ListOffsetArray64(self, start_at_zero=False): + def to_ListOffsetArray64(self, start_at_zero: bool = False) -> ListOffsetArray: offsets = self._compact_offsets64(start_at_zero) return self._broadcast_tooffsets64(offsets) @@ -355,7 +365,7 @@ def _carry(self, carry: Index, allow_lazy: bool) -> Content: ) assert nextcarry.nplike is self._backend.index_nplike - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_RegularArray_getitem_carry", nextcarry.dtype.type, @@ -377,74 +387,80 @@ def _carry(self, carry: Index, allow_lazy: bool) -> Content: ) def _compact_offsets64(self, start_at_zero): - out = ak.index.Index64.empty( - self._length + 1, - self._backend.index_nplike, - ) - assert out.nplike is self._backend.index_nplike - self._handle_error( - self._backend["awkward_RegularArray_compact_offsets", out.dtype.type]( - out.data, - self._length, - self._size, + index_nplike = self._backend.index_nplike + if self._size is not unknown_length and self._size == 0: + return ak.index.Index64.zeros(self._length + 1, nplike=index_nplike) + else: + return ak.index.Index64( + index_nplike.arange( + 0, + index_nplike.shape_item_as_index(self._length * self._size) + 1, + index_nplike.shape_item_as_index(self._size), + dtype=np.int64, + ), + nplike=index_nplike, ) - ) - return out - def _broadcast_tooffsets64(self, offsets): - if offsets.nplike.known_data and (offsets.length == 0 or offsets[0] != 0): + def _broadcast_tooffsets64(self, offsets: Index) -> ListOffsetArray: + self._touch_data(recursive=False) + offsets._touch_data() + + index_nplike = self._backend.index_nplike + assert offsets.nplike is index_nplike + if offsets.length is not unknown_length and offsets.length == 0: raise AssertionError( - "broadcast_tooffsets64 can only be used with offsets that start at 0, not {}".format( - "(empty)" if offsets.length == 0 else str(offsets[0]) - ) + "broadcast_tooffsets64 can only be used with non-empty offsets" ) - - if offsets.nplike.known_data and offsets.length - 1 != self._length: + elif index_nplike.known_data and offsets[0] != 0: + raise AssertionError( + f"broadcast_tooffsets64 can only be used with offsets that start at 0, not {offsets[0]}" + ) + elif ( + offsets.length is not unknown_length + and self._length is not unknown_length + and offsets.length - 1 != self._length + ): raise AssertionError( "cannot broadcast RegularArray of length {} to length {}".format( self._length, offsets.length - 1 ) ) - if self._size == 1: - carrylen = self._backend.index_nplike.index_as_shape_item(offsets[-1]) - nextcarry = ak.index.Index64.empty(carrylen, self._backend.index_nplike) + if self._size is not unknown_length and self._size == 1: + count = offsets.data[1:] - offsets.data[:-1] + # Sanity check that our kernel isn't losing values here assert ( - nextcarry.nplike is self._backend.index_nplike - and offsets.nplike is self._backend.index_nplike - ) - self._handle_error( - self._backend[ - "awkward_RegularArray_broadcast_tooffsets_size1", - nextcarry.dtype.type, - offsets.dtype.type, - ]( - nextcarry.data, - offsets.data, - offsets.length, - ) + not self._backend.index_nplike.known_data + or count.size is unknown_length + or count.size == 0 + or count.dtype == np.intp + or self._backend.index_nplike.max(count) <= np.iinfo(np.intp).max ) - nextcontent = self._content._carry(nextcarry, True) - return ak.contents.ListOffsetArray( - offsets, nextcontent, parameters=self._parameters + carry = ak.index.Index64( + index_nplike.repeat( + index_nplike.arange( + index_nplike.shape_item_as_index(self._length), dtype=np.int64 + ), + index_nplike.astype(count, np.intp), + ), + nplike=index_nplike, ) - + next_content = self._content._carry(carry, True) else: - assert offsets.nplike is self._backend.index_nplike - self._handle_error( - self._backend[ - "awkward_RegularArray_broadcast_tooffsets", offsets.dtype.type - ]( - offsets.data, - offsets.length, - self._size, - ) - ) - return ak.contents.ListOffsetArray( - offsets, self._content, parameters=self._parameters - ) + this_offsets = self._compact_offsets64(True) + if index_nplike.known_data and not index_nplike.array_equal( + offsets.data, this_offsets.data + ): + raise ValueError("cannot broadcast nested list") + + next_content = self._content[: offsets[-1]] + return ak.contents.ListOffsetArray( + offsets, next_content, parameters=self._parameters + ) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: out = self.to_ListOffsetArray64(True) return out._getitem_next_jagged(slicestarts, slicestops, slicecontent, tail) @@ -463,7 +479,7 @@ def _getitem_next( nexthead, nexttail = ak._slicing.head_tail(tail) nextcarry = ak.index.Index64.empty(self._length, index_nplike) assert nextcarry.nplike is index_nplike - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_RegularArray_getitem_next_at", nextcarry.dtype.type ]( @@ -485,7 +501,7 @@ def _getitem_next( nextcarry = ak.index.Index64.empty(self._length * nextsize, index_nplike) assert nextcarry.nplike is index_nplike - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_RegularArray_getitem_next_range", nextcarry.dtype.type, @@ -518,7 +534,7 @@ def _getitem_next( nextadvanced.nplike is index_nplike and advanced.nplike is index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_RegularArray_getitem_next_range_spreadadvanced", nextadvanced.dtype.type, @@ -555,7 +571,7 @@ def _getitem_next( flathead = index_nplike.reshape(index_nplike.asarray(head.data), (-1,)) regular_flathead = ak.index.Index64.empty(flathead.shape[0], index_nplike) assert regular_flathead.nplike is index_nplike - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_RegularArray_getitem_next_array_regularize", regular_flathead.dtype.type, @@ -583,7 +599,7 @@ def _getitem_next( and nextadvanced.nplike is index_nplike and regular_flathead.nplike is index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_RegularArray_getitem_next_array", nextcarry.dtype.type, @@ -625,7 +641,7 @@ def _getitem_next( and advanced.nplike is index_nplike and regular_flathead.nplike is index_nplike ) - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_RegularArray_getitem_next_array_advanced", nextcarry.dtype.type, @@ -674,7 +690,7 @@ def _getitem_next( ) assert head.offsets.nplike is index_nplike - self._handle_error( + self._maybe_index_error( self._backend[ "awkward_RegularArray_getitem_jagged_expand", multistarts.dtype.type, @@ -703,10 +719,10 @@ def _getitem_next( else: raise AssertionError(repr(head)) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: return self.to_ListOffsetArray64(True)._offsets_and_flattened(axis, depth) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -730,7 +746,7 @@ def _mergeable_next(self, other, mergebool): else: return False - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -778,7 +794,7 @@ def _local_index(self, axis, depth): localindex = ak.index.Index64.empty( self._length * self._size, nplike=self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend["awkward_RegularArray_localindex", np.int64]( localindex.data, self._size, @@ -922,7 +938,7 @@ def _combinations(self, n, replacement, recordlookup, parameters, axis, depth): assert ( toindex.nplike is index_nplike and fromindex.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_RegularArray_combinations_64", np.int64, @@ -940,11 +956,11 @@ def _combinations(self, n, replacement, recordlookup, parameters, axis, depth): ) contents = [] - length = unset + length = UNSET for ptr in tocarry: contents.append(self._content._carry(ptr, True)) length = contents[-1].length - assert length is not unset + assert length is not UNSET recordarray = ak.contents.RecordArray( contents, recordlookup, @@ -980,18 +996,6 @@ def _reduce_next( branch, depth = self.branch_depth nextlen = self._length * self._size if not branch and negaxis == depth: - if self._size == 0: - nextstarts = ak.index.Index64( - index_nplike.zeros(self._length, dtype=np.int64), - nplike=index_nplike, - ) - else: - nextstarts = ak.index.Index64( - index_nplike.arange(0, nextlen, self._size), - nplike=index_nplike, - ) - assert nextstarts.length == self._length - nextcarry = ak.index.Index64.empty(nextlen, nplike=index_nplike) nextparents = ak.index.Index64.empty(nextlen, nplike=index_nplike) assert ( @@ -999,7 +1003,7 @@ def _reduce_next( and nextcarry.nplike is index_nplike and nextparents.nplike is index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_RegularArray_reduce_nonlocal_preparenext", nextcarry.dtype.type, @@ -1010,7 +1014,28 @@ def _reduce_next( nextparents.data, parents.data, self._size, - len(self), + self._length, + ) + ) + nextstarts = ak.index.Index64.empty( + # `starts` must have at least enough elements for the largest `nextparent` to index into + # The upper bound for this value is given by `nextlen` (each item in this list belonging + # to a distinct reduction), but the length of `starts` should equate to `maxnextparents - 1`. + starts.length * self._size, + nplike=index_nplike, + ) + assert ( + nextstarts.nplike is index_nplike and nextparents.nplike is index_nplike + ) + self._backend.maybe_kernel_error( + self._backend[ + "awkward_ListOffsetArray_reduce_nonlocal_nextstarts_64", + nextstarts.dtype.type, + nextparents.dtype.type, + ]( + nextstarts.data, + nextparents.data, + nextlen, ) ) @@ -1049,7 +1074,7 @@ def _reduce_next( nextparents = ak.index.Index64.empty(nextlen, index_nplike) assert nextparents.nplike is index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_RegularArray_reduce_local_nextparents", nextparents.dtype.type, @@ -1138,7 +1163,7 @@ def _reduce_next( outoffsets = ak.index.Index64.empty(outlength + 1, index_nplike) assert outoffsets.nplike is index_nplike and parents.nplike is index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_ListOffsetArray_reduce_local_outoffsets_64", outoffsets.dtype.type, @@ -1180,7 +1205,7 @@ def _pad_none(self, target, axis, depth, clip): self._backend.index_nplike, ) assert index.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_RegularArray_rpad_and_clip_axis1", index.dtype.type ](index.data, target, self._size, self._length) @@ -1206,19 +1231,27 @@ def _pad_none(self, target, axis, depth, clip): def _to_backend_array(self, allow_missing, backend): array_param = self.parameter("__array__") if array_param in {"bytestring", "string"}: - return backend.nplike.asarray(self.to_list()) - - out = self._content._to_backend_array(allow_missing, backend) - shape = (self._length, self._size) + out.shape[1:] - - # ShapeItem is a defined type, but some nplikes don't map onto the entire space; e.g. - # NumPy never has `None` shape items. We require that if a shape-item is used between nplikes - # they both be the same "known-shape-ness". - assert self._backend.index_nplike.known_data == self._backend.nplike.known_data - return self._backend.nplike.reshape( - out[: self._backend.nplike.shape_item_as_index(self._length * self._size)], - shape, - ) + # As our array-of-strings _may_ be empty, we should pass the dtype + dtype = np.str_ if array_param == "string" else np.bytes_ + return backend.nplike.asarray(self.to_list(), dtype=dtype) + else: + out = self._content._to_backend_array(allow_missing, backend) + shape = (self._length, self._size) + out.shape[1:] + + # ShapeItem is a defined type, but some nplikes don't map onto the entire space; e.g. + # NumPy never has `None` shape items. We require that if a shape-item is used between nplikes + # they both be the same "known-shape-ness". + assert ( + self._backend.index_nplike.known_data == self._backend.nplike.known_data + ) + return self._backend.nplike.reshape( + out[ + : self._backend.nplike.shape_item_as_index( + self._length * self._size + ) + ], + shape, + ) def _to_arrow(self, pyarrow, mask_node, validbytes, length, options): assert self._backend.nplike.known_data @@ -1297,7 +1330,7 @@ def _remove_structure(self, backend, options): else: return contents - def _drop_none(self): + def _drop_none(self) -> Content: return self.to_ListOffsetArray64()._drop_none() def _recursively_apply( @@ -1432,5 +1465,5 @@ def _to_backend(self, backend: Backend) -> Self: def _is_equal_to(self, other, index_dtype, numpyarray): return self._size == other.size and self._content.is_equal_to( - self._content, index_dtype, numpyarray + other._content, index_dtype, numpyarray ) diff --git a/src/awkward/contents/unionarray.py b/src/awkward/contents/unionarray.py index 06c198bc52..785a36f9db 100644 --- a/src/awkward/contents/unionarray.py +++ b/src/awkward/contents/unionarray.py @@ -4,22 +4,24 @@ import copy import ctypes -from collections.abc import Iterable, Sequence +from collections.abc import Iterable, MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend +from awkward._errors import AxisError from awkward._layout import maybe_posaxis from awkward._nplikes.jax import Jax from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata -from awkward._nplikes.shape import unknown_length +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._nplikes.typetracer import OneOf, TypeTracer from awkward._parameters import parameters_intersect, parameters_union from awkward._regularize import is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content +from awkward.forms.form import Form from awkward.forms.unionform import UnionForm from awkward.index import Index, Index8, Index64 @@ -116,6 +118,8 @@ def __init__(self, tags, index, contents, *, parameters=None): if len(contents) < 2: raise TypeError(f"{type(self).__name__} must have at least 2 'contents'") + + n_seen_options = 0 for content in contents: if not isinstance(content, Content): raise TypeError( @@ -129,6 +133,14 @@ def __init__(self, tags, index, contents, *, parameters=None): type(self).__name__, type(content).__name__ ) ) + elif content.is_option: + n_seen_options += 1 + + if n_seen_options not in {0, len(contents)}: + raise TypeError( + "{0} must either be comprised of entirely optional contents, or no optional contents; " + "try {0}.simplified instead".format(type(self).__name__) + ) if ( not (tags.length is unknown_length or index.length is unknown_length) @@ -177,17 +189,17 @@ def contents(self): def copy( self, - tags=unset, - index=unset, - contents=unset, + tags=UNSET, + index=UNSET, + contents=UNSET, *, - parameters=unset, + parameters=UNSET, ): return UnionArray( - self._tags if tags is unset else tags, - self._index if index is unset else index, - self._contents if contents is unset else contents, - parameters=self._parameters if parameters is unset else parameters, + self._tags if tags is UNSET else tags, + self._index if index is UNSET else index, + self._contents if contents is UNSET else contents, + parameters=self._parameters if parameters is UNSET else parameters, ) def __copy__(self): @@ -256,7 +268,7 @@ def simplified( for k in range(len(contents)): # Try and merge inner union content with running outer-union contentca if merge and contents[k]._mergeable_next(inner_cont, mergebool): - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_UnionArray_simplify", tags.dtype.type, @@ -285,7 +297,7 @@ def simplified( # Did we fail to merge any of the final outer contents with this inner union content? if unmerged: - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_UnionArray_simplify", tags.dtype.type, @@ -314,7 +326,7 @@ def simplified( unmerged = True for k in range(len(contents)): if contents[k] is self_cont: - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_UnionArray_simplify_one", tags.dtype.type, @@ -336,7 +348,7 @@ def simplified( break elif merge and contents[k]._mergeable_next(self_cont, mergebool): - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_UnionArray_simplify_one", tags.dtype.type, @@ -359,7 +371,7 @@ def simplified( break if unmerged: - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_UnionArray_simplify_one", tags.dtype.type, @@ -384,6 +396,17 @@ def simplified( "FIXME: handle UnionArray with more than 127 contents" ) + # If any contents are options, ensure all contents are options! + if any(c.is_option for c in contents): + contents = [ + c + if c.is_option + else c.to_IndexedOptionArray64() + if c.is_indexed + else ak.contents.UnmaskedArray(c) + for c in contents + ] + if len(contents) == 1: next = contents[0]._carry(index, True) return next.copy(parameters=parameters_union(next._parameters, parameters)) @@ -399,7 +422,7 @@ def simplified( def content(self, index): return self._contents[index] - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> UnionForm: form_key = getkey(self) return self.form_cls( self._tags.form, @@ -409,7 +432,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) key1 = getkey(self, form, "tags") key2 = getkey(self, form, "index") @@ -432,24 +462,22 @@ def _to_typetracer(self, forget_length: bool) -> Self: parameters=self._parameters, ) - def _touch_data(self, recursive): - if not self._backend.index_nplike.known_data: - self._tags.data.touch_data() - self._index.data.touch_data() + def _touch_data(self, recursive: bool): + self._tags._touch_data() + self._index._touch_data() if recursive: for x in self._contents: x._touch_data(recursive) - def _touch_shape(self, recursive): - if not self._backend.index_nplike.known_data: - self._tags.data.touch_shape() - self._index.data.touch_shape() + def _touch_shape(self, recursive: bool): + self._tags._touch_shape() + self._index._touch_shape() if recursive: for x in self._contents: x._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._tags.length def __repr__(self): @@ -465,7 +493,7 @@ def _repr(self, indent, pre, post): out.append(self._index._repr(indent + " ", "", "\n")) for i, x in enumerate(self._contents): - out.append(f"{indent} \n") + out.append(f"{indent} \n") out.append(x._repr(indent + " ", "", "\n")) out.append(f"{indent} \n") @@ -625,7 +653,7 @@ def project(self, index): and self._tags.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_project", lenout.dtype.type, @@ -660,7 +688,7 @@ def regular_index( assert ( _size.nplike is backend.index_nplike and tags.nplike is backend.index_nplike ) - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_UnionArray_regular_index_getsize", _size.dtype.type, @@ -679,7 +707,7 @@ def regular_index( and current.nplike is backend.index_nplike and tags.nplike is backend.index_nplike ) - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_UnionArray_regular_index", outindex.dtype.type, @@ -729,7 +757,7 @@ def nested_tags_index( and f_offsets.nplike is index_nplike and count.nplike is index_nplike ) - Content._selfless_handle_error( + backend.maybe_kernel_error( backend[ "awkward_UnionArray_nestedfill_tags_index", tags.dtype.type, @@ -758,7 +786,9 @@ def _getitem_next_jagged_generic(self, slicestarts, slicestops, slicecontent, ta ) return self._getitem_next_jagged(slicestarts, slicestops, slicecontent, tail) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: return self._getitem_next_jagged_generic( slicestarts, slicestops, slicecontent, tail ) @@ -806,11 +836,11 @@ def _getitem_next( else: raise AssertionError(repr(head)) - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 == depth: - raise np.AxisError("axis=0 not allowed for flatten") + raise AxisError("axis=0 not allowed for flatten") else: has_offsets = False @@ -836,7 +866,7 @@ def _offsets_and_flattened(self, axis, depth): and self._tags.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_flatten_length", total_length.dtype.type, @@ -871,7 +901,7 @@ def _offsets_and_flattened(self, axis, depth): and self._tags.nplike is self._backend.index_nplike and self._index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_flatten_combine", totags.dtype.type, @@ -919,7 +949,7 @@ def _offsets_and_flattened(self, axis, depth): ), ) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: return True def _merging_strategy(self, others): @@ -963,7 +993,7 @@ def _reverse_merge(self, other): contents.extend(self.contents) assert tags.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend["awkward_UnionArray_filltags_const", tags.dtype.type]( tags.data, 0, @@ -973,7 +1003,7 @@ def _reverse_merge(self, other): ) assert index.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend["awkward_UnionArray_fillindex_count", index.dtype.type]( index.data, 0, @@ -985,7 +1015,7 @@ def _reverse_merge(self, other): tags.nplike is self._backend.index_nplike and self.tags.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_filltags", tags.dtype.type, @@ -1003,7 +1033,7 @@ def _reverse_merge(self, other): index.nplike is self._backend.index_nplike and self.index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_fillindex", index.dtype.type, @@ -1023,7 +1053,7 @@ def _reverse_merge(self, other): tags, index, contents, parameters=self._parameters ) - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -1057,7 +1087,7 @@ def _mergemany(self, others): nexttags.nplike is self._backend.index_nplike and union_tags.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_filltags", nexttags.dtype.type, @@ -1074,7 +1104,7 @@ def _mergemany(self, others): nextindex.nplike is self._backend.index_nplike and union_index.nplike is self._backend.index_nplike ) - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_fillindex", nextindex.dtype.type, @@ -1092,7 +1122,7 @@ def _mergemany(self, others): else: assert nexttags.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_filltags_const", nexttags.dtype.type, @@ -1105,7 +1135,7 @@ def _mergemany(self, others): ) assert nextindex.nplike is self._backend.index_nplike - self._handle_error( + self._backend.maybe_kernel_error( self._backend[ "awkward_UnionArray_fillindex_count", nextindex.dtype.type ](nextindex.data, length_so_far, array.length) @@ -1582,7 +1612,7 @@ def _to_backend(self, backend: Backend) -> Self: def _is_equal_to(self, other, index_dtype, numpyarray): return ( - self.tags == other.tags + self.tags.is_equal_to(other.tags) and self.index.is_equal_to(other.index, index_dtype, numpyarray) and len(self.contents) == len(other.contents) and all( diff --git a/src/awkward/contents/unmaskedarray.py b/src/awkward/contents/unmaskedarray.py index 42dea971ca..3edf1da428 100644 --- a/src/awkward/contents/unmaskedarray.py +++ b/src/awkward/contents/unmaskedarray.py @@ -3,12 +3,15 @@ import copy import math +from collections.abc import MutableMapping, Sequence import awkward as ak from awkward._backends.backend import Backend +from awkward._errors import AxisError from awkward._layout import maybe_posaxis from awkward._nplikes.numpy import Numpy -from awkward._nplikes.numpylike import IndexType, NumpyMetadata +from awkward._nplikes.numpylike import ArrayLike, IndexType, NumpyMetadata +from awkward._nplikes.shape import ShapeItem from awkward._nplikes.typetracer import MaybeNone from awkward._parameters import ( parameters_intersect, @@ -17,14 +20,16 @@ ) from awkward._regularize import is_integer_like from awkward._slicing import NO_HEAD -from awkward._typing import TYPE_CHECKING, Final, Self, SupportsIndex, final -from awkward._util import unset +from awkward._typing import TYPE_CHECKING, Callable, Final, Self, SupportsIndex, final +from awkward._util import UNSET from awkward.contents.content import Content +from awkward.forms.form import Form from awkward.forms.unmaskedform import UnmaskedForm from awkward.index import Index if TYPE_CHECKING: from awkward._slicing import SliceItem + from awkward.contents import IndexedOptionArray np = NumpyMetadata.instance() numpy = Numpy.instance() @@ -83,15 +88,15 @@ def __init__(self, content, *, parameters=None): self._init(parameters, content.backend) @property - def content(self): + def content(self) -> Content: return self._content form_cls: Final = UnmaskedForm - def copy(self, content=unset, *, parameters=unset): + def copy(self, content=UNSET, *, parameters=UNSET): return UnmaskedArray( - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, ) def __copy__(self): @@ -117,7 +122,7 @@ def simplified(cls, content, *, parameters=None): else: return cls(content, parameters=parameters) - def _form_with_key(self, getkey): + def _form_with_key(self, getkey: Callable[[Content], str | None]) -> UnmaskedForm: form_key = getkey(self) return self.form_cls( self._content._form_with_key(getkey), @@ -125,7 +130,14 @@ def _form_with_key(self, getkey): form_key=form_key, ) - def _to_buffers(self, form, getkey, container, backend, byteorder): + def _to_buffers( + self, + form: Form, + getkey: Callable[[Content, Form, str], str], + container: MutableMapping[str, ArrayLike], + backend: Backend, + byteorder: str, + ): assert isinstance(form, self.form_cls) self._content._to_buffers(form.content, getkey, container, backend, byteorder) @@ -135,16 +147,16 @@ def _to_typetracer(self, forget_length: bool) -> Self: parameters=self._parameters, ) - def _touch_data(self, recursive): + def _touch_data(self, recursive: bool): if recursive: self._content._touch_data(recursive) - def _touch_shape(self, recursive): + def _touch_shape(self, recursive: bool): if recursive: self._content._touch_shape(recursive) @property - def length(self): + def length(self) -> ShapeItem: return self._content.length def __repr__(self): @@ -161,7 +173,7 @@ def _repr(self, indent, pre, post): out.append(post) return "".join(out) - def to_IndexedOptionArray64(self): + def to_IndexedOptionArray64(self) -> IndexedOptionArray: arange = self._backend.index_nplike.arange(self._content.length, dtype=np.int64) return ak.contents.IndexedOptionArray( ak.index.Index64(arange, nplike=self._backend.index_nplike), @@ -245,7 +257,9 @@ def _carry(self, carry: Index, allow_lazy: bool) -> Content: self._content._carry(carry, allow_lazy), parameters=self._parameters ) - def _getitem_next_jagged(self, slicestarts, slicestops, slicecontent, tail): + def _getitem_next_jagged( + self, slicestarts: Index, slicestops: Index, slicecontent: Content, tail + ) -> Content: return UnmaskedArray( self._content._getitem_next_jagged( slicestarts, slicestops, slicecontent, tail @@ -296,10 +310,10 @@ def project(self, mask=None): else: return self._content - def _offsets_and_flattened(self, axis, depth): + def _offsets_and_flattened(self, axis: int, depth: int) -> tuple[Index, Content]: posaxis = maybe_posaxis(self, axis, depth) if posaxis is not None and posaxis + 1 == depth: - raise np.AxisError("axis=0 not allowed for flatten") + raise AxisError("axis=0 not allowed for flatten") else: offsets, flattened = self._content._offsets_and_flattened(axis, depth) if offsets.length == 0: @@ -311,7 +325,7 @@ def _offsets_and_flattened(self, axis, depth): else: return (offsets, flattened) - def _mergeable_next(self, other, mergebool): + def _mergeable_next(self, other: Content, mergebool: bool) -> bool: # Is the other content is an identity, or a union? if other.is_identity_like or other.is_union: return True @@ -326,7 +340,7 @@ def _mergeable_next(self, other, mergebool): def _reverse_merge(self, other): return self.to_IndexedOptionArray64()._reverse_merge(other) - def _mergemany(self, others): + def _mergemany(self, others: Sequence[Content]) -> Content: if len(others) == 0: return self @@ -476,7 +490,7 @@ def _remove_structure(self, backend, options): else: return [self] - def _drop_none(self): + def _drop_none(self) -> Content: return self.to_ByteMaskedArray(True)._drop_none() def _recursively_apply( diff --git a/src/awkward/forms/__init__.py b/src/awkward/forms/__init__.py index ed19ec1066..378b84d515 100644 --- a/src/awkward/forms/__init__.py +++ b/src/awkward/forms/__init__.py @@ -3,7 +3,7 @@ from awkward.forms.bitmaskedform import BitMaskedForm # noqa: F401 from awkward.forms.bytemaskedform import ByteMaskedForm # noqa: F401 from awkward.forms.emptyform import EmptyForm # noqa: F401 -from awkward.forms.form import Form, from_dict, from_json # noqa: F401 +from awkward.forms.form import Form, from_dict, from_json, from_type # noqa: F401 from awkward.forms.indexedform import IndexedForm # noqa: F401 from awkward.forms.indexedoptionform import IndexedOptionForm # noqa: F401 from awkward.forms.listform import ListForm # noqa: F401 diff --git a/src/awkward/forms/bitmaskedform.py b/src/awkward/forms/bitmaskedform.py index 5aa33c75e8..4dbc551451 100644 --- a/src/awkward/forms/bitmaskedform.py +++ b/src/awkward/forms/bitmaskedform.py @@ -1,9 +1,8 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE import awkward as ak -from awkward._behavior import find_typestr from awkward._parameters import type_parameters_equal from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form @@ -70,21 +69,21 @@ def lsb_order(self): def copy( self, - mask=unset, - content=unset, - valid_when=unset, - lsb_order=unset, + mask=UNSET, + content=UNSET, + valid_when=UNSET, + lsb_order=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return BitMaskedForm( - self._mask if mask is unset else mask, - self._content if content is unset else content, - self._valid_when if valid_when is unset else valid_when, - self._lsb_order if lsb_order is unset else lsb_order, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._mask if mask is UNSET else mask, + self._content if content is UNSET else content, + self._valid_when if valid_when is UNSET else valid_when, + self._lsb_order if lsb_order is UNSET else lsb_order, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -142,11 +141,10 @@ def _to_dict_part(self, verbose, toplevel): verbose, ) - def _type(self, typestrs): + @property + def type(self): return ak.types.OptionType( - self._content._type(typestrs), - parameters=self._parameters, - typestr=find_typestr(self._parameters, typestrs), + self._content.type, parameters=self._parameters ).simplify_option_union() def __eq__(self, other): diff --git a/src/awkward/forms/bytemaskedform.py b/src/awkward/forms/bytemaskedform.py index 514d370fac..90147b0b15 100644 --- a/src/awkward/forms/bytemaskedform.py +++ b/src/awkward/forms/bytemaskedform.py @@ -1,9 +1,8 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE import awkward as ak -from awkward._behavior import find_typestr from awkward._parameters import type_parameters_equal from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form @@ -58,19 +57,19 @@ def valid_when(self): def copy( self, - mask=unset, - content=unset, - valid_when=unset, + mask=UNSET, + content=UNSET, + valid_when=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return ByteMaskedForm( - self._mask if mask is unset else mask, - self._content if content is unset else content, - self._valid_when if valid_when is unset else valid_when, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._mask if mask is UNSET else mask, + self._content if content is UNSET else content, + self._valid_when if valid_when is UNSET else valid_when, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -120,11 +119,10 @@ def _to_dict_part(self, verbose, toplevel): verbose, ) - def _type(self, typestrs): + @property + def type(self): return ak.types.OptionType( - self._content._type(typestrs), - parameters=self._parameters, - typestr=find_typestr(self._parameters, typestrs), + self._content.type, parameters=self._parameters ).simplify_option_union() def __eq__(self, other): diff --git a/src/awkward/forms/emptyform.py b/src/awkward/forms/emptyform.py index 2576ae6afe..7be425f3cf 100644 --- a/src/awkward/forms/emptyform.py +++ b/src/awkward/forms/emptyform.py @@ -1,11 +1,13 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE from __future__ import annotations +from inspect import signature + import awkward as ak -from awkward._behavior import find_typestr from awkward._errors import deprecate -from awkward._typing import final -from awkward._util import unset +from awkward._nplikes.shape import ShapeItem +from awkward._typing import Iterator, final +from awkward._util import UNSET from awkward.forms.form import Form, JSONMapping @@ -22,15 +24,15 @@ def __init__(self, *, parameters: JSONMapping | None = None, form_key=None): self._init(parameters=parameters, form_key=form_key) def copy( - self, *, parameters: JSONMapping | None = unset, form_key=unset + self, *, parameters: JSONMapping | None = UNSET, form_key=UNSET ) -> EmptyForm: - if not (parameters is unset or parameters is None or len(parameters) == 0): + if not (parameters is UNSET or parameters is None or len(parameters) == 0): deprecate( f"{type(self).__name__} cannot contain parameters", version="2.2.0" ) return EmptyForm( - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -46,17 +48,41 @@ def __repr__(self): def _to_dict_part(self, verbose, toplevel): return self._to_dict_extra({"class": "EmptyArray"}, verbose) - def _type(self, typestrs): - return ak.types.UnknownType( - parameters=self._parameters, - typestr=find_typestr(self._parameters, typestrs), - ) + @property + def type(self): + return ak.types.UnknownType(parameters=self._parameters) def __eq__(self, other) -> bool: return isinstance(other, EmptyForm) and self._form_key == other._form_key - def to_NumpyForm(self, dtype): - return ak.forms.numpyform.from_dtype(dtype, parameters=self._parameters) + def to_NumpyForm(self, *args, **kwargs): + def legacy_impl(dtype): + deprecate( + f"the `dtype` parameter in {type(self).__name__}.to_NumpyForm is deprecated, " + f"in favour of a new `primitive` argument. Pass `primitive` by keyword to opt-in to the new behavior.", + version="2.4.0", + ) + return ak.forms.numpyform.from_dtype(dtype, parameters=self._parameters) + + def new_impl(*, primitive): + return ak.forms.numpyform.NumpyForm(primitive, parameters=self._parameters) + + dispatch_table = [ + new_impl, + legacy_impl, + ] + for func in dispatch_table: + sig = signature(func) + try: + bound_arguments = sig.bind(*args, **kwargs) + except TypeError: + continue + else: + return func(*bound_arguments.args, **bound_arguments.kwargs) + raise AssertionError( + f"{type(self).__name__}.to_NumpyForm accepts either the new `primitive` argument as a keyword-only " + f"argument, or the legacy `dtype` argument as positional or keyword" + ) def purelist_parameter(self, key): if self._parameters is None or key not in self._parameters: @@ -106,3 +132,6 @@ def _select_columns(self, index, specifier, matches, output): def _column_types(self) -> tuple[str, ...]: return ("empty",) + + def _length_one_buffer_lengths(self) -> Iterator[ShapeItem]: + yield 0 diff --git a/src/awkward/forms/form.py b/src/awkward/forms/form.py index 323345267a..d73296479d 100644 --- a/src/awkward/forms/form.py +++ b/src/awkward/forms/form.py @@ -8,9 +8,10 @@ import awkward as ak from awkward._backends.numpy import NumpyBackend -from awkward._behavior import find_typestrs +from awkward._errors import deprecate from awkward._nplikes.numpylike import NumpyMetadata -from awkward._nplikes.shape import unknown_length +from awkward._nplikes.shape import ShapeItem, unknown_length +from awkward._parameters import parameters_union from awkward._typing import Final, JSONMapping, JSONSerializable np = NumpyMetadata.instance() @@ -181,6 +182,73 @@ def from_json(input: str) -> Form: return from_dict(json.loads(input)) +def from_type(type_: ak.types.Type) -> Form: + # Categorical types are reintroduced into forms using metadata + if type_.parameter("__categorical__"): + # Drop categorical placeholder parameter + if type_._parameters is None: + next_parameters = None + else: + next_parameters = type_._parameters.copy() + next_parameters.pop("__categorical__") + + if isinstance(type_, ak.types.OptionType): + next_content = from_type(type_.content) + return ak.forms.IndexedOptionForm( + "i64", + next_content, + parameters=parameters_union( + next_parameters, {"__array__": "categorical"} + ), + ) + else: + next_content = from_type(type_.copy(parameters=next_parameters)) + return ak.forms.IndexedForm( + "i64", next_content, parameters={"__array__": "categorical"} + ) + + if isinstance(type_, ak.types.NumpyType): + return ak.forms.NumpyForm(type_.primitive, parameters=type_._parameters) + elif isinstance(type_, ak.types.ListType): + return ak.forms.ListOffsetForm( + "i64", from_type(type_.content), parameters=type_._parameters + ) + elif isinstance(type_, ak.types.RegularType): + return ak.forms.RegularForm( + from_type(type_.content), + size=type_.size, + parameters=type_._parameters, + ) + elif isinstance(type_, ak.types.OptionType): + return ak.forms.IndexedOptionForm( + "i64", + from_type(type_.content), + parameters=type_._parameters, + ) + elif isinstance(type_, ak.types.RecordType): + return ak.forms.RecordForm( + [from_type(c) for c in type_.contents], + type_.fields, + parameters=type_._parameters, + ) + elif isinstance(type_, ak.types.UnionType): + return ak.forms.UnionForm( + "i8", + "i64", + [from_type(c) for c in type_.contents], + parameters=type_._parameters, + ) + elif isinstance(type_, ak.types.UnknownType): + return ak.forms.EmptyForm(parameters=type_._parameters) + elif isinstance(type_, (ak.types.ArrayType, ak.types.ScalarType)): + raise TypeError( + "High-level types (ak.types.ArrayType, ak.types.ScalarType) do not have representations as Awkward forms. " + "Instead the low level type should be used." + ) + else: + raise TypeError(f"unsupported type {type_!r}") + + def _expand_braces(text, seen=None): if seen is None: seen = set() @@ -308,10 +376,17 @@ def _repr_args(self): @property def type(self): - return self._type({}) + raise NotImplementedError def type_from_behavior(self, behavior): - return self._type(find_typestrs(behavior)) + deprecate( + "low level types produced by forms do not hold references to behaviors. " + "Use a high-level type (e.g. ak.types.ArrayType or ak.types.ScalarType) to" + "associate a type with behavior information, or simply access the low-level" + "type from Form.type", + version="2.4.0", + ) + return self.type def columns(self, list_indicator=None, column_prefix=()): output = [] @@ -356,12 +431,15 @@ def _column_types(self): def _to_dict_part(self, verbose, toplevel): raise NotImplementedError - def _type(self, typestrs): - raise NotImplementedError - def length_zero_array( self, *, backend=numpy_backend, highlevel=True, behavior=None ): + if highlevel: + deprecate( + "The `highlevel=True` variant of `Form.length_zero_array` is now deprecated. " + "Please use `ak.Array(form.length_zero_array(...), behavior=...)` if an `ak.Array` is required.", + version="2.3.0", + ) return ak.operations.ak_from_buffers._impl( form=self, length=0, @@ -375,19 +453,99 @@ def length_zero_array( ) def length_one_array(self, *, backend=numpy_backend, highlevel=True, behavior=None): - # A length-1 array will need at least N bytes, where N is the largest dtype (e.g. 256 bit complex) - # Similarly, a length-1 array will need no more than 2*N bytes, as all contents need at most two - # index-types e.g. `ListOffsetArray.offsets` for their various index metadata. Therefore, we - # create a buffer of this length (2N) and instruct all contents to use it (via `buffer_key=""`). - # At the same time, with all index-like metadata set to 0, the list types will have zero lengths - # whilst unions, indexed, and option types will contain a single value. + # The naive implementation of a length-1 array requires that we have a sufficiently + # large buffer to be able to build _any_ subtree. + def max_prefer_unknown(this: ShapeItem, that: ShapeItem) -> ShapeItem: + if this is unknown_length: + return this + if that is unknown_length: + return that + return max(this, that) + + container = {} + + def prepare(form, multiplier): + form_key = f"node-{len(container)}" + + if isinstance(form, (ak.forms.BitMaskedForm, ak.forms.ByteMaskedForm)): + if form.valid_when: + container[form_key] = b"\x00" * multiplier + else: + container[form_key] = b"\xff" * multiplier + return form.copy(form_key=form_key) # DO NOT RECURSE + + elif isinstance(form, ak.forms.IndexedOptionForm): + container[form_key] = b"\xff\xff\xff\xff\xff\xff\xff\xff" # -1 + return form.copy(form_key=form_key) # DO NOT RECURSE + + elif isinstance(form, ak.forms.EmptyForm): + # no error if protected by non-recursing node type + raise TypeError( + "cannot generate a length_one_array from a Form with an " + "unknowntype that cannot be hidden (EmptyForm not within " + "BitMaskedForm, ByteMaskedForm, or IndexedOptionForm)" + ) + + elif isinstance(form, ak.forms.UnmaskedForm): + return form.copy(content=prepare(form.content, multiplier)) + + elif isinstance(form, (ak.forms.IndexedForm, ak.forms.ListForm)): + container[form_key] = b"\x00" * (8 * multiplier) + return form.copy( + content=prepare(form.content, multiplier), form_key=form_key + ) + + elif isinstance(form, ak.forms.ListOffsetForm): + # offsets length == array length + 1 + container[form_key] = b"\x00" * (8 * (multiplier + 1)) + return form.copy( + content=prepare(form.content, multiplier), form_key=form_key + ) + + elif isinstance(form, ak.forms.RegularForm): + size = form.size + + # https://github.com/scikit-hep/awkward/pull/2499#discussion_r1220503454 + if size is unknown_length: + size = 1 + + return form.copy(content=prepare(form.content, multiplier * size)) + + elif isinstance(form, ak.forms.NumpyForm): + dtype = ak.types.numpytype.primitive_to_dtype(form._primitive) + size = multiplier * dtype.itemsize + for x in form.inner_shape: + if x is not unknown_length: + size *= x + + container[form_key] = b"\x00" * size + return form.copy(form_key=form_key) + + elif isinstance(form, ak.forms.RecordForm): + return form.copy( + # recurse down all contents + contents=[prepare(x, multiplier) for x in form.contents] + ) + + elif isinstance(form, ak.forms.UnionForm): + # both tags and index will get this buffer, but index is 8 bytes + container[form_key] = b"\x00" * (8 * multiplier) + return form.copy( + # only recurse down contents[0] because all index == 0 + contents=( + [prepare(form.contents[0], multiplier)] + form.contents[1:] + ), + form_key=form_key, + ) + + else: + raise AssertionError(f"not a Form: {form!r}") + return ak.operations.ak_from_buffers._impl( - form=self, + form=prepare(self, 1), length=1, - container={ - "": b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - }, - buffer_key="", + container=container, + buffer_key="{form_key}", backend=backend, byteorder=ak._util.native_byteorder, highlevel=highlevel, diff --git a/src/awkward/forms/indexedform.py b/src/awkward/forms/indexedform.py index dda45ba71f..260ce63eb9 100644 --- a/src/awkward/forms/indexedform.py +++ b/src/awkward/forms/indexedform.py @@ -3,7 +3,7 @@ import awkward as ak from awkward._parameters import parameters_union, type_parameters_equal from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form @@ -46,17 +46,17 @@ def content(self): def copy( self, - index=unset, - content=unset, + index=UNSET, + content=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return IndexedForm( - self._index if index is unset else index, - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._index if index is UNSET else index, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -106,8 +106,9 @@ def _to_dict_part(self, verbose, toplevel): verbose, ) - def _type(self, typestrs): - out = self._content._type(typestrs) + @property + def type(self): + out = self._content.type if self._parameters is not None: if out._parameters is None: diff --git a/src/awkward/forms/indexedoptionform.py b/src/awkward/forms/indexedoptionform.py index 26253ed56f..fcc37b2b4d 100644 --- a/src/awkward/forms/indexedoptionform.py +++ b/src/awkward/forms/indexedoptionform.py @@ -1,9 +1,8 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE import awkward as ak -from awkward._behavior import find_typestr from awkward._parameters import parameters_union, type_parameters_equal from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form @@ -47,17 +46,17 @@ def content(self): def copy( self, - index=unset, - content=unset, + index=UNSET, + content=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return IndexedOptionForm( - self._index if index is unset else index, - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._index if index is UNSET else index, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -98,7 +97,8 @@ def _to_dict_part(self, verbose, toplevel): verbose, ) - def _type(self, typestrs): + @property + def type(self): if self.parameter("__array__") == "categorical": parameters = dict(self._parameters) del parameters["__array__"] @@ -107,9 +107,8 @@ def _type(self, typestrs): parameters = self._parameters return ak.types.OptionType( - self._content._type(typestrs), + self._content.type, parameters=parameters, - typestr=find_typestr(self._parameters, typestrs), ).simplify_option_union() def __eq__(self, other): diff --git a/src/awkward/forms/listform.py b/src/awkward/forms/listform.py index 40017d90ca..ce9ce6c30d 100644 --- a/src/awkward/forms/listform.py +++ b/src/awkward/forms/listform.py @@ -1,9 +1,8 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE import awkward as ak -from awkward._behavior import find_typestr from awkward._parameters import type_parameters_equal from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form @@ -58,19 +57,19 @@ def content(self): def copy( self, - starts=unset, - stops=unset, - content=unset, + starts=UNSET, + stops=UNSET, + content=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return ListForm( - self._starts if starts is unset else starts, - self._stops if stops is unset else stops, - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._starts if starts is UNSET else starts, + self._stops if stops is UNSET else stops, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -105,11 +104,11 @@ def _to_dict_part(self, verbose, toplevel): verbose, ) - def _type(self, typestrs): + @property + def type(self): return ak.types.ListType( - self._content._type(typestrs), + self._content.type, parameters=self._parameters, - typestr=find_typestr(self._parameters, typestrs), ) def __eq__(self, other): diff --git a/src/awkward/forms/listoffsetform.py b/src/awkward/forms/listoffsetform.py index df59901053..98a66be299 100644 --- a/src/awkward/forms/listoffsetform.py +++ b/src/awkward/forms/listoffsetform.py @@ -1,9 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations + import awkward as ak -from awkward._behavior import find_typestr from awkward._parameters import type_parameters_equal -from awkward._typing import final -from awkward._util import unset +from awkward._typing import JSONMapping, final +from awkward._util import UNSET from awkward.forms.form import Form @@ -11,7 +12,14 @@ class ListOffsetForm(Form): is_list = True - def __init__(self, offsets, content, *, parameters=None, form_key=None): + def __init__( + self, + offsets: str, + content: Form, + *, + parameters: JSONMapping | None = None, + form_key: str | None = None, + ): if not isinstance(offsets, str): raise TypeError( "{} 'offsets' must be of type str, not {}".format( @@ -33,17 +41,17 @@ def content(self): def copy( self, - offsets=unset, - content=unset, + offsets=UNSET, + content=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return ListOffsetForm( - self._offsets if offsets is unset else offsets, - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._offsets if offsets is UNSET else offsets, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -64,11 +72,11 @@ def _to_dict_part(self, verbose, toplevel): verbose, ) - def _type(self, typestrs): + @property + def type(self): return ak.types.ListType( - self._content._type(typestrs), + self._content.type, parameters=self._parameters, - typestr=find_typestr(self._parameters, typestrs), ) def __eq__(self, other): diff --git a/src/awkward/forms/numpyform.py b/src/awkward/forms/numpyform.py index 7b811eb51e..27c35a31c1 100644 --- a/src/awkward/forms/numpyform.py +++ b/src/awkward/forms/numpyform.py @@ -2,24 +2,36 @@ from collections.abc import Iterable import awkward as ak -from awkward._behavior import find_typestr +from awkward._errors import deprecate from awkward._nplikes.numpylike import NumpyMetadata from awkward._parameters import type_parameters_equal from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form np = NumpyMetadata.instance() -def from_dtype(dtype, parameters=None): +def from_dtype(dtype, parameters=None, *, time_units_as_parameter: bool = UNSET): if dtype.subdtype is None: inner_shape = () else: inner_shape = dtype.shape dtype = dtype.subdtype[0] - if issubclass(dtype.type, (np.datetime64, np.timedelta64)): + if time_units_as_parameter is UNSET: + time_units_as_parameter = True + + if time_units_as_parameter: + deprecate( + "from_dtype conversion of temporal units to generic `datetime64` and `timedelta64` types is deprecated, " + "pass `time_units_as_parameter=False` to disable this warning.", + version="2.4.0", + ) + + if time_units_as_parameter and issubclass( + dtype.type, (np.datetime64, np.timedelta64) + ): unit, step = np.datetime_data(dtype) if unit != "generic": unitstr = ("" if step == 1 else str(step)) + unit @@ -73,17 +85,17 @@ def inner_shape(self): def copy( self, - primitive=unset, - inner_shape=unset, + primitive=UNSET, + inner_shape=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return NumpyForm( - self._primitive if primitive is unset else primitive, - self._inner_shape if inner_shape is unset else inner_shape, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._primitive if primitive is UNSET else primitive, + self._inner_shape if inner_shape is UNSET else inner_shape, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -127,11 +139,11 @@ def _to_dict_part(self, verbose, toplevel): out["inner_shape"] = list(self._inner_shape) return self._to_dict_extra(out, verbose) - def _type(self, typestrs): + @property + def type(self): out = ak.types.NumpyType( self._primitive, parameters=None, - typestr=find_typestr(self._parameters, typestrs), ) for x in self._inner_shape[::-1]: out = ak.types.RegularType(out, x) diff --git a/src/awkward/forms/recordform.py b/src/awkward/forms/recordform.py index 20c944be7e..cb9280e476 100644 --- a/src/awkward/forms/recordform.py +++ b/src/awkward/forms/recordform.py @@ -3,11 +3,10 @@ from collections.abc import Iterable import awkward as ak -from awkward._behavior import find_typestr from awkward._parameters import type_parameters_equal from awkward._regularize import is_integer from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form @@ -60,17 +59,17 @@ def fields(self): def copy( self, - contents=unset, - fields=unset, + contents=UNSET, + fields=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return RecordForm( - self._contents if contents is unset else contents, - self._fields if fields is unset else fields, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._contents if contents is UNSET else contents, + self._fields if fields is UNSET else fields, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -165,12 +164,12 @@ def _to_dict_part(self, verbose, toplevel): out["contents"] = contents_tolist return self._to_dict_extra(out, verbose) - def _type(self, typestrs): + @property + def type(self): return ak.types.RecordType( - [x._type(typestrs) for x in self._contents], + [x.type for x in self._contents], self._fields, parameters=self._parameters, - typestr=find_typestr(self._parameters, typestrs), ) def __eq__(self, other): diff --git a/src/awkward/forms/regularform.py b/src/awkward/forms/regularform.py index 3d0af9f887..81fae833fd 100644 --- a/src/awkward/forms/regularform.py +++ b/src/awkward/forms/regularform.py @@ -1,11 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE import awkward as ak -from awkward._behavior import find_typestr from awkward._nplikes.shape import unknown_length from awkward._parameters import type_parameters_equal from awkward._regularize import is_integer from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form @@ -40,12 +39,12 @@ def content(self): def size(self): return self._size - def copy(self, content=unset, size=unset, *, parameters=unset, form_key=unset): + def copy(self, content=UNSET, size=UNSET, *, parameters=UNSET, form_key=UNSET): return RegularForm( - self._content if content is unset else content, - self._size if size is unset else size, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._content if content is UNSET else content, + self._size if size is UNSET else size, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -66,12 +65,12 @@ def _to_dict_part(self, verbose, toplevel): verbose, ) - def _type(self, typestrs): + @property + def type(self): return ak.types.RegularType( - self._content._type(typestrs), + self._content.type, self._size, parameters=self._parameters, - typestr=find_typestr(self._parameters, typestrs), ) def __eq__(self, other): diff --git a/src/awkward/forms/unionform.py b/src/awkward/forms/unionform.py index d9d5d7f713..311da84399 100644 --- a/src/awkward/forms/unionform.py +++ b/src/awkward/forms/unionform.py @@ -3,10 +3,9 @@ from collections.abc import Iterable import awkward as ak -from awkward._behavior import find_typestr from awkward._parameters import type_parameters_equal from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form @@ -68,19 +67,19 @@ def contents(self): def copy( self, - tags=unset, - index=unset, - contents=unset, + tags=UNSET, + index=UNSET, + contents=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return UnionForm( - self._tags if tags is unset else tags, - self._index if index is unset else index, - self._contents if contents is unset else contents, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._tags if tags is UNSET else tags, + self._index if index is UNSET else index, + self._contents if contents is UNSET else contents, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -133,11 +132,11 @@ def _to_dict_part(self, verbose, toplevel): verbose, ) - def _type(self, typestrs): + @property + def type(self): return ak.types.UnionType( - [x._type(typestrs) for x in self._contents], + [x.type for x in self._contents], parameters=self._parameters, - typestr=find_typestr(self._parameters, typestrs), ) def __eq__(self, other): diff --git a/src/awkward/forms/unmaskedform.py b/src/awkward/forms/unmaskedform.py index 4bd64136b1..8c37326f72 100644 --- a/src/awkward/forms/unmaskedform.py +++ b/src/awkward/forms/unmaskedform.py @@ -1,9 +1,8 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE import awkward as ak -from awkward._behavior import find_typestr from awkward._parameters import parameters_union, type_parameters_equal from awkward._typing import final -from awkward._util import unset +from awkward._util import UNSET from awkward.forms.form import Form @@ -34,15 +33,15 @@ def content(self): def copy( self, - content=unset, + content=UNSET, *, - parameters=unset, - form_key=unset, + parameters=UNSET, + form_key=UNSET, ): return UnmaskedForm( - self._content if content is unset else content, - parameters=self._parameters if parameters is unset else parameters, - form_key=self._form_key if form_key is unset else form_key, + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, + form_key=self._form_key if form_key is UNSET else form_key, ) @classmethod @@ -78,11 +77,11 @@ def _to_dict_part(self, verbose, toplevel): verbose, ) - def _type(self, typestrs): + @property + def type(self): return ak.types.OptionType( - self._content._type(typestrs), + self._content.type, parameters=self._parameters, - typestr=find_typestr(self._parameters, typestrs), ).simplify_option_union() def __eq__(self, other): diff --git a/src/awkward/highlevel.py b/src/awkward/highlevel.py index f87b3ce800..ac6b4f6bb0 100644 --- a/src/awkward/highlevel.py +++ b/src/awkward/highlevel.py @@ -327,7 +327,7 @@ def __init__(self, array): def __getitem__(self, where): with ak._errors.OperationErrorContext( - "ak.Array.mask", {0: self._array, 1: where} + "ak.Array.mask", args=[self._array, where], kwargs={} ): return ak.operations.mask(self._array, where, valid_when=True) @@ -436,7 +436,9 @@ def type(self): wrapped by an #ak.types.ArrayType. """ return ak.types.ArrayType( - self._layout.form.type_from_behavior(self._behavior), self._layout.length + self._layout.form.type, + self._layout.length, + self._behavior, ) @property @@ -1016,7 +1018,8 @@ def __setitem__(self, where, what): """ with ak._errors.OperationErrorContext( "ak.Array.__setitem__", - {"self": self, "field_name": where, "field_value": what}, + (self,), + {"where": where, "what": what}, ): if not ( isinstance(where, str) @@ -1047,7 +1050,8 @@ def __delitem__(self, where): """ with ak._errors.OperationErrorContext( "ak.Array.__delitem__", - {"self": self, "field_name": where}, + (self,), + {"where": where}, ): if not ( isinstance(where, str) @@ -1279,11 +1283,7 @@ def __array__(self, *args, **kwargs): nested lists in a NumPy `"O"` array are severed from the array and cannot be sliced as dimensions. """ - arguments = {0: self} - for i, arg in enumerate(args): - arguments[i + 1] = arg - arguments.update(kwargs) - with ak._errors.OperationErrorContext("numpy.asarray", arguments): + with ak._errors.OperationErrorContext("numpy.asarray", (self, *args), kwargs): return ak._connect.numpy.convert_to_array(self._layout, args, kwargs) def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): @@ -1351,12 +1351,8 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): See also #__array_function__. """ - name = f"{type(ufunc).__module__}.{ufunc.__name__}.{str(method)}" - arguments = {} - for i, arg in enumerate(inputs): - arguments[i] = arg - arguments.update(kwargs) - with ak._errors.OperationErrorContext(name, arguments): + name = f"{type(ufunc).__module__}.{ufunc.__name__}.{method!s}" + with ak._errors.OperationErrorContext(name, inputs, kwargs): return ak._connect.numpy.array_ufunc(ufunc, method, inputs, kwargs) def __array_function__(self, func, types, args, kwargs): @@ -1713,9 +1709,7 @@ def type(self): The type of a #ak.record.Record (from #ak.Array.layout) is not wrapped by an #ak.types.ScalarType. """ - return ak.types.ScalarType( - self._layout.array.form.type_from_behavior(self._behavior) - ) + return ak.types.ScalarType(self._layout.array.form.type, self._behavior) @property def typestr(self): @@ -1787,7 +1781,8 @@ def __setitem__(self, where, what): """ with ak._errors.OperationErrorContext( "ak.Record.__setitem__", - {"self": self, "field_name": where, "field_value": what}, + (self,), + {"where": where, "what": what}, ): if not ( isinstance(where, str) @@ -1819,7 +1814,8 @@ def __delitem__(self, where): """ with ak._errors.OperationErrorContext( "ak.Record.__delitem__", - {"self": self, "field_name": where}, + (self,), + {"where": where}, ): if not ( isinstance(where, str) @@ -2029,12 +2025,8 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): See #ak.Array.__array_ufunc__ for a more complete description. """ - name = f"{type(ufunc).__module__}.{ufunc.__name__}.{str(method)}" - arguments = {} - for i, arg in enumerate(inputs): - arguments[i] = arg - arguments.update(kwargs) - with ak._errors.OperationErrorContext(name, arguments): + name = f"{type(ufunc).__module__}.{ufunc.__name__}.{method!s}" + with ak._errors.OperationErrorContext(name, inputs, kwargs): return ak._connect.numpy.array_ufunc(ufunc, method, inputs, kwargs) @property @@ -2235,7 +2227,7 @@ class ArrayBuilder(Sized): be considered the "least effort" approach. """ - def __init__(self, *, behavior=None, initial=1024, resize=1.5): + def __init__(self, *, behavior=None, initial=1024, resize=8): self._layout = _ext.ArrayBuilder(initial=initial, resize=resize) self.behavior = behavior @@ -2318,9 +2310,7 @@ def type(self): wrapped by an #ak.types.ArrayType. """ form = ak.forms.from_json(self._layout.form()) - return ak.types.ArrayType( - form.type_from_behavior(self._behavior), len(self._layout) - ) + return ak.types.ArrayType(form.type, len(self._layout), self._behavior) @property def typestr(self): @@ -2378,11 +2368,7 @@ def __array__(self, *args, **kwargs): See #ak.Array.__array__ for a more complete description. """ - arguments = {0: self} - for i, arg in enumerate(args): - arguments[i + 1] = arg - arguments.update(kwargs) - with ak._errors.OperationErrorContext("numpy.asarray", arguments): + with ak._errors.OperationErrorContext("numpy.asarray", (self, *args), kwargs): return ak._connect.numpy.convert_to_array(self.snapshot(), args, kwargs) @property @@ -2417,7 +2403,7 @@ def snapshot(self): formstr, length, container = self._layout.to_buffers() form = ak.forms.from_json(formstr) - with ak._errors.OperationErrorContext("ak.ArrayBuilder.snapshot", {}): + with ak._errors.OperationErrorContext("ak.ArrayBuilder.snapshot", [], {}): return ak.operations.ak_from_buffers._impl( form, length, diff --git a/src/awkward/index.py b/src/awkward/index.py index 2ce8898fe2..3660aad9ae 100644 --- a/src/awkward/index.py +++ b/src/awkward/index.py @@ -10,13 +10,13 @@ from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyLike, NumpyMetadata from awkward._nplikes.typetracer import TypeTracer -from awkward._typing import Self +from awkward._typing import Final, Self -np = NumpyMetadata.instance() -numpy = Numpy.instance() +np: Final = NumpyMetadata.instance() +numpy: Final = Numpy.instance() -_dtype_to_form = { +_dtype_to_form: Final = { np.dtype(np.int8): "i8", np.dtype(np.uint8): "u8", np.dtype(np.int32): "i32", @@ -24,20 +24,15 @@ np.dtype(np.int64): "i64", } +_form_to_dtype: Final = {v: k for k, v in _dtype_to_form.items()} -def _form_to_zero_length(form): - if form == "i8": - return Index8(numpy.zeros(0, dtype=np.int8)) - elif form == "u8": - return IndexU8(numpy.zeros(0, dtype=np.uint8)) - elif form == "i32": - return Index32(numpy.zeros(0, dtype=np.int32)) - elif form == "u32": - return IndexU32(numpy.zeros(0, dtype=np.uint32)) - elif form == "i64": - return Index64(numpy.zeros(0, dtype=np.int64)) - else: - raise AssertionError(f"unrecognized Index form: {form!r}") + +def _form_to_zero_length(form: str) -> Index: + try: + dtype = _form_to_dtype[form] + except KeyError: + raise AssertionError(f"unrecognized Index form: {form!r}") from None + return Index(numpy.zeros(0, dtype=dtype)) class Index: @@ -231,6 +226,14 @@ def is_equal_to(self, other, index_dtype=True, numpyarray=True): else: return self.nplike.array_equal(self.data, other.data) + def _touch_data(self): + if not self.nplike.known_data: + self._data.touch_data() + + def _touch_shape(self): + if not self.nplike.known_data: + self._data.touch_shape() + class Index8(Index): _expected_dtype = np.dtype(np.int8) diff --git a/src/awkward/numba.py b/src/awkward/numba.py index 93cb0585a7..d413d31f1b 100644 --- a/src/awkward/numba.py +++ b/src/awkward/numba.py @@ -1,5 +1,9 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +import math + +import numpy # noqa: TID251 + import awkward as ak _has_checked_version = False @@ -33,6 +37,119 @@ def register_and_check(): _register() +class GrowableBuffer: + def __init__(self, dtype, *, initial=1024, resize=8.0): + register_and_check() + + import numba + + # all mutable data are in arrays that can be in-place shared with Numba + self._panels = numba.typed.List([numpy.empty((initial,), dtype=dtype)]) + self._length_pos = numpy.zeros((2,), dtype=numpy.int64) + self._resize = resize + + @classmethod + def _from_data(cls, panels, length_pos, resize): + out = cls.__new__(cls) + out._panels = panels + out._length_pos = length_pos + out._resize = resize + return out + + @property + def dtype(self): + return self._panels[0].dtype + + def __repr__(self): + return f"" + + @property + def _length(self): + return self._length_pos[0] + + @_length.setter + def _length(self, value): + self._length_pos[0] = value + + def _length_inc(self, value): + self._length_pos[0] += value + + @property + def _pos(self): + return self._length_pos[1] + + @_pos.setter + def _pos(self, value): + self._length_pos[1] = value + + def _pos_inc(self, value): + self._length_pos[1] += value + + def __len__(self): + return self._length + + def append(self, datum): + if self._pos == len(self._panels[-1]): + self._add_panel() + + self._panels[-1][self._pos] = datum + self._pos_inc(1) + self._length_inc(1) + + def extend(self, data): + panel_index = len(self._panels) - 1 + pos = self._pos + + available = len(self._panels[-1]) - pos + remaining = len(data) + + if remaining > available: + panel_length = int(math.ceil(len(self._panels[0]) * self._resize)) + + self._panels.append( + numpy.empty((max(remaining, panel_length),), dtype=self.dtype) + ) + self._pos = 0 + available += len(self._panels[-1]) + + while remaining > 0: + panel = self._panels[panel_index] + available_in_panel = len(panel) - pos + to_write = min(remaining, available_in_panel) + + start = len(data) - remaining + panel[pos : pos + to_write] = data[start : start + to_write] + + if panel_index == len(self._panels) - 1: + self._pos_inc(to_write) + remaining -= to_write + pos = 0 + panel_index += 1 + + self._length_inc(len(data)) + + def _add_panel(self): + panel_length = int(math.ceil(len(self._panels[0]) * self._resize)) + + self._panels.append(numpy.empty((panel_length,), dtype=self.dtype)) + self._pos = 0 + + def snapshot(self): + out = numpy.empty((self._length,), dtype=self.dtype) + + start = 0 + stop = 0 + for panel in self._panels[:-1]: # full panels, not including the last + stop += len(panel) + out[start:stop] = panel + start = stop + + stop += self._pos + out[start:stop] = self._panels[-1][: self._pos] + + return out + + def _register(): if hasattr(ak.numba, "ArrayViewType"): return @@ -42,6 +159,7 @@ def _register(): import awkward._connect.numba.arrayview import awkward._connect.numba.arrayview_cuda import awkward._connect.numba.builder + import awkward._connect.numba.growablebuffer import awkward._connect.numba.layout n = ak.numba @@ -63,6 +181,7 @@ def _register(): n.ArrayBuilderType = awkward._connect.numba.builder.ArrayBuilderType n.ArrayBuilderModel = awkward._connect.numba.builder.ArrayBuilderModel n.cuda = awkward._connect.numba.arrayview_cuda.ArrayViewArgHandler() + n._from_data = awkward._connect.numba.growablebuffer._from_data @numba.extending.typeof_impl.register(ak.highlevel.Array) def typeof_Array(obj, c): diff --git a/src/awkward/operations/__init__.py b/src/awkward/operations/__init__.py index f2275e2018..450e4679de 100644 --- a/src/awkward/operations/__init__.py +++ b/src/awkward/operations/__init__.py @@ -22,6 +22,7 @@ from awkward.operations.ak_count_nonzero import * from awkward.operations.ak_covar import * from awkward.operations.ak_drop_none import * +from awkward.operations.ak_enforce_type import * from awkward.operations.ak_fields import * from awkward.operations.ak_fill_none import * from awkward.operations.ak_firsts import * diff --git a/src/awkward/operations/ak_all.py b/src/awkward/operations/ak_all.py index 562e33282c..ff6dc8fadd 100644 --- a/src/awkward/operations/ak_all.py +++ b/src/awkward/operations/ak_all.py @@ -2,22 +2,22 @@ __all__ = ("all",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def all( array, axis=None, *, keepdims=False, mask_identity=False, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -53,28 +53,7 @@ def all( See #ak.sum for a more complete description of nested list and missing value (None) handling in reducers. """ - with ak._errors.OperationErrorContext( - "ak.all", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @@ -98,5 +77,5 @@ def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @ak._connect.numpy.implements("all") -def _nep_18_impl(a, axis=None, out=unsupported, keepdims=False, *, where=unsupported): +def _nep_18_impl(a, axis=None, out=UNSUPPORTED, keepdims=False, *, where=UNSUPPORTED): return all(a, axis=axis, keepdims=keepdims) diff --git a/src/awkward/operations/ak_almost_equal.py b/src/awkward/operations/ak_almost_equal.py index ad0d5225f8..296e61075f 100644 --- a/src/awkward/operations/ak_almost_equal.py +++ b/src/awkward/operations/ak_almost_equal.py @@ -2,10 +2,9 @@ from __future__ import annotations __all__ = ("almost_equal",) - - from awkward._backends.dispatch import backend_of from awkward._behavior import behavior_of, get_array_class, get_record_class +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata from awkward._parameters import parameters_are_equal from awkward.operations.ak_to_layout import to_layout @@ -13,6 +12,7 @@ np = NumpyMetadata.instance() +@with_operation_context def almost_equal( left, right, @@ -64,22 +64,30 @@ def is_approx_dtype(left, right) -> bool: return np.issubdtype(right, family) return left == right + def packed_list_content(layout): + layout = layout.to_ListOffsetArray64(False) + return layout.content[layout.offsets[0] : layout.offsets[-1]] + def visitor(left, right) -> bool: - # Enforce super-canonicalisation rules + # First, erase indexed types! + if left.is_indexed and not left.is_option: + left = left.project() + if right.is_indexed and not right.is_option: + right = right.project() + + # Simplify option types if left.is_option: left = left.to_IndexedOptionArray64() if right.is_option: right = right.to_IndexedOptionArray64() - if type(left) is not type(right): - if not check_regular and ( - left.is_list and right.is_regular or left.is_regular and right.is_list - ): - left = left.to_ListOffsetArray64() - right = right.to_ListOffsetArray64() - else: - return False + # Simplify regular NumPy types + if left.is_numpy and left.purelist_depth > 1: + left = left.to_RegularArray() + if right.is_numpy and right.purelist_depth > 1: + right = right.to_RegularArray() + # Different lengths aren't equal! if left.length != right.length: return False @@ -96,49 +104,106 @@ def visitor(left, right) -> bool: ): return False - if left.is_list: - return backend.index_nplike.array_equal( - left.offsets, right.offsets - ) and visitor( - left.content[: left.offsets[-1]], right.content[: right.offsets[-1]] - ) - elif left.is_regular: + # Regular-regular + if left.is_regular and right.is_regular: return (left.size == right.size) and visitor(left.content, right.content) - elif left.is_numpy: - return ( - is_approx_dtype(left.dtype, right.dtype) - and backend.nplike.all( - backend.nplike.isclose( - left.data, right.data, rtol=rtol, atol=atol, equal_nan=False - ) + # List-list + elif left.is_list and right.is_list: + # Mixed regular-var + if left.is_regular and not right.is_regular: + return (not check_regular) and visitor( + left.content, + packed_list_content(right), + ) + elif right.is_regular and not left.is_regular: + return (not check_regular) and visitor( + packed_list_content(left), + right.content, + ) + else: + return visitor( + packed_list_content(left), + packed_list_content(right), ) - and left.shape == right.shape - ) - elif left.is_option: + elif left.is_numpy and right.is_numpy: + # Timelike types must be exactly compared, including their units + if ( + np.issubdtype(left.dtype, np.datetime64) + or np.issubdtype(right.dtype, np.datetime64) + or np.issubdtype(left.dtype, np.timedelta64) + or np.issubdtype(right.dtype, np.timedelta64) + ): + return ( + (left.dtype == right.dtype) + and backend.nplike.all(left.data == right.data) + and left.shape == right.shape + ) + else: + return ( + is_approx_dtype(left.dtype, right.dtype) + and backend.nplike.all( + backend.nplike.isclose( + left.data, right.data, rtol=rtol, atol=atol, equal_nan=False + ) + ) + and left.shape == right.shape + ) + elif left.is_option and right.is_option: return backend.index_nplike.array_equal( - left.index.data < 0, right.index.data < 0 - ) and visitor(left.project().to_packed(), right.project().to_packed()) - elif left.is_union: - return (len(left.contents) == len(right.contents)) and all( - visitor(left.project(i).to_packed(), right.project(i).to_packed()) - for i, _ in enumerate(left.contents) + left.mask_as_bool(True), right.mask_as_bool(True) + ) and visitor(left.project(), right.project()) + elif left.is_union and right.is_union: + # For two unions with different content orderings to match, the tags should be equal at each index + # Therefore, we can order the contents by index appearance + def ordered_unique_values(values): + # First, find unique values and their appearance (from smallest to largest) + # unique_index is in ascending order of `unique` value + ( + unique, + unique_index, + *_, + ) = backend.index_nplike.unique_all(values) + # Now re-order `unique` by order of appearance (`unique_index`) + return values[backend.index_nplike.sort(unique_index)] + + # Find order of appearance for each union tags, and assume these are one-to-one maps + left_tag_order = ordered_unique_values(left.tags.data) + right_tag_order = ordered_unique_values(right.tags.data) + + # Create map from left tags to right tags + left_tag_to_right_tag = backend.index_nplike.empty( + left_tag_order.size, dtype=np.int64 ) - elif left.is_record: + left_tag_to_right_tag[left_tag_order] = right_tag_order + + # Map left tags onto right, such that the result should equal right.tags + # if the two tag arrays are equivalent + new_left_tag = left_tag_to_right_tag[left.tags.data] + if not backend.index_nplike.all(new_left_tag == right.tags.data): + return False + + # Now project out the contents, and check for equality + for i, j in zip(left_tag_order, right_tag_order): + if not visitor(left.project(i), right.project(j)): + return False + return True + + elif left.is_record and right.is_record: return ( ( get_record_class(left, left_behavior) is get_record_class(right, right_behavior) or not check_parameters ) - and (left.fields == right.fields) - and (left.is_tuple == right.is_tuple) - and all(visitor(x, y) for x, y in zip(left.contents, right.contents)) + and left.is_tuple == right.is_tuple + and (left.is_tuple or (len(left.fields) == len(right.fields))) + and all(visitor(left.content(f), right.content(f)) for f in left.fields) ) - elif left.is_unknown: + elif left.is_unknown and right.is_unknown: return True else: - raise AssertionError + return False return visitor(left, right) diff --git a/src/awkward/operations/ak_any.py b/src/awkward/operations/ak_any.py index a3f40157f4..b9c0c136b1 100644 --- a/src/awkward/operations/ak_any.py +++ b/src/awkward/operations/ak_any.py @@ -2,22 +2,22 @@ __all__ = ("any",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def any( array, axis=None, *, keepdims=False, mask_identity=False, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -53,28 +53,7 @@ def any( See #ak.sum for a more complete description of nested list and missing value (None) handling in reducers. """ - with ak._errors.OperationErrorContext( - "ak.any", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @@ -98,5 +77,5 @@ def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @ak._connect.numpy.implements("any") -def _nep_18_impl(a, axis=None, out=unsupported, keepdims=False, *, where=unsupported): +def _nep_18_impl(a, axis=None, out=UNSUPPORTED, keepdims=False, *, where=UNSUPPORTED): return any(a, axis=axis, keepdims=keepdims) diff --git a/src/awkward/operations/ak_argcartesian.py b/src/awkward/operations/ak_argcartesian.py index 419975d64c..d4872667d6 100644 --- a/src/awkward/operations/ak_argcartesian.py +++ b/src/awkward/operations/ak_argcartesian.py @@ -4,6 +4,7 @@ from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -12,6 +13,7 @@ cpu = NumpyBackend.instance() +@with_operation_context def argcartesian( arrays, axis=1, @@ -88,19 +90,7 @@ def argcartesian( All of the parameters for #ak.cartesian apply equally to #ak.argcartesian, so see the #ak.cartesian documentation for a more complete description. """ - with ak._errors.OperationErrorContext( - "ak.argcartesian", - { - "arrays": arrays, - "axis": axis, - "nested": nested, - "parameters": parameters, - "with_name": with_name, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior) + return _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior) def _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior): diff --git a/src/awkward/operations/ak_argcombinations.py b/src/awkward/operations/ak_argcombinations.py index d34cad2155..795bd2a2bc 100644 --- a/src/awkward/operations/ak_argcombinations.py +++ b/src/awkward/operations/ak_argcombinations.py @@ -1,6 +1,7 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("argcombinations",) import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -8,6 +9,7 @@ np = NumpyMetadata.instance() +@with_operation_context def argcombinations( array, n, @@ -54,31 +56,17 @@ def argcombinations( #ak.argcartesian. See #ak.combinations and #ak.argcartesian for a more complete description. """ - with ak._errors.OperationErrorContext( - "ak.argcombinations", - { - "array": array, - "n": n, - "replacement": replacement, - "axis": axis, - "fields": fields, - "parameters": parameters, - "with_name": with_name, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl( - array, - n, - replacement, - axis, - fields, - parameters, - with_name, - highlevel, - behavior, - ) + return _impl( + array, + n, + replacement, + axis, + fields, + parameters, + with_name, + highlevel, + behavior, + ) def _impl( diff --git a/src/awkward/operations/ak_argmax.py b/src/awkward/operations/ak_argmax.py index 3bd9a6af3b..2577459cb9 100644 --- a/src/awkward/operations/ak_argmax.py +++ b/src/awkward/operations/ak_argmax.py @@ -2,22 +2,22 @@ __all__ = ("argmax",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def argmax( array, axis=None, *, keepdims=False, mask_identity=True, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -60,37 +60,16 @@ def argmax( See also #ak.nanargmax. """ - with ak._errors.OperationErrorContext( - "ak.argmax", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) +@with_operation_context def nanargmax( array, axis=None, *, keepdims=False, mask_identity=True, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -124,30 +103,14 @@ def nanargmax( See also #ak.argmax. """ - with ak._errors.OperationErrorContext( - "ak.nanargmax", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - array = ak.operations.ak_nan_to_none._impl(array, False, None) - - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl( + ak.operations.ak_nan_to_none._impl(array, False, None), + axis, + keepdims, + mask_identity, + highlevel, + behavior, + ) def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @@ -171,10 +134,10 @@ def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @ak._connect.numpy.implements("argmax") -def _nep_18_impl_argmax(a, axis=None, out=unsupported, *, keepdims=False): +def _nep_18_impl_argmax(a, axis=None, out=UNSUPPORTED, *, keepdims=False): return argmax(a, axis=axis, keepdims=keepdims) @ak._connect.numpy.implements("nanargmax") -def _nep_18_impl_nanargmax(a, axis=None, out=unsupported, *, keepdims=False): +def _nep_18_impl_nanargmax(a, axis=None, out=UNSUPPORTED, *, keepdims=False): return nanargmax(a, axis=axis, keepdims=keepdims) diff --git a/src/awkward/operations/ak_argmin.py b/src/awkward/operations/ak_argmin.py index e606fa5261..0341785971 100644 --- a/src/awkward/operations/ak_argmin.py +++ b/src/awkward/operations/ak_argmin.py @@ -2,22 +2,22 @@ __all__ = ("argmin",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def argmin( array, axis=None, *, keepdims=False, mask_identity=True, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -60,37 +60,16 @@ def argmin( See also #ak.nanargmin. """ - with ak._errors.OperationErrorContext( - "ak.argmin", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) +@with_operation_context def nanargmin( array, axis=None, *, keepdims=False, mask_identity=True, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -123,30 +102,14 @@ def nanargmin( See also #ak.argmin. """ - with ak._errors.OperationErrorContext( - "ak.nanargmin", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - array = ak.operations.ak_nan_to_none._impl(array, False, None) - - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl( + ak.operations.ak_nan_to_none._impl(array, False, None), + axis, + keepdims, + mask_identity, + highlevel, + behavior, + ) def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @@ -170,10 +133,10 @@ def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @ak._connect.numpy.implements("argmin") -def _nep_18_impl_argmin(a, axis=None, out=unsupported, *, keepdims=False): +def _nep_18_impl_argmin(a, axis=None, out=UNSUPPORTED, *, keepdims=False): return argmin(a, axis=axis, keepdims=keepdims) @ak._connect.numpy.implements("nanargmin") -def _nep_18_impl_nanargmin(a, axis=None, out=unsupported, *, keepdims=False): +def _nep_18_impl_nanargmin(a, axis=None, out=UNSUPPORTED, *, keepdims=False): return nanargmin(a, axis=axis, keepdims=keepdims) diff --git a/src/awkward/operations/ak_argsort.py b/src/awkward/operations/ak_argsort.py index ae9061d8d7..02317ac81c 100644 --- a/src/awkward/operations/ak_argsort.py +++ b/src/awkward/operations/ak_argsort.py @@ -1,7 +1,8 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("argsort",) import awkward as ak -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -9,6 +10,7 @@ np = NumpyMetadata.instance() +@with_operation_context def argsort( array, axis=-1, *, ascending=True, stable=True, highlevel=True, behavior=None ): @@ -47,18 +49,7 @@ def argsort( >>> data[index] """ - with ak._errors.OperationErrorContext( - "ak.argsort", - { - "array": array, - "axis": axis, - "ascending": ascending, - "stable": stable, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, axis, ascending, stable, highlevel, behavior) + return _impl(array, axis, ascending, stable, highlevel, behavior) def _impl(array, axis, ascending, stable, highlevel, behavior): @@ -69,7 +60,7 @@ def _impl(array, axis, ascending, stable, highlevel, behavior): @ak._connect.numpy.implements("argsort") -def _nep_18_impl(a, axis=-1, kind=None, order=unsupported): +def _nep_18_impl(a, axis=-1, kind=None, order=UNSUPPORTED): if kind is None: stable = False elif kind in ("stable", "mergesort"): diff --git a/src/awkward/operations/ak_backend.py b/src/awkward/operations/ak_backend.py index 6b07d983d4..8d221a77af 100644 --- a/src/awkward/operations/ak_backend.py +++ b/src/awkward/operations/ak_backend.py @@ -1,10 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("backend",) - -import awkward as ak from awkward._backends.dispatch import backend_of +from awkward._errors import with_operation_context +@with_operation_context def backend(*arrays) -> str: """ Args: @@ -21,11 +21,7 @@ def backend(*arrays) -> str: See #ak.to_backend. """ - with ak._errors.OperationErrorContext( - "ak.backend", - {"*arrays": arrays}, - ): - return _impl(arrays) + return _impl(arrays) def _impl(arrays) -> str: diff --git a/src/awkward/operations/ak_broadcast_arrays.py b/src/awkward/operations/ak_broadcast_arrays.py index ab15444614..287f810126 100644 --- a/src/awkward/operations/ak_broadcast_arrays.py +++ b/src/awkward/operations/ak_broadcast_arrays.py @@ -4,7 +4,8 @@ from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata @@ -12,6 +13,7 @@ cpu = NumpyBackend.instance() +@with_operation_context def broadcast_arrays( *arrays, depth_limit=None, @@ -176,27 +178,15 @@ def broadcast_arrays( [], [[6.6]]] """ - with ak._errors.OperationErrorContext( - "ak.broadcast_arrays", - { - "arrays": arrays, - "depth_limit": depth_limit, - "broadcast_parameters_rule": broadcast_parameters_rule, - "left_broadcast": left_broadcast, - "right_broadcast": right_broadcast, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl( - arrays, - depth_limit, - broadcast_parameters_rule, - left_broadcast, - right_broadcast, - highlevel, - behavior, - ) + return _impl( + arrays, + depth_limit, + broadcast_parameters_rule, + left_broadcast, + right_broadcast, + highlevel, + behavior, + ) def _impl( @@ -222,7 +212,14 @@ def _impl( inputs.append(y.to_backend(backend)) def action(inputs, depth, **kwargs): - if depth == depth_limit or all(x.is_numpy for x in inputs): + # The depth limit is the depth at which we must return, i.e. + # the _first_ layout at that depth + if depth == depth_limit: + return tuple(inputs) + # Walk through non-leaf nodes + elif all( + x.purelist_depth == 1 and not (x.is_option or x.is_indexed) for x in inputs + ): return tuple(inputs) else: return None @@ -242,5 +239,5 @@ def action(inputs, depth, **kwargs): @ak._connect.numpy.implements("broadcast_arrays") -def _nep_18_impl(*args, subok=unsupported): +def _nep_18_impl(*args, subok=UNSUPPORTED): return broadcast_arrays(*args) diff --git a/src/awkward/operations/ak_broadcast_fields.py b/src/awkward/operations/ak_broadcast_fields.py index 3c463efa95..d702168bb9 100644 --- a/src/awkward/operations/ak_broadcast_fields.py +++ b/src/awkward/operations/ak_broadcast_fields.py @@ -4,11 +4,13 @@ from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout cpu = NumpyBackend.instance() +@with_operation_context def broadcast_fields( *arrays, highlevel=True, @@ -50,15 +52,7 @@ def broadcast_fields( } """ - with ak._errors.OperationErrorContext( - "ak.broadcast_fields", - { - "arrays": arrays, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(arrays, highlevel, behavior) + return _impl(arrays, highlevel, behavior) def _impl(arrays, highlevel, behavior): diff --git a/src/awkward/operations/ak_cartesian.py b/src/awkward/operations/ak_cartesian.py index c7becc9b51..0d051275a1 100644 --- a/src/awkward/operations/ak_cartesian.py +++ b/src/awkward/operations/ak_cartesian.py @@ -4,6 +4,7 @@ from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -12,6 +13,7 @@ cpu = NumpyBackend.instance() +@with_operation_context def cartesian( arrays, axis=1, @@ -191,19 +193,7 @@ def cartesian( #ak.argcartesian form can be particularly useful as nested indexing in #ak.Array.__getitem__. """ - with ak._errors.OperationErrorContext( - "ak.cartesian", - { - "arrays": arrays, - "axis": axis, - "nested": nested, - "parameters": parameters, - "with_name": with_name, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior) + return _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior) def _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior): @@ -217,6 +207,8 @@ def _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior): ).to_backend(backend) for name, layout in arrays.items() } + layouts = list(array_layouts.values()) + fields = list(array_layouts.keys()) else: arrays = list(arrays) @@ -228,6 +220,8 @@ def _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior): ).to_backend(backend) for layout in arrays ] + layouts = array_layouts + fields = None if with_name is not None: if parameters is None: @@ -236,30 +230,30 @@ def _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior): parameters = dict(parameters) parameters["__record__"] = with_name - if isinstance(array_layouts, dict): - layouts = list(array_layouts.values()) - else: - layouts = array_layouts - posaxis = maybe_posaxis(layouts[0], axis, 1) - # Validate `posaxis` if posaxis is None or posaxis < 0: - raise ValueError("negative axis depth is ambiguous") + raise AxisError("negative axis depth is ambiguous") + # Ensure other layouts have same positive value for axis for layout in layouts[1:]: if maybe_posaxis(layout, axis, 1) != posaxis: - raise ValueError( + raise AxisError( "arrays to cartesian-product do not have the same depth for negative axis" ) + depths = [obj.purelist_depth for obj in layouts] + if posaxis >= max(depths): + raise AxisError( + f"axis={axis} exceeds the max depth of the given arrays (which is {max(depths)})" + ) # Validate `nested` if nested is None or nested is False: nested = [] elif nested is True: - if isinstance(array_layouts, dict): - nested = list(array_layouts.keys())[:-1] + if fields is not None: + nested = list(fields)[:-1] else: - nested = list(range(len(array_layouts))[:-1]) + nested = list(range(len(layouts))[:-1]) else: if isinstance(array_layouts, dict): if any(not (isinstance(x, str) and x in array_layouts) for x in nested): @@ -283,17 +277,8 @@ def _impl(arrays, axis, nested, parameters, with_name, highlevel, behavior): ) if posaxis == 0: - if isinstance(array_layouts, dict): - fields = [] - tonested = [] - for i, (name, _) in enumerate(array_layouts.items()): - fields.append(name) - if name in nested: - tonested.append(i) - nested = tonested - - else: - fields = None + if fields is not None: + nested = [i for i, name in enumerate(fields) if name in nested] indexes = [ ak.index.Index64(backend.index_nplike.reshape(x, (-1,))) @@ -377,29 +362,15 @@ def apply_pad_inner_list_at_axis(layout, depth, lateral_context, **kwargs): # This list *must* be sorted in reverse order axes_to_flatten.reverse() - if isinstance(array_layouts, dict): - fields = list(array_layouts.keys()) - new_layouts = [ - ak._do.recursively_apply( - layout, - apply_pad_inner_list_at_axis, - behavior, - lateral_context={"i": i}, - ) - for i, (_, layout) in enumerate(array_layouts.items()) - ] - - else: - fields = None - new_layouts = [ - ak._do.recursively_apply( - layout, - apply_pad_inner_list_at_axis, - behavior, - lateral_context={"i": i}, - ) - for i, layout in enumerate(array_layouts) - ] + new_layouts = [ + ak._do.recursively_apply( + layout, + apply_pad_inner_list_at_axis, + behavior, + lateral_context={"i": i}, + ) + for i, layout in enumerate(layouts) + ] def apply_build_record(inputs, depth, **kwargs): if depth == posaxis + len(array_layouts): diff --git a/src/awkward/operations/ak_categories.py b/src/awkward/operations/ak_categories.py index fa46867fc1..9281ee316d 100644 --- a/src/awkward/operations/ak_categories.py +++ b/src/awkward/operations/ak_categories.py @@ -2,9 +2,11 @@ __all__ = ("categories",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout +@with_operation_context def categories(array, highlevel=True): """ Args: @@ -18,11 +20,7 @@ def categories(array, highlevel=True): See also #ak.is_categorical, #ak.to_categorical, #ak.from_categorical. """ - with ak._errors.OperationErrorContext( - "ak.categories", - {"array": array, "highlevel": highlevel}, - ): - return _impl(array, highlevel) + return _impl(array, highlevel) def _impl(array, highlevel): diff --git a/src/awkward/operations/ak_combinations.py b/src/awkward/operations/ak_combinations.py index 836d792a0d..046c050333 100644 --- a/src/awkward/operations/ak_combinations.py +++ b/src/awkward/operations/ak_combinations.py @@ -1,6 +1,7 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("combinations",) import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -8,6 +9,7 @@ np = NumpyMetadata.instance() +@with_operation_context def combinations( array, n, @@ -175,31 +177,17 @@ def combinations( The #ak.argcombinations form can be particularly useful as nested indexing in #ak.Array.__getitem__. """ - with ak._errors.OperationErrorContext( - "ak.combinations", - { - "array": array, - "n": n, - "replacement": replacement, - "axis": axis, - "fields": fields, - "parameters": parameters, - "with_name": with_name, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl( - array, - n, - replacement, - axis, - fields, - parameters, - with_name, - highlevel, - behavior, - ) + return _impl( + array, + n, + replacement, + axis, + fields, + parameters, + with_name, + highlevel, + behavior, + ) def _impl( diff --git a/src/awkward/operations/ak_concatenate.py b/src/awkward/operations/ak_concatenate.py index 9756904add..670a0796db 100644 --- a/src/awkward/operations/ak_concatenate.py +++ b/src/awkward/operations/ak_concatenate.py @@ -4,9 +4,11 @@ from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata -from awkward._regularize import is_integer, regularize_axis +from awkward._nplikes.shape import unknown_length +from awkward._regularize import regularize_axis from awkward._typing import Sequence from awkward.contents import Content from awkward.operations.ak_fill_none import fill_none @@ -16,6 +18,7 @@ @ak._connect.numpy.implements("concatenate") +@with_operation_context def concatenate(arrays, axis=0, *, mergebool=True, highlevel=True, behavior=None): """ Args: @@ -38,17 +41,7 @@ def concatenate(arrays, axis=0, *, mergebool=True, highlevel=True, behavior=None must have the same lengths and nested lists are each concatenated, element for element, and similarly for deeper levels. """ - with ak._errors.OperationErrorContext( - "ak.concatenate", - { - "arrays": arrays, - "axis": axis, - "mergebool": mergebool, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(arrays, axis, mergebool, highlevel, behavior) + return _impl(arrays, axis, mergebool, highlevel, behavior) def _impl(arrays, axis, mergebool, highlevel, behavior): @@ -132,9 +125,20 @@ def _impl(arrays, axis, mergebool, highlevel, behavior): else: def action(inputs, depth, **kwargs): - if depth == posaxis and any( - isinstance(x, ak.contents.Content) and x.is_option for x in inputs + if any( + x.minmax_depth == (1, 1) + for x in inputs + if isinstance(x, ak.contents.Content) ): + raise ValueError( + "at least one array is not deep enough to concatenate at " + "axis={}".format(axis) + ) + + if depth != posaxis: + return + + if any(isinstance(x, ak.contents.Content) and x.is_option for x in inputs): nextinputs = [] for x in inputs: if x.is_option and x.content.is_list: @@ -143,23 +147,25 @@ def action(inputs, depth, **kwargs): nextinputs.append(x) inputs = nextinputs - if depth == posaxis: - backend = backend_of(*inputs, default=cpu) - - length = None - for x in inputs: - if isinstance(x, ak.contents.Content): - if not is_integer(length): - length = x.length - elif length != x.length and is_integer(x.length): - raise ValueError( - "all arrays must have the same length for " - "axis={}".format(axis) - ) + # Ensure the lengths agree, taking known lengths over unknown lengths + length = None + for x in inputs: + if isinstance(x, ak.contents.Content): + if length is None: + length = x.length + elif x.length is unknown_length: + continue + elif length is unknown_length: + length = x.length + elif length != x.length: + raise ValueError( + "all arrays must have the same length for " + "axis={}".format(axis) + ) + assert length is not None - if depth == posaxis and all( - isinstance(x, ak.contents.Content) - and x.is_regular + if all( + (isinstance(x, ak.contents.Content) and x.is_regular) or (isinstance(x, ak.contents.NumpyArray) and x.data.ndim > 1) or not isinstance(x, ak.contents.Content) for x in inputs @@ -190,7 +196,14 @@ def action(inputs, depth, **kwargs): prototype[start : start + size] = tag start += size - tags = ak.index.Index8(backend.index_nplike.tile(prototype, length)) + tags = ak.index.Index8( + backend.index_nplike.reshape( + backend.index_nplike.broadcast_to( + prototype, (length, prototype.size) + ), + (-1,), + ) + ) index = ak.contents.UnionArray.regular_index(tags, backend=backend) inner = ak.contents.UnionArray.simplified( tags, @@ -199,9 +212,9 @@ def action(inputs, depth, **kwargs): mergebool=mergebool, ) - return (ak.contents.RegularArray(inner, len(prototype)),) + return (ak.contents.RegularArray(inner, prototype.size),) - elif depth == posaxis and all( + elif all( isinstance(x, ak.contents.Content) and x.is_list or (isinstance(x, ak.contents.NumpyArray) and x.data.ndim > 1) @@ -217,7 +230,10 @@ def action(inputs, depth, **kwargs): ak.contents.ListOffsetArray( ak.index.Index64( backend.index_nplike.arange( - length + 1, dtype=np.int64 + backend.index_nplike.shape_item_as_index( + length + 1 + ), + dtype=np.int64, ), nplike=backend.index_nplike, ), @@ -263,16 +279,6 @@ def action(inputs, depth, **kwargs): return (ak.contents.ListOffsetArray(offsets, inner),) - elif any( - x.minmax_depth == (1, 1) - for x in inputs - if isinstance(x, ak.contents.Content) - ): - raise ValueError( - "at least one array is not deep enough to concatenate at " - "axis={}".format(axis) - ) - else: return None @@ -297,12 +303,12 @@ def _merge_as_union( offset = 0 for i, content in enumerate(contents): - content._handle_error( + content.backend.maybe_kernel_error( content.backend["awkward_UnionArray_filltags_const", tags.dtype.type]( tags.data, offset, content.length, i ) ) - content._handle_error( + content.backend.maybe_kernel_error( content.backend["awkward_UnionArray_fillindex_count", index.dtype.type]( index.data, offset, content.length ) diff --git a/src/awkward/operations/ak_copy.py b/src/awkward/operations/ak_copy.py index a48937188d..433f0966c4 100644 --- a/src/awkward/operations/ak_copy.py +++ b/src/awkward/operations/ak_copy.py @@ -1,15 +1,16 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("copy",) - import copy as _copy import awkward as ak -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def copy(array): """ Args: @@ -58,11 +59,7 @@ def copy(array): changes, so we don't support it. However, an #ak.Array's data might come from a mutable third-party library, so this function allows you to make a true copy. """ - with ak._errors.OperationErrorContext( - "ak.fill_none", - {"array": array}, - ): - return _impl(array) + return _impl(array) def _impl(array): @@ -70,5 +67,5 @@ def _impl(array): @ak._connect.numpy.implements("copy") -def _nep_18_impl(a, order=unsupported, subok=unsupported): +def _nep_18_impl(a, order=UNSUPPORTED, subok=UNSUPPORTED): return copy(a) diff --git a/src/awkward/operations/ak_corr.py b/src/awkward/operations/ak_corr.py index 238717bbf8..6f59a959e8 100644 --- a/src/awkward/operations/ak_corr.py +++ b/src/awkward/operations/ak_corr.py @@ -2,14 +2,15 @@ __all__ = ("corr",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._nplikes import ufuncs from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def corr( x, y, @@ -18,7 +19,6 @@ def corr( *, keepdims=False, mask_identity=False, - flatten_records=unset, ): """ Args: @@ -59,28 +59,7 @@ def corr( missing values (None) in reducers, and #ak.mean for an example with another non-reducer. """ - with ak._errors.OperationErrorContext( - "ak.corr", - { - "x": x, - "y": y, - "weight": weight, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(x, y, weight, axis, keepdims, mask_identity) + return _impl(x, y, weight, axis, keepdims, mask_identity) def _impl(x, y, weight, axis, keepdims, mask_identity): diff --git a/src/awkward/operations/ak_count.py b/src/awkward/operations/ak_count.py index 3cbef31ee9..dab8963fdc 100644 --- a/src/awkward/operations/ak_count.py +++ b/src/awkward/operations/ak_count.py @@ -2,21 +2,21 @@ __all__ = ("count",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def count( array, axis=None, *, keepdims=False, mask_identity=False, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -95,28 +95,7 @@ def count( If it is desirable to exclude NaN ("not a number") values from #ak.count, use #ak.nan_to_none to turn them into None, which are not counted. """ - with ak._errors.OperationErrorContext( - "ak.count", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): diff --git a/src/awkward/operations/ak_count_nonzero.py b/src/awkward/operations/ak_count_nonzero.py index a92bb511eb..a7341b777e 100644 --- a/src/awkward/operations/ak_count_nonzero.py +++ b/src/awkward/operations/ak_count_nonzero.py @@ -2,21 +2,21 @@ __all__ = ("count_nonzero",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def count_nonzero( array, axis=None, *, keepdims=False, mask_identity=False, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -54,28 +54,7 @@ def count_nonzero( count None values. If it is desirable to count them, use #ak.fill_none to turn them into something that would be counted. """ - with ak._errors.OperationErrorContext( - "ak.count_nonzero", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): diff --git a/src/awkward/operations/ak_covar.py b/src/awkward/operations/ak_covar.py index c85fae4b1e..567a831147 100644 --- a/src/awkward/operations/ak_covar.py +++ b/src/awkward/operations/ak_covar.py @@ -2,13 +2,14 @@ __all__ = ("covar",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def covar( x, y, @@ -17,7 +18,6 @@ def covar( *, keepdims=False, mask_identity=False, - flatten_records=unset, ): """ Args: @@ -56,28 +56,7 @@ def covar( missing values (None) in reducers, and #ak.mean for an example with another non-reducer. """ - with ak._errors.OperationErrorContext( - "ak.covar", - { - "x": x, - "y": y, - "weight": weight, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(x, y, weight, axis, keepdims, mask_identity) + return _impl(x, y, weight, axis, keepdims, mask_identity) def _impl(x, y, weight, axis, keepdims, mask_identity): diff --git a/src/awkward/operations/ak_drop_none.py b/src/awkward/operations/ak_drop_none.py index 7fddac9f8b..f740ad5fe5 100644 --- a/src/awkward/operations/ak_drop_none.py +++ b/src/awkward/operations/ak_drop_none.py @@ -1,6 +1,7 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("drop_none",) import awkward as ak +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -8,6 +9,7 @@ np = NumpyMetadata.instance() +@with_operation_context def drop_none(array, axis=None, highlevel=True, behavior=None): """ Args: @@ -40,11 +42,7 @@ def drop_none(array, axis=None, highlevel=True, behavior=None): """ - with ak._errors.OperationErrorContext( - "ak.drop_none", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): @@ -69,9 +67,7 @@ def action(layout, continuation, **kwargs): else: max_axis = layout.branch_depth[1] - 1 if axis > max_axis: - raise np.AxisError( - f"axis={axis} exceeds the depth ({max_axis}) of this array" - ) + raise AxisError(f"axis={axis} exceeds the depth ({max_axis}) of this array") def recompute_offsets(layout, depth, **kwargs): posaxis = maybe_posaxis(layout, axis, depth) @@ -89,7 +85,7 @@ def action(layout, depth, **kwargs): if layout.is_record: posaxises = {maybe_posaxis(x, axis, depth) for x in layout.contents} if len(posaxises) > 1 and any(x < depth for x in posaxises): - raise np.AxisError( + raise AxisError( f"axis={axis} implies different levels in records that might require part of a record to be dropped, which is impossible" ) posaxis = maybe_posaxis(layout, axis, depth) diff --git a/src/awkward/operations/ak_enforce_type.py b/src/awkward/operations/ak_enforce_type.py new file mode 100644 index 0000000000..d40a5e1b6a --- /dev/null +++ b/src/awkward/operations/ak_enforce_type.py @@ -0,0 +1,1281 @@ +from __future__ import annotations + +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +# ruff: noqa: B023 +__all__ = ("enforce_type",) +from itertools import permutations + +import awkward as ak +from awkward._errors import with_operation_context +from awkward._layout import wrap_layout +from awkward._nplikes.numpylike import NumpyMetadata +from awkward._nplikes.shape import unknown_length +from awkward._parameters import type_parameters_equal +from awkward._typing import NamedTuple +from awkward.types.numpytype import primitive_to_dtype + +np = NumpyMetadata.instance() + + +@with_operation_context +def enforce_type( + array, + type, + *, + highlevel=True, + behavior=None, +): + """ + Args: + array: Array-like data (anything #ak.to_layout recognizes). + type (#ak.types.Type, or str): The type that `array` will be enforced to. + highlevel (bool): If True, return an #ak.Array; otherwise, return + a low-level #ak.contents.Content subclass. + behavior (None or dict): Custom #ak.behavior for the output array, if + high-level. + + Returns an array whose structure is modified to match the given type. + + In addition to preserving the existing type and/or changing parameters, + + - #ak.types.OptionType can be added + + >>> a = ak.Array([1, 2, 3]) + >>> a.type.show() + 3 * int64 + >>> b = ak.enforce_type(a, "?int64") + >>> b.type.show() + 3 * ?int64 + + or removed (if there are no missing values) + + >>> a = ak.Array([1, 2, 3, None]) + >>> b = a[:-1] + >>> b.type.show() + 3 * ?int64 + >>> c = ak.enforce_type(b, "int64") + >>> c.type.show() + 3 * int64 + + - #ak.types.UnionType can + + * grow to include new variant types, + + >>> a = ak.Array([{'x': 1}, 2.0]) + >>> a.type.show() + 2 * union[ + { + x: int64 + }, + float64 + ] + >>> b = ak.enforce_type(a, "union[{x: int64}, float64, string]") + >>> b.type.show() + 2 * union[ + { + x: float32 + }, + float64, + string + ] + + * convert to a single type, + + >>> a = ak.concatenate([ + ... ak.Array([{'x': 1}, {'x': 2}]), + ... ak.Array([{'x': True, "y": None}, {'x': False, "y": None}]) + ... ]) + >>> a.type.show() + 4 * union[ + { + x: int64 + }, + { + x: bool, + y: ?unknown + } + ] + >>> b = ak.enforce_type(a, "{x: float64}") + >>> b.type.show() + 4 * { + x: float64 + } + + * project to a single type (if conversion to a single type is not possible, and the union contains no values for this type), + + >>> a = ak.concatenate([ + ... ak.Array([{'x': 1}, {'x': 2}]), + ... ak.Array([{'x': "yes", "y": None}, {'x': "no", "y": None}]) + ... ]) + >>> b = a[:2] + >>> b.type.show() + 2 * union[ + { + x: int64 + }, + { + x: string, + y: ?unknown + } + ] + >>> c = ak.enforce_type(b, "{x: int64}") + >>> c.type.show() + 2 * { + x: int64 + } + + * change type in a single variant. + + >>> a = ak.Array([{'x': 1}, 2.0]) + >>> a.type.show() + 2 * union[ + { + x: int64 + }, + float64 + ] + >>> b = ak.enforce_type(a, "union[{x: float32}, float64]") + >>> b.type.show() + 2 * union[ + { + x: float32 + }, + float64 + ] + + Due to these rules, changes to more than one variant of a union must be performed with multiple calls to #ak.enforce_type + + - #ak.types.RecordType can + + * grow to include new optional fields / slots, + + >>> a = ak.Array([{'x': 1}]) + >>> a.type.show() + 1 * { + x: int64 + } + >>> b = ak.enforce_type(a, "{x: int64, y: ?float32}") + >>> b.type.show() + 1 * { + x: int64, + y: ?float32 + } + + * shrink to drop existing fields / slots. + + >>> a = ak.Array([{'x': 1, 'y': 1j+3}]) + >>> a.type.show() + 1 * { + x: int64, + y: complex128 + } + >>> b = ak.enforce_type(a, "{x: int64}") + >>> b.type.show() + 1 * { + x: int64 + } + + A #ak.types.RecordType may only be converted to another #ak.types.RecordType if it is of the same flavour, i.e. + tuples can be converted to tuples, or records to records. Where a new field/slot is added to a #ak.types.RecordType, + it must be an #ak.types.OptionType. For tuples, slots may only be added to the end of the tuple + - #ak.types.RegularType can convert to a #ak.types.ListType + + >>> a = ak.to_regular([[1, 2, 3], [4, 5, 6]]) + >>> a.type.show() + 2 * 3 * int64 + >>> b = ak.enforce_type(a, "var * int64") + >>> b.type.show() + 2 * var * int64 + + - #ak.types.ListType can convert to a #ak.types.RegularType + + >>> a = ak.Array([[1, 2, 3], [4, 5, 6]]) + >>> a.type.show() + 2 * var * int64 + >>> b = ak.enforce_type(a, "3 * int64") + >>> b.type.show() + 2 * 3 * int64 + + - #ak.types.NumpyType can change primitive + + >>> a = ak.Array([1, 2, 3]) + >>> a.type.show() + 3 * int64 + >>> b = ak.enforce_type(a, "float32") + >>> b.type.show() + 3 * float32 + + - #ak.types.UnknownType can be converted to any other type + + >>> a = ak.Array([]) + >>> a.type.show() + 0 * unknown + >>> b = ak.enforce_type(a, "float32") + >>> b.type.show() + 0 * float32 + + and can be converted to from any other type. + + >>> a = ak.Array([1, 2, 3]) + >>> a.type.show() + 3 * int64 + >>> b = ak.enforce_type(a, "?unknown") + >>> b.type.show() + 3 * ?unknown + + The conversion rules outlined above are not data-dependent; the appropriate rule is chosen from the layout and the + given type value. If the conversion is not possible given the layout data, e.g. a conversion from an irregular list + to a regular type, it will fail. + """ + return _impl(array, type, highlevel, behavior) + + +def _impl(array, type_, highlevel, behavior): + layout = ak.to_layout(array, allow_record=True) + + if isinstance(type_, str): + type_ = ak.types.from_datashape(type_, highlevel=False) + + if isinstance(type_, (ak.types.ArrayType, ak.types.ScalarType)): + raise TypeError( + "High-level type objects are not supported by this function. Instead, " + "a low-level type object (instance of ak.types.Type) should be used. " + "If you are using a high-level type `type` from another array (e.g. using `array.type`), " + "then the low-level type object can be found under `type.content`" + ) + + # Ensure we re-wrap records! + if isinstance(layout, ak.record.Record): + out = ak.record.Record( + _enforce_type(layout.array[layout.at : layout.at + 1], type_), 0 + ) + else: + out = _enforce_type(layout, type_) + + return wrap_layout( + out, + like=array, + behavior=behavior, + highlevel=highlevel, + ) + + +# TODO: move this if it ends up being useful elsewhere +def _layout_has_type(layout: ak.contents.Content, type_: ak.types.Type) -> bool: + """ + Args: + layout: content object + type_: low-level type object + + Returns True if the layout satisfies the given type;, otherwise False. + """ + if not type_parameters_equal(layout._parameters, type_._parameters): + return False + + if layout.is_unknown: + return isinstance(type_, ak.types.UnknownType) + elif layout.is_option: + return isinstance(type_, ak.types.OptionType) and _layout_has_type( + layout.content, type_.content + ) + elif layout.is_indexed: + return _layout_has_type(layout.content, type_) + elif layout.is_regular: + return ( + isinstance(type_, ak.types.RegularType) + and ( + layout.size is unknown_length + or type_.size is unknown_length + or layout.size == type_.size + ) + and _layout_has_type(layout.content, type_.content) + ) + elif layout.is_list: + return isinstance(type_, ak.types.ListType) and _layout_has_type( + layout.content, type_.content + ) + elif layout.is_numpy: + for _ in range(layout.purelist_depth - 1): + if not isinstance(type_, ak.types.RegularType): + return False + type_ = type_.content + return isinstance( + type_, ak.types.NumpyType + ) and layout.dtype == primitive_to_dtype(type_.primitive) + elif layout.is_record: + if ( + not isinstance(type_, ak.types.RecordType) + or type_.is_tuple != layout.is_tuple + ): + return False + + if layout.is_tuple: + return all( + _layout_has_type(c, t) for c, t in zip(layout.contents, type_.contents) + ) + else: + return (frozenset(layout.fields) == frozenset(type_.fields)) and all( + _layout_has_type(layout.content(f), type_.content(f)) + for f in type_.fields + ) + elif layout.is_union: + if len(layout.contents) != len(type_.contents): + return False + + for contents in permutations(layout.contents): + if all( + _layout_has_type(layout, type_) + for layout, type_ in zip(contents, type_.contents) + ): + return True + return False + else: + raise TypeError(layout) + + +# TODO: move this if it ends up being useful elsewhere +class _TypeEnforceableResult(NamedTuple): + is_enforceable: bool + requires_packing: bool + + +def _type_is_enforceable( + layout: ak.contents.Content, type_: ak.types.Type +) -> _TypeEnforceableResult: + """ + Determine whether the layout can be enforced to the given type. + + Args: + layout: content object + type_: low-level type object + + Returns: a namedtuple with `is_enforceable` and `requires_packing` fields. + """ + if layout.is_unknown: + return _TypeEnforceableResult(is_enforceable=True, requires_packing=False) + + elif isinstance(type_, ak.types.UnknownType): + return _TypeEnforceableResult(is_enforceable=False, requires_packing=False) + + elif layout.is_option: + if isinstance(type_, ak.types.OptionType): + # Converting to an unknown inside an option! + if isinstance(type_.content, ak.types.UnknownType): + return _TypeEnforceableResult( + is_enforceable=True, requires_packing=False + ) + else: + return _type_is_enforceable(layout.content, type_.content) + else: + content_is_enforceable, content_needs_packed = _type_is_enforceable( + layout.content, type_ + ) + return _TypeEnforceableResult( + is_enforceable=content_is_enforceable, requires_packing=True + ) + + elif layout.is_indexed: + return _type_is_enforceable(layout.content, type_) + + # Here we *don't* have any layouts that are options, unknowns, or indexed + # If we see an option, we are therefore *adding* one + elif isinstance(type_, ak.types.OptionType): + # Converting to an unknown inside an option! + if isinstance(type_.content, ak.types.UnknownType): + return _TypeEnforceableResult(is_enforceable=True, requires_packing=False) + else: + return _type_is_enforceable(layout, type_.content) + + elif layout.is_union: + # If the target is a union type, then we have to determine the solution for e.g. + # {A, B, C, D} → {X, Y, C, Z}. + if isinstance(type_, ak.types.UnionType): + n_type_contents = len(type_.contents) + n_layout_contents = len(layout.contents) + # The general operation of converting between one union and another can be decomposed into multiple + # conversions from {A, B, C} to {A, B}, or from {A, B} to {A, B, C}. + # Here we will only allow these transformations, because (a) the code is easier to write! + # and (b) it is much easier to reason about _as a user_. + + # If the target has _more_ contents, then we assume we can add an unused content + # Assume here that we have a *subset* of the type, i.e layout is {A, B, C} + # and type is {A, B, C, D, ...}. + if n_type_contents > n_layout_contents: + # We can permute the type order, as union contents are not ordered + # Permute the index, so that we can later recover remaining types + ix_contents = range(n_type_contents) + for ix_perm_contents in permutations(ix_contents, n_layout_contents): + retained_types = [type_.contents[j] for j in ix_perm_contents] + # Require that all layouts match types for layout permutation + if all( + _layout_has_type(c, t) + for c, t in zip(layout.contents, retained_types) + ): + return _TypeEnforceableResult( + is_enforceable=True, requires_packing=False + ) + + return _TypeEnforceableResult( + is_enforceable=False, requires_packing=False + ) + + # Otherwise, we assume that we're projecting out one (or more) of our contents + # Assume here that we have a *subset* of the layout, i.e layout is {A, B, C, D, ...} + # and type is {A, B, C}. As the layout needs to lose a content, we must hope that the matching + # permutation (by type) is also one that drops only unused contents from the union, + # as layout operation must be typetracer-predictable + elif n_layout_contents > n_type_contents: + ix_contents = range(n_layout_contents) + for ix_perm_contents in permutations(ix_contents, n_type_contents): + retained_contents = [layout.contents[j] for j in ix_perm_contents] + # Require that all layouts match types for layout permutation + if all( + _layout_has_type(c, t) + for c, t in zip(retained_contents, type_.contents) + ): + return _TypeEnforceableResult( + is_enforceable=True, requires_packing=True + ) + return _TypeEnforceableResult( + is_enforceable=False, requires_packing=False + ) + + # Type and layout have same number of contents. Up-to *one* content can differ + else: + ix_contents = range(n_type_contents) + for ix_perm_contents in permutations(ix_contents): + permuted_types = [type_.contents[j] for j in ix_perm_contents] + + # How many contents match types in this permutation? + content_matches_type = [ + _layout_has_type(c, t) + for c, t in zip(layout.contents, permuted_types) + ] + n_matching = sum(content_matches_type, 0) + + if n_matching == len(type_.contents): + return _TypeEnforceableResult( + is_enforceable=True, requires_packing=False + ) + # Single content differs, we can convert by position + elif n_matching == len(type_.contents) - 1: + for tag, content_type, is_match in zip( + range(len(layout.contents)), + permuted_types, + content_matches_type, + ): + if not is_match: + # This content is being converted + return _type_is_enforceable( + layout.contents[tag], content_type + ) + raise AssertionError() + else: + return _TypeEnforceableResult( + is_enforceable=False, requires_packing=False + ) + # Otherwise, we are projecting out the union to a single type + else: + contents_enforceable = [ + _type_is_enforceable(content, type_) + for tag, content in enumerate(layout.contents) + ] + if all(c.is_enforceable for c in contents_enforceable): + # Conversion mode + return _TypeEnforceableResult( + is_enforceable=True, + requires_packing=any( + c.requires_packing for c in contents_enforceable + ), + ) + else: + # Projection mode + # Find the first content whose type equals the given type + for tag, content in enumerate(layout.contents): # noqa: B007 + if _layout_has_type(content, type_): + return _TypeEnforceableResult( + is_enforceable=True, requires_packing=False + ) + return _TypeEnforceableResult( + is_enforceable=False, requires_packing=False + ) + + # Here we *don't* have any layouts that are options, unknowns, indexed, or unions + # If we see a union, we are therefore *adding* one + elif isinstance(type_, ak.types.UnionType): + for _i, content_type in enumerate(type_.contents): + if _layout_has_type(layout, content_type): + return _type_is_enforceable(layout, content_type) + return _TypeEnforceableResult(is_enforceable=False, requires_packing=False) + + elif layout.is_regular: + if isinstance(type_, ak.types.RegularType): + if layout.size == type_.size: + return _TypeEnforceableResult( + is_enforceable=False, requires_packing=False + ) + return _type_is_enforceable(layout.content, type_.content) + + elif isinstance(type_, ak.types.ListType): + return _type_is_enforceable(layout.content, type_.content) + + else: + return _TypeEnforceableResult(is_enforceable=False, requires_packing=False) + + elif layout.is_list: + if isinstance(type_, ak.types.RegularType): + return _type_is_enforceable(layout.content, type_.content) + + elif isinstance(type_, ak.types.ListType): + return _type_is_enforceable(layout.content, type_.content) + + else: + return _TypeEnforceableResult(is_enforceable=False, requires_packing=False) + + elif layout.is_numpy: + for _ in range(layout.purelist_depth - 1): + if not isinstance(type_, ak.types.RegularType): + return _TypeEnforceableResult( + is_enforceable=False, requires_packing=False + ) + type_ = type_.content + if isinstance(type_, ak.types.NumpyType): + return _TypeEnforceableResult( + is_enforceable=True, + requires_packing=primitive_to_dtype(type_.primitive) != layout.dtype, + ) + else: + return _TypeEnforceableResult( + is_enforceable=False, + requires_packing=False, + ) + + elif layout.is_record: + if isinstance(type_, ak.types.RecordType): + if type_.is_tuple and layout.is_tuple: + # Recurse into shared contents + type_contents = iter(type_.contents) + contents_enforceable = [ + _type_is_enforceable(c, t) + for c, t in zip(layout.contents, type_contents) + ] + # Anything left in `type_contents` are the types of new slots + for next_type in type_contents: + if not isinstance(next_type, ak.types.OptionType): + return _TypeEnforceableResult( + is_enforceable=False, requires_packing=False + ) + + return _TypeEnforceableResult( + is_enforceable=all(c.is_enforceable for c in contents_enforceable), + requires_packing=any( + c.requires_packing for c in contents_enforceable + ), + ) + + elif not (type_.is_tuple or layout.is_tuple): + layout_fields = frozenset(layout._fields) + + # Compute existing and new fields + # Use lists to preserve type order + existing_fields = [] + new_fields = [] + for field in type_.fields: + if field in layout_fields: + existing_fields.append(field) + else: + new_fields.append(field) + + # Recurse into shared contents + contents_enforceable = [ + _type_is_enforceable(layout.content(f), type_.content(f)) + for f in existing_fields + ] + for field in new_fields: + field_type = type_.content(field) + if not isinstance(field_type, ak.types.OptionType): + return _TypeEnforceableResult( + is_enforceable=False, requires_packing=False + ) + + return _TypeEnforceableResult( + is_enforceable=all(c.is_enforceable for c in contents_enforceable), + requires_packing=any( + c.requires_packing for c in contents_enforceable + ), + ) + + else: + return _TypeEnforceableResult( + is_enforceable=False, requires_packing=False + ) + else: + return _TypeEnforceableResult(is_enforceable=False, requires_packing=False) + else: + raise TypeError(layout) + + +def _recurse_indexed_any( + layout: ak.contents.IndexedArray, type_: ak.types.Type +) -> ak.contents.Content: + content_enforceable = _type_is_enforceable(layout.content, type_) + + if content_enforceable.requires_packing: + # To ensure that we can project out options, we need to know + # exactly what's visible to the user, so we'll project our contents + return _enforce_type(layout.project(), type_) + else: + # If the types match, then we don't need to project, as only parameters + # are changed (if at all) + return layout.copy(content=_enforce_type(layout.content, type_)) + + +def _recurse_unknown_any( + layout: ak.contents.EmptyArray, type_: ak.types.Type +) -> ak.contents.Content: + type_form = ak.forms.from_type(type_) + return type_form.length_zero_array(highlevel=False).copy( + parameters=type_._parameters + ) + + +def _recurse_any_unknown(layout: ak.contents.Content, type_: ak.types.UnknownType): + raise TypeError( + "cannot convert non-EmptyArray layouts to a bare UnknownType. " + "To introduce an UnknownType, it must be wrapped in an OptionType" + ) + + +def _recurse_option_any( + layout: ak.contents.IndexedOptionArray + | ak.contents.BitMaskedArray + | ak.contents.ByteMaskedArray + | ak.contents.UnmaskedArray, + type_: ak.types.Type, +) -> ak.contents.Content: + # option → option (no change) + if isinstance(type_, ak.types.OptionType): + # Converting to an unknown inside an option! + if isinstance(type_.content, ak.types.UnknownType): + return ak.contents.IndexedOptionArray( + ak.index.Index64(layout.backend.index_nplike.full(layout.length, -1)), + ak.forms.from_type(type_.content).length_zero_array( + backend=layout.backend, highlevel=False + ), + ) + else: + # Check that we can build the content + content_enforceable = _type_is_enforceable(layout.content, type_.content) + if content_enforceable.requires_packing: + # If so, convert to packed so that any non-referenced content items are trimmed + # This is required so that unused union items are seen to be safe to project out later + # We don't use to_packed(), as it recurses + index_nplike = layout.backend.index_nplike + new_index = index_nplike.empty(layout.length, dtype=np.int64) + + is_none = layout.mask_as_bool(False) + num_none = index_nplike.count_nonzero(is_none) + + new_index[is_none] = -1 + new_index[~is_none] = index_nplike.arange( + layout.length - num_none, + dtype=new_index.dtype, + ) + return ak.contents.IndexedOptionArray( + ak.index.Index64(new_index, nplike=index_nplike), + _enforce_type(layout.project(), type_.content), + parameters=layout._parameters, + ) + else: + return layout.copy( + content=_enforce_type(layout.content, type_.content), + parameters=type_._parameters, + ) + + # drop option! + else: + # Check that we can build the content + content_enforceable = _type_is_enforceable(layout.content, type_) + + if layout.backend.index_nplike.any(layout.mask_as_bool(False)): + raise ValueError( + "option types can only be removed if there are no missing values" + ) + # If the option-type is not indexed, then at this point it's already packed + elif not layout.is_indexed: + return _enforce_type(layout.content[: layout.length], type_) + # Otherwise project out if required + elif content_enforceable.requires_packing: + return _enforce_type(layout.project(), type_) + # If we don't need to be packed, we can create a simple IndexedArray + else: + # Convert option to IndexedOptionArray and determine index of valid values + assert layout.is_indexed + return ak.contents.IndexedArray.simplified( + index=ak.index.Index64(layout.index.data[layout.mask_as_bool(True)]), + content=_enforce_type(layout.content, type_), + parameters=layout._parameters, + ) + + +def _recurse_any_option( + layout: ak.contents.Content, type_: ak.types.OptionType +) -> ak.contents.Content: + # Converting to an unknown inside an option! + if isinstance(type_.content, ak.types.UnknownType): + return ak.contents.IndexedOptionArray( + ak.index.Index64(layout.backend.index_nplike.full(layout.length, -1)), + ak.forms.from_type(type_.content).length_zero_array( + backend=layout.backend, highlevel=False + ), + ) + else: + return ak.contents.UnmaskedArray( + _enforce_type(layout, type_.content), parameters=type_._parameters + ) + + +def _recurse_union_any( + layout: ak.contents.UnionArray, type_: ak.types.Type +) -> ak.contents.Content: + # If the target is a union type, then we have to determine the solution for e.g. + # {A, B, C, D} → {X, Y, C, Z}. + if isinstance(type_, ak.types.UnionType): + return _recurse_union_union(layout, type_) + # Otherwise, we are projecting out the union to a single type + else: + return _recurse_union_non_union(layout, type_) + + +def _recurse_union_union( + layout: ak.contents.UnionArray, type_: ak.types.UnionType +) -> ak.contents.Content: + n_type_contents = len(type_.contents) + n_layout_contents = len(layout.contents) + # The general operation of converting between one union and another can be decomposed into multiple + # conversions from {A, B, C} to {A, B}, or from {A, B} to {A, B, C}. + # Here we will only allow these transformations, because (a) the code is easier to write! + # and (b) it is much easier to reason about _as a user_. + + # If the target has _more_ contents, then we assume we can add an unused content + # Assume here that we have a *subset* of the type, i.e layout is {A, B, C} + # and type is {A, B, C, D, ...}. + if n_type_contents > n_layout_contents: + # We can permute the type order, as union contents are not ordered + # Permute the index, so that we can later recover remaining types + ix_contents = range(n_type_contents) + for ix_perm_contents in permutations(ix_contents, n_layout_contents): + retained_types = [type_.contents[j] for j in ix_perm_contents] + # Require that all layouts match types for layout permutation + if all( + _layout_has_type(c, t) for c, t in zip(layout.contents, retained_types) + ): + break + + else: + # No permutation succeeded + raise NotImplementedError( + "UnionArray(s) can currently only be converted into UnionArray(s) with a greater number contents if the " + "layout contents are equal to some permutation of the type contents " + ) + ix_perm_contents_set = frozenset(ix_perm_contents) + missing_types = [ + type_.contents[j] for j in ix_contents if j not in ix_perm_contents_set + ] + + # We only need to recurse here to enable parameter changes + # Given that we _know_ all layouts match their types for the permutation, + # we don't need to project these contents — they won't be operated upon (besides parameters) + contents = [ + _enforce_type(b, c) for b, c in zip(layout.contents, retained_types) + ] + contents.extend( + [ + ak.forms.from_type(t).length_zero_array( + highlevel=False, backend=layout.backend + ) + for t in missing_types + ] + ) + return layout.copy(contents=contents, parameters=type_._parameters) + + # Otherwise, we assume that we're projecting out one (or more) of our contents + # Assume here that we have a *subset* of the layout, i.e layout is {A, B, C, D, ...} + # and type is {A, B, C}. As the layout needs to lose a content, we must hope that the matching + # permutation (by type) is also one that drops only unused contents from the union, + # as layout operation must be typetracer-predictable + elif n_layout_contents > n_type_contents: + ix_contents = range(n_layout_contents) + for ix_perm_contents in permutations(ix_contents, n_type_contents): + retained_contents = [layout.contents[j] for j in ix_perm_contents] + # Require that all layouts match types for layout permutation + if all( + _layout_has_type(c, t) + for c, t in zip(retained_contents, type_.contents) + ): + break + else: + raise NotImplementedError( + "UnionArray(s) can currently only be converted into UnionArray(s) with a greater " + "number of contents if the layout contents are compatible with some permutation of " + "the type contents" + ) + + # We only need to recurse here to enable parameter changes + # Given that we _know_ all layouts match their types for the permutation, + # we don't need to project these contents — they won't be operated upon (besides parameters) + contents = [ + _enforce_type(c, t) for c, t in zip(retained_contents, type_.contents) + ] + + is_trivial_permutation = ix_perm_contents == range(n_type_contents) + # Optimisation: if this is the trivial permutation, swe don't need to do any tag re-arranging + if is_trivial_permutation: + layout_tags = layout.tags + else: + layout_tags = ak.index.Index8.empty( + layout.tags.length, layout.backend.index_nplike + ) + + # Ensure that the union references all of the tags of the permutation, + # and re-order the tags if this is not the trivial permutation + _total_used_tags = 0 + for i, j in zip(ix_perm_contents, range(n_type_contents)): + layout_tag_is_i = layout.tags.data == i + + # Rewrite the tags if they need to be condensed (i.e., not if this is the trivial permutation) + if not is_trivial_permutation: + layout_tags.data[layout_tag_is_i] = j + + # Keep track of the length of layout subcontent + _total_used_tags += layout.backend.index_nplike.count_nonzero( + layout_tag_is_i + ) + # Is the new union of the same length as the original? + total_used_tags = layout.backend.index_nplike.index_as_shape_item( + _total_used_tags + ) + if not ( + total_used_tags is unknown_length + or layout.length is unknown_length + or total_used_tags == layout.length + ): + raise ValueError("union conversion must not be lossless") + + return layout.copy( + tags=layout_tags, + contents=contents, + parameters=type_._parameters, + ) + + # Type and layout have same number of contents. Up-to *one* content can differ + else: + ix_contents = range(n_type_contents) + for ix_perm_contents in permutations(ix_contents): + permuted_types = [type_.contents[j] for j in ix_perm_contents] + + # How many contents match types in this permutation? + content_matches_type = [ + _layout_has_type(c, t) for c, t in zip(layout.contents, permuted_types) + ] + n_matching = sum(content_matches_type, 0) + + # If all contents are nominally equal to the position-matched type, then only parameters have changed + if n_matching == len(type_.contents): + # Now build the result + contents = [ + _enforce_type(c, t) for c, t in zip(layout.contents, permuted_types) + ] + return layout.copy( + contents=contents, + parameters=type_._parameters, + ) + # Single content differs, we can convert by position + elif n_matching == len(type_.contents) - 1: + next_contents = [] + index: ak.index.Index | None = None + for tag, content_type, is_match in zip( + range(len(layout.contents)), permuted_types, content_matches_type + ): + # If the types agree between the intended type and content, then include this content + # as-is, only recursing to update parameters. Because the types agree, we're safe + # not to project out this content + if is_match: + # assert not builder_needs_packed(builder) + next_contents.append( + _enforce_type(layout.contents[tag], content_type) + ) + # Otherwise, this content is being converted, and we need to recurse into the projection + # to ensure that the content is packed + else: + # tag_needs_packed = builder_needs_packed(builder) + tag_content_enforceable = _type_is_enforceable( + layout.contents[tag], content_type + ) + + if tag_content_enforceable.requires_packing: + # Project changed ccontent + layout_content = layout.project(tag) + # Rebuild the index as an enumeration over the (dense) projection + # This ensures that it is packed! + index_data = layout.backend.index_nplike.asarray( + layout.index.data, copy=True + ) + is_tag = layout.tags.data == tag + index_data[is_tag] = layout.backend.index_nplike.arange( + layout_content.length, dtype=index_data.dtype + ) + index = ak.index.Index(index_data) + next_contents.append( + _enforce_type(layout_content, content_type) + ) + else: + index = layout.index + next_contents.append( + _enforce_type(layout.contents[tag], content_type) + ) + + return layout.copy( + index=index, + contents=next_contents, + parameters=type_._parameters, + ) + else: + raise TypeError( + "UnionArray(s) can currently only be converted into UnionArray(s) with the same number of contents " + "if no greater than one content differs in type" + ) + + +def _recurse_union_non_union( + layout: ak.contents.UnionArray, type_: ak.types.Type +) -> ak.contents.Content: + index_nplike = layout.backend.index_nplike + if all(_type_is_enforceable(c, type_).is_enforceable for c in layout.contents): + # Convert each projected content to the required type + next_contents = [] + index_data = index_nplike.empty(layout.length, dtype=np.int64) + j = 0 + for tag in range(len(layout.contents)): + tag_content = layout.project(tag) + # Set the index of these tags to a simple range + i, j = j, j + index_nplike.shape_item_as_index(tag_content.length) + index_data[layout.tags.data == tag] = index_nplike.arange( + i, j, dtype=np.int64 + ) + # Convert layout + next_contents.append(_enforce_type(tag_content, type_)) + + # Merge the results + for content in next_contents[1:]: + assert ak._do.mergeable(next_contents[0], content, mergebool=False) + next_content = ak._do.mergemany(next_contents) + + # Index over them + index = ak.index.Index64(index_data) + return ak.contents.IndexedArray(index, next_content) + else: + # Find the first content whose type equals the given type + for tag, content in enumerate(layout.contents): # noqa: B007 + if _layout_has_type(content, type_): + break + else: + raise TypeError( + f"UnionArray(s) can only be converted into {type_} if it has the same type, " + f"but no content with type {type_} was found" + ) + + # Require that we are the only content + content_is_tag = layout.tags.data == tag + if index_nplike.known_data and not index_nplike.all(content_is_tag): + raise ValueError( + f"UnionArray(s) can only be converted to {type_} if they are equivalent to their " + f"projections" + ) + else: + # We don't need to pack, as the type hasn't changed, so introduce an indexed type. + # This ensures that unions over records don't needlessly project. + # From the canonical rules, the content of a union *can* be an index, so we use simplified + return ak.contents.IndexedArray.simplified( + ak.index.Index(layout.index.data[content_is_tag]), + _enforce_type(content, type_), + ) + + +def _recurse_any_union( + layout: ak.contents.Content, type_: ak.types.UnionType +) -> ak.contents.Content: + index_nplike = layout.backend.index_nplike + + for i, content_type in enumerate(type_.contents): + if not _layout_has_type(layout, content_type): + continue + + # Build zero-length contents from the new types + tags = index_nplike.zeros(layout.length, dtype=np.int8) + index = index_nplike.arange(layout.length, dtype=np.int64) + + other_contents = [ + ak.forms.from_type(t).length_zero_array( + backend=layout.backend, highlevel=False + ) + for j, t in enumerate(type_.contents) + if j != i + ] + + return ak.contents.UnionArray( + tags=ak.index.Index8(tags, nplike=index_nplike), + index=ak.index.Index64(index, nplike=index_nplike), + contents=[ + _enforce_type(layout, content_type), + *other_contents, + ], + parameters=type_._parameters, + ) + + raise TypeError( + f"{type(layout).__name__} can only be converted into a UnionType if it is compatible with one " + "of its contents, but no compatible content as found" + ) + + +def _recurse_regular_any( + layout: ak.contents.RegularArray, type_: ak.types.Type +) -> ak.contents.Content: + if isinstance(type_, ak.types.RegularType): + # regular → regular requires same size! + if layout.size != type_.size: + raise ValueError( + f"regular layout has different size ({layout.size}) to type ({type_.size})" + ) + + return layout.copy( + content=_enforce_type(layout.content, type_.content), + parameters=type_._parameters, + ) + + elif isinstance(type_, ak.types.ListType): + layout_list = layout.to_ListOffsetArray64(True) + return layout_list.copy( + content=_enforce_type(layout.content, type_.content), + parameters=type_._parameters, + ) + + else: + raise TypeError( + f"lists can only be converted to lists, options of lists, or unions thereof, not {type_}" + ) + + +def _recurse_list_any( + layout: ak.contents.ListArray | ak.contents.ListOffsetArray, type_: ak.types.Type +) -> ak.contents.Content: + if isinstance(type_, ak.types.RegularType): + layout_regular = layout.to_RegularArray() + + # Empty arrays can have any size! + if layout_regular.length is not unknown_length and layout_regular.length == 0: + return layout_regular.copy( + # Correct the size + size=type_.size, + content=_enforce_type(layout_regular.content, type_.content), + ) + + elif layout_regular.size is unknown_length or layout_regular.size == type_.size: + return layout_regular.copy( + # The result of `to_RegularArray` should already be packed + content=_enforce_type(layout_regular.content, type_.content), + parameters=type_._parameters, + ) + + else: + # Runtime error + raise ValueError( + f"converted regular layout has different size ({layout_regular.size}) to type ({type_.size})" + ) + + elif isinstance(type_, ak.types.ListType): + content_enforceable = _type_is_enforceable(layout.content, type_.content) + if content_enforceable.requires_packing: + # Need to pack the content! + layout = layout.to_ListOffsetArray64(True) + layout = layout[: layout.offsets[-1]] + return layout.copy( + content=_enforce_type(layout.content, type_.content), + parameters=type_._parameters, + ) + else: + # Don't need to pack the content + return layout.copy( + content=_enforce_type(layout.content, type_.content), + parameters=type_._parameters, + ) + + else: + raise TypeError( + f"lists can only be converted to lists, options of lists, or unions thereof, not {type_}" + ) + + +def _recurse_numpy_any( + layout: ak.contents.NumpyArray, type_: ak.types.Type +) -> ak.contents.Content: + if len(layout.shape) == 1: + if not isinstance(type_, ak.types.NumpyType): + raise TypeError( + "NumpyArray(s) can only be converted into NumpyArray(s), options of NumpyArray(s), or " + "unions thereof" + ) + return ak.values_astype( + # HACK: drop parameters from type so that character arrays are supported + layout.copy(parameters=None), + to=primitive_to_dtype(type_.primitive), + highlevel=False, + ).copy(parameters=type_._parameters) + + else: + assert len(layout.shape) > 0 + return _enforce_type(layout.to_RegularArray(), type_) + + +def _recurse_record_any( + layout: ak.contents.RecordArray, type_: ak.types.Type +) -> ak.contents.Content: + if isinstance(type_, ak.types.RecordType): + if type_.is_tuple and layout.is_tuple: + # Recurse into shared contents + type_contents = iter(type_.contents) + next_contents = [ + _enforce_type(c, t) for c, t in zip(layout.contents, type_contents) + ] + # Anything left in `type_contents` are the types of new slots + for next_type in type_contents: + # Added types must be options, so that they can be all-None + if not isinstance(next_type, ak.types.OptionType): + raise TypeError( + "can only add new slots to a tuple if they are option types" + ) + # Append new contents + next_contents.append( + ak.contents.IndexedOptionArray( + ak.index.Index64( + layout.backend.index_nplike.full(layout.length, -1) + ), + ak.forms.from_type(next_type.content).length_zero_array( + backend=layout.backend, highlevel=False + ), + ) + ) + + return layout.copy( + fields=None, + contents=next_contents, + parameters=type_._parameters, + ) + + elif not (type_.is_tuple or layout.is_tuple): + layout_fields = frozenset(layout._fields) + + # Compute existing and new fields + # Use lists to preserve type order + existing_fields = [] + new_fields = [] + for field in type_.fields: + if field in layout_fields: + existing_fields.append(field) + else: + new_fields.append(field) + next_fields = existing_fields + new_fields + + # Recurse into shared contents + next_contents = [ + _enforce_type(layout.content(f), type_.content(f)) + for f in existing_fields + ] + for field in new_fields: + field_type = type_.content(field) + + # Added types must be options, so that they can be all-None + if not isinstance(field_type, ak.types.OptionType): + raise TypeError( + "can only add new fields to a record if they are option types" + ) + # Append new contents + next_contents.append( + ak.contents.IndexedOptionArray( + ak.index.Index64( + layout.backend.index_nplike.full(layout.length, -1) + ), + ak.forms.from_type(field_type.content).length_zero_array( + backend=layout.backend, highlevel=False + ), + ) + ) + + return layout.copy( + fields=next_fields, + contents=next_contents, + parameters=type_._parameters, + ) + + else: + raise ValueError( + "RecordArray(s) cannot be converted between records and tuples." + ) + else: + raise TypeError( + "RecordArray(s) can only be converted into RecordArray(s), options of RecordArray(s), or " + "unions thereof" + ) + + +def _enforce_type( + layout: ak.contents.Content, type_: ak.types.Type +) -> ak.contents.Content: + """ + Args: + layout: layout to recurse into + type_: expected type of the recursion result + + Returns a callable which converts from `layout` to `type_`. layout ensures that + calling `recurse` is a type-only program, whilst keeping the conversion logic + adjacent to the type check logic. + """ + if layout.is_unknown: + return _recurse_unknown_any(layout, type_) + + elif isinstance(type_, ak.types.UnknownType): + return _recurse_any_unknown(layout, type_) + + elif layout.is_option: + return _recurse_option_any(layout, type_) + + elif layout.is_indexed: + return _recurse_indexed_any(layout, type_) + + # Here we *don't* have any layouts that are options, unknowns, or indexed + # If we see an option, we are therefore *adding* one + elif isinstance(type_, ak.types.OptionType): + return _recurse_any_option(layout, type_) + + elif layout.is_union: + return _recurse_union_any(layout, type_) + + # Here we *don't* have any layouts that are options, unknowns, indexed, or unions + # If we see a union, we are therefore *adding* one + elif isinstance(type_, ak.types.UnionType): + return _recurse_any_union(layout, type_) + + elif layout.is_regular: + return _recurse_regular_any(layout, type_) + + elif layout.is_list: + return _recurse_list_any(layout, type_) + + elif layout.is_numpy: + return _recurse_numpy_any(layout, type_) + + elif layout.is_record: + return _recurse_record_any(layout, type_) + else: + raise NotImplementedError(type(layout), type_) diff --git a/src/awkward/operations/ak_fields.py b/src/awkward/operations/ak_fields.py index 3cae9027e5..9c94ec4d3d 100644 --- a/src/awkward/operations/ak_fields.py +++ b/src/awkward/operations/ak_fields.py @@ -1,12 +1,13 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("fields",) - import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def fields(array): """ Args: @@ -23,11 +24,7 @@ def fields(array): If the array contains neither tuples nor records, this returns an empty list. """ - with ak._errors.OperationErrorContext( - "ak.fields", - {"array": array}, - ): - return _impl(array) + return _impl(array) def _impl(array): diff --git a/src/awkward/operations/ak_fill_none.py b/src/awkward/operations/ak_fill_none.py index 413a8285de..1b631c29ce 100644 --- a/src/awkward/operations/ak_fill_none.py +++ b/src/awkward/operations/ak_fill_none.py @@ -6,6 +6,7 @@ from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import is_sized_iterable, regularize_axis @@ -14,6 +15,7 @@ cpu = NumpyBackend.instance() +@with_operation_context def fill_none(array, value, axis=-1, *, highlevel=True, behavior=None): """ Args: @@ -58,17 +60,7 @@ def fill_none(array, value, axis=-1, *, highlevel=True, behavior=None): The values could be floating-point numbers or strings. """ - with ak._errors.OperationErrorContext( - "ak.fill_none", - { - "array": array, - "value": value, - "axis": axis, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, value, axis, highlevel, behavior) + return _impl(array, value, axis, highlevel, behavior) def _impl(array, value, axis, highlevel, behavior): @@ -136,7 +128,7 @@ def action(layout, depth, **kwargs): return layout elif layout.is_leaf: - raise np.AxisError( + raise AxisError( f"axis={axis} exceeds the depth of this array ({depth})" ) diff --git a/src/awkward/operations/ak_firsts.py b/src/awkward/operations/ak_firsts.py index b5f8d2fa8f..0207eb9550 100644 --- a/src/awkward/operations/ak_firsts.py +++ b/src/awkward/operations/ak_firsts.py @@ -2,6 +2,7 @@ __all__ = ("firsts",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import is_integer, regularize_axis @@ -9,6 +10,7 @@ np = NumpyMetadata.instance() +@with_operation_context def firsts(array, axis=1, *, highlevel=True, behavior=None): """ Args: @@ -40,11 +42,7 @@ def firsts(array, axis=1, *, highlevel=True, behavior=None): See #ak.singletons to invert this function. """ - with ak._errors.OperationErrorContext( - "ak.firsts", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): @@ -90,7 +88,7 @@ def action(layout, depth, depth_context, **kwargs): ) elif layout.is_leaf: - raise np.AxisError( + raise AxisError( f"axis={axis} exceeds the depth of this array ({depth})" ) diff --git a/src/awkward/operations/ak_flatten.py b/src/awkward/operations/ak_flatten.py index 4673c74efd..db0dc937e0 100644 --- a/src/awkward/operations/ak_flatten.py +++ b/src/awkward/operations/ak_flatten.py @@ -1,6 +1,7 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("flatten",) import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -8,6 +9,7 @@ np = NumpyMetadata.instance() +@with_operation_context def flatten(array, axis=1, *, highlevel=True, behavior=None): """ Args: @@ -157,11 +159,7 @@ def flatten(array, axis=1, *, highlevel=True, behavior=None): 2.2, 999] """ - with ak._errors.OperationErrorContext( - "ak.flatten", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): diff --git a/src/awkward/operations/ak_from_arrow.py b/src/awkward/operations/ak_from_arrow.py index 5e5f6c8a24..3b06d7db93 100644 --- a/src/awkward/operations/ak_from_arrow.py +++ b/src/awkward/operations/ak_from_arrow.py @@ -1,12 +1,14 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("from_arrow",) import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def from_arrow(array, *, generate_bitmasks=False, highlevel=True, behavior=None): """ Args: @@ -32,16 +34,7 @@ def from_arrow(array, *, generate_bitmasks=False, highlevel=True, behavior=None) See also #ak.to_arrow, #ak.to_arrow_table, #ak.from_parquet, #ak.from_arrow_schema. """ - with ak._errors.OperationErrorContext( - "ak.from_arrow", - { - "array": array, - "generate_bitmasks": generate_bitmasks, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, generate_bitmasks, highlevel, behavior) + return _impl(array, generate_bitmasks, highlevel, behavior) def _impl(array, generate_bitmasks, highlevel, behavior): diff --git a/src/awkward/operations/ak_from_arrow_schema.py b/src/awkward/operations/ak_from_arrow_schema.py index a8881b69a2..0caf19b3c2 100644 --- a/src/awkward/operations/ak_from_arrow_schema.py +++ b/src/awkward/operations/ak_from_arrow_schema.py @@ -1,12 +1,12 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("from_arrow_schema",) - -import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def from_arrow_schema(schema): """ Args: @@ -16,11 +16,7 @@ def from_arrow_schema(schema): See also #ak.to_arrow, #ak.to_arrow_table, #ak.from_arrow, #ak.to_parquet, #ak.from_parquet. """ - with ak._errors.OperationErrorContext( - "ak.from_arrow_schema", - {"schema": schema}, - ): - return _impl(schema) + return _impl(schema) def _impl(schema): diff --git a/src/awkward/operations/ak_from_avro_file.py b/src/awkward/operations/ak_from_avro_file.py index 7c07cde565..2acf1fe7cc 100644 --- a/src/awkward/operations/ak_from_avro_file.py +++ b/src/awkward/operations/ak_from_avro_file.py @@ -1,21 +1,22 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("from_avro_file",) -# from awkward._typing import Type -import pathlib +from os import PathLike, fsdecode import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def from_avro_file( file, limit_entries=None, *, debug_forth=False, highlevel=True, behavior=None ): """ Args: - file (string or file-like object): Avro file to be read as Awkward Array. + file (path-like or file-like object): Avro file to be read as Awkward Array. limit_entries (int): The number of rows of the Avro file to be read into the Awkward Array. debug_forth (bool): If True, prints the generated Forth code for debugging. highlevel (bool): If True, return an #ak.Array; otherwise, return @@ -30,36 +31,24 @@ def from_avro_file( """ import awkward._connect.avro - with ak._errors.OperationErrorContext( - "ak.from_avro_file", - { - "file": file, - "highlevel": highlevel, - "behavior": behavior, - "limit_entries": limit_entries, - "debug_forth": debug_forth, - }, - ): - if isinstance(file, pathlib.Path): - file = str(file) - - if isinstance(file, str): - with open(file, "rb") as opened_file: - form, length, container = awkward._connect.avro.ReadAvroFT( - opened_file, limit_entries, debug_forth - ).outcontents - return _impl(form, length, container, highlevel, behavior) + if isinstance(file, (str, bytes, PathLike)): + file = fsdecode(file) + with open(file, "rb") as opened_file: + form, length, container = awkward._connect.avro.ReadAvroFT( + opened_file, limit_entries, debug_forth + ).outcontents + return _impl(form, length, container, highlevel, behavior) + else: + if not hasattr(file, "read") or not hasattr(file, "seek"): + raise TypeError( + "'file' must either be a filename string or be a file-like object with 'read' and 'seek' methods" + ) else: - if not hasattr(file, "read") or not hasattr(file, "seek"): - raise TypeError( - "'file' must either be a filename string or be a file-like object with 'read' and 'seek' methods" - ) - else: - form, length, container = awkward._connect.avro.ReadAvroFT( - file, limit_entries, debug_forth - ).outarr - return _impl(form, length, container, highlevel, behavior) + form, length, container = awkward._connect.avro.ReadAvroFT( + file, limit_entries, debug_forth + ).outarr + return _impl(form, length, container, highlevel, behavior) def _impl(form, length, container, highlevel, behavior): diff --git a/src/awkward/operations/ak_from_buffers.py b/src/awkward/operations/ak_from_buffers.py index 55d53d1869..75237565b7 100644 --- a/src/awkward/operations/ak_from_buffers.py +++ b/src/awkward/operations/ak_from_buffers.py @@ -2,11 +2,11 @@ from __future__ import annotations __all__ = ("from_buffers",) - import math import awkward as ak from awkward._backends.dispatch import regularize_backend +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyMetadata @@ -16,6 +16,7 @@ numpy = Numpy.instance() +@with_operation_context def from_buffers( form, length, @@ -73,30 +74,17 @@ def from_buffers( See #ak.to_buffers for examples. """ - with ak._errors.OperationErrorContext( - "ak.from_buffers", - { - "form": form, - "length": length, - "container": container, - "buffer_key": buffer_key, - "backend": backend, - "byteorder": byteorder, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl( - form, - length, - container, - buffer_key, - backend, - byteorder, - highlevel, - behavior, - False, - ) + return _impl( + form, + length, + container, + buffer_key, + backend, + byteorder, + highlevel, + behavior, + False, + ) def _impl( @@ -175,6 +163,7 @@ def _from_buffer(nplike, buffer, dtype, count, byteorder): return array +@with_operation_context def reconstitute(form, length, container, getkey, backend, byteorder, simplify): if isinstance(form, ak.forms.EmptyForm): if length != 0: @@ -199,7 +188,9 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): data = backend.nplike.reshape(data, (length, *form.inner_shape)) else: data = backend.nplike.reshape(data, (-1, *form.inner_shape)) - return ak.contents.NumpyArray(data, parameters=form.parameters, backend=backend) + return ak.contents.NumpyArray( + data, parameters=form._parameters, backend=backend + ) elif isinstance(form, ak.forms.UnmaskedForm): content = reconstitute( @@ -209,7 +200,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): make = ak.contents.UnmaskedArray.simplified else: make = ak.contents.UnmaskedArray - return make(content, parameters=form.parameters) + return make(content, parameters=form._parameters) elif isinstance(form, ak.forms.BitMaskedForm): raw_array = container[getkey(form, "mask")] @@ -234,7 +225,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): form.valid_when, length, form.lsb_order, - parameters=form.parameters, + parameters=form._parameters, ) elif isinstance(form, ak.forms.ByteMaskedForm): @@ -257,7 +248,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): ak.index.Index(mask), content, form.valid_when, - parameters=form.parameters, + parameters=form._parameters, ) elif isinstance(form, ak.forms.IndexedOptionForm): @@ -282,7 +273,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): return make( ak.index.Index(index), content, - parameters=form.parameters, + parameters=form._parameters, ) elif isinstance(form, ak.forms.IndexedForm): @@ -311,7 +302,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): return make( ak.index.Index(index), content, - parameters=form.parameters, + parameters=form._parameters, ) elif isinstance(form, ak.forms.ListForm): @@ -340,7 +331,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): ak.index.Index(starts), ak.index.Index(stops), content, - parameters=form.parameters, + parameters=form._parameters, ) elif isinstance(form, ak.forms.ListOffsetForm): @@ -359,7 +350,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): return ak.contents.ListOffsetArray( ak.index.Index(offsets), content, - parameters=form.parameters, + parameters=form._parameters, ) elif isinstance(form, ak.forms.RegularForm): @@ -371,7 +362,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): content, form.size, length, - parameters=form.parameters, + parameters=form._parameters, ) elif isinstance(form, ak.forms.RecordForm): @@ -385,7 +376,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): contents, None if form.is_tuple else form.fields, length, - parameters=form.parameters, + parameters=form._parameters, ) elif isinstance(form, ak.forms.UnionForm): @@ -426,7 +417,7 @@ def reconstitute(form, length, container, getkey, backend, byteorder, simplify): ak.index.Index(tags), ak.index.Index(index), contents, - parameters=form.parameters, + parameters=form._parameters, ) else: diff --git a/src/awkward/operations/ak_from_categorical.py b/src/awkward/operations/ak_from_categorical.py index 77ce70661d..5f32c5dc71 100644 --- a/src/awkward/operations/ak_from_categorical.py +++ b/src/awkward/operations/ak_from_categorical.py @@ -2,9 +2,11 @@ __all__ = ("from_categorical",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout +@with_operation_context def from_categorical(array, *, highlevel=True, behavior=None): """ Args: @@ -24,11 +26,7 @@ def from_categorical(array, *, highlevel=True, behavior=None): See also #ak.is_categorical, #ak.categories, #ak.to_categorical, #ak.from_categorical. """ - with ak._errors.OperationErrorContext( - "ak.from_categorical", - {"array": array, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, highlevel, behavior) + return _impl(array, highlevel, behavior) def _impl(array, highlevel, behavior): diff --git a/src/awkward/operations/ak_from_cupy.py b/src/awkward/operations/ak_from_cupy.py index 3b29fdf391..63c4d6743b 100644 --- a/src/awkward/operations/ak_from_cupy.py +++ b/src/awkward/operations/ak_from_cupy.py @@ -1,9 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("from_cupy",) -import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import from_arraylib, wrap_layout +@with_operation_context def from_cupy(array, *, regulararray=False, highlevel=True, behavior=None): """ Args: @@ -28,17 +29,8 @@ def from_cupy(array, *, regulararray=False, highlevel=True, behavior=None): See also #ak.to_cupy, #ak.from_numpy and #ak.from_jax. """ - with ak._errors.OperationErrorContext( - "ak.from_cupy", - { - "array": array, - "regulararray": regulararray, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return wrap_layout( - from_arraylib(array, regulararray, False), - highlevel=highlevel, - behavior=behavior, - ) + return wrap_layout( + from_arraylib(array, regulararray, False), + highlevel=highlevel, + behavior=behavior, + ) diff --git a/src/awkward/operations/ak_from_iter.py b/src/awkward/operations/ak_from_iter.py index a629f2bb24..5ab39aabb1 100644 --- a/src/awkward/operations/ak_from_iter.py +++ b/src/awkward/operations/ak_from_iter.py @@ -1,16 +1,17 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("from_iter",) - from collections.abc import Iterable from awkward_cpp.lib import _ext import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def from_iter( iterable, *, @@ -18,7 +19,7 @@ def from_iter( highlevel=True, behavior=None, initial=1024, - resize=1.5, + resize=8, ): """ Args: @@ -59,18 +60,7 @@ def from_iter( See also #ak.to_list. """ - with ak._errors.OperationErrorContext( - "ak.from_iter", - { - "iterable": iterable, - "allow_record": allow_record, - "highlevel": highlevel, - "behavior": behavior, - "initial": initial, - "resize": resize, - }, - ): - return _impl(iterable, highlevel, behavior, allow_record, initial, resize) + return _impl(iterable, highlevel, behavior, allow_record, initial, resize) def _impl(iterable, highlevel, behavior, allow_record, initial, resize): diff --git a/src/awkward/operations/ak_from_jax.py b/src/awkward/operations/ak_from_jax.py index 79518090df..6f77cfa6df 100644 --- a/src/awkward/operations/ak_from_jax.py +++ b/src/awkward/operations/ak_from_jax.py @@ -1,10 +1,11 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("from_jax",) - -from awkward import _errors, jax +from awkward import jax +from awkward._errors import with_operation_context from awkward._layout import from_arraylib, wrap_layout +@with_operation_context def from_jax(array, *, regulararray=False, highlevel=True, behavior=None): """ Args: @@ -29,18 +30,9 @@ def from_jax(array, *, regulararray=False, highlevel=True, behavior=None): See also #ak.to_jax, #ak.from_numpy and #ak.from_jax. """ - with _errors.OperationErrorContext( - "ak.from_jax", - { - "array": array, - "regulararray": regulararray, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - jax.assert_registered() - return wrap_layout( - from_arraylib(array, regulararray, False), - highlevel=highlevel, - behavior=behavior, - ) + jax.assert_registered() + return wrap_layout( + from_arraylib(array, regulararray, False), + highlevel=highlevel, + behavior=behavior, + ) diff --git a/src/awkward/operations/ak_from_json.py b/src/awkward/operations/ak_from_json.py index 0e0c26d760..c1ba994e7d 100644 --- a/src/awkward/operations/ak_from_json.py +++ b/src/awkward/operations/ak_from_json.py @@ -8,6 +8,7 @@ from awkward_cpp.lib import _ext import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyMetadata @@ -17,6 +18,7 @@ numpy = Numpy.instance() +@with_operation_context def from_json( source, *, @@ -28,7 +30,7 @@ def from_json( complex_record_fields=None, buffersize=65536, initial=1024, - resize=1.5, + resize=8, highlevel=True, behavior=None, ): @@ -319,53 +321,36 @@ def from_json( See also #ak.to_json. """ - with ak._errors.OperationErrorContext( - "ak.from_json", - { - "source": source, - "line_delimited": line_delimited, - "schema": schema, - "nan_string": nan_string, - "posinf_string": posinf_string, - "neginf_string": neginf_string, - "complex_record_fields": complex_record_fields, - "buffersize": buffersize, - "initial": initial, - "resize": resize, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if schema is None: - return _no_schema( - source, - line_delimited, - nan_string, - posinf_string, - neginf_string, - complex_record_fields, - buffersize, - initial, - resize, - highlevel, - behavior, - ) + if schema is None: + return _no_schema( + source, + line_delimited, + nan_string, + posinf_string, + neginf_string, + complex_record_fields, + buffersize, + initial, + resize, + highlevel, + behavior, + ) - else: - return _yes_schema( - source, - line_delimited, - schema, - nan_string, - posinf_string, - neginf_string, - complex_record_fields, - buffersize, - initial, - resize, - highlevel, - behavior, - ) + else: + return _yes_schema( + source, + line_delimited, + schema, + nan_string, + posinf_string, + neginf_string, + complex_record_fields, + buffersize, + initial, + resize, + highlevel, + behavior, + ) class _BytesReader: @@ -399,7 +384,7 @@ def __exit__(self, exception_type, exception_value, exception_traceback): def _get_reader(source): - if not isinstance(source, pathlib.Path) and isinstance(source, str): + if isinstance(source, str): source = source.encode("utf8", errors="surrogateescape") if isinstance(source, bytes): @@ -580,6 +565,7 @@ def _yes_schema( return layout +@with_operation_context def build_assembly(schema, container, instructions): if not isinstance(schema, dict): raise TypeError(f"unrecognized JSONSchema: expected dict, got {schema!r}") diff --git a/src/awkward/operations/ak_from_numpy.py b/src/awkward/operations/ak_from_numpy.py index e541f6a9d3..3f23fcbd31 100644 --- a/src/awkward/operations/ak_from_numpy.py +++ b/src/awkward/operations/ak_from_numpy.py @@ -1,9 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("from_numpy",) -import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import from_arraylib, wrap_layout +@with_operation_context def from_numpy( array, *, regulararray=False, recordarray=True, highlevel=True, behavior=None ): @@ -38,18 +39,8 @@ def from_numpy( See also #ak.to_numpy and #ak.from_cupy. """ - with ak._errors.OperationErrorContext( - "ak.from_numpy", - { - "array": array, - "regulararray": regulararray, - "recordarray": recordarray, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return wrap_layout( - from_arraylib(array, regulararray, recordarray), - highlevel=highlevel, - behavior=behavior, - ) + return wrap_layout( + from_arraylib(array, regulararray, recordarray), + highlevel=highlevel, + behavior=behavior, + ) diff --git a/src/awkward/operations/ak_from_parquet.py b/src/awkward/operations/ak_from_parquet.py index d28741d4a9..829717ca18 100644 --- a/src/awkward/operations/ak_from_parquet.py +++ b/src/awkward/operations/ak_from_parquet.py @@ -1,9 +1,12 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("from_parquet",) import awkward as ak +from awkward._errors import with_operation_context +from awkward._layout import wrap_layout from awkward._regularize import is_integer +@with_operation_context def from_parquet( path, *, @@ -50,44 +53,30 @@ def from_parquet( See also #ak.to_parquet, #ak.metadata_from_parquet. """ - with ak._errors.OperationErrorContext( - "ak.from_parquet", - { - "path": path, - "columns": columns, - "row_groups": row_groups, - "storage_options": storage_options, - "max_gap": max_gap, - "max_block": max_block, - "footer_sample_size": footer_sample_size, - "generate_bitmasks": generate_bitmasks, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - import awkward._connect.pyarrow # noqa: F401 - - parquet_columns, subform, actual_paths, fs, subrg, row_counts, meta = metadata( - path, - storage_options, - row_groups, - columns, - ) - return _load( - actual_paths, - parquet_columns if columns is not None else None, - subrg, - max_gap, - max_block, - footer_sample_size, - generate_bitmasks, - subform, - highlevel, - behavior, - fs, - ) + import awkward._connect.pyarrow # noqa: F401 + + parquet_columns, subform, actual_paths, fs, subrg, row_counts, meta = metadata( + path, + storage_options, + row_groups, + columns, + ) + return _load( + actual_paths, + parquet_columns if columns is not None else None, + subrg, + max_gap, + max_block, + footer_sample_size, + generate_bitmasks, + subform, + highlevel, + behavior, + fs, + ) +@with_operation_context def metadata( path, storage_options=None, @@ -230,7 +219,9 @@ def _load( ) if len(arrays) == 0: - return subform.length_zero_array(highlevel=highlevel, behavior=behavior) + return wrap_layout( + subform.length_zero_array(highlevel=False), behavior=behavior + ) elif len(arrays) == 1: # make high-level if isinstance(arrays[0], ak.record.Record): diff --git a/src/awkward/operations/ak_from_rdataframe.py b/src/awkward/operations/ak_from_rdataframe.py index 17666084c1..156c7b26d0 100644 --- a/src/awkward/operations/ak_from_rdataframe.py +++ b/src/awkward/operations/ak_from_rdataframe.py @@ -1,12 +1,13 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("from_rdataframe",) - import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def from_rdataframe( rdf, columns, @@ -45,21 +46,7 @@ def from_rdataframe( See also #ak.to_rdataframe. """ - with ak._errors.OperationErrorContext( - "ak.from_rdataframe", - { - "rdf": rdf, - "columns": columns, - "keep_order": keep_order, - "offsets_type": offsets_type, - "with_name": with_name, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl( - rdf, columns, highlevel, behavior, with_name, offsets_type, keep_order - ) + return _impl(rdf, columns, highlevel, behavior, with_name, offsets_type, keep_order) def _impl( diff --git a/src/awkward/operations/ak_from_regular.py b/src/awkward/operations/ak_from_regular.py index 739ed97274..92b837805c 100644 --- a/src/awkward/operations/ak_from_regular.py +++ b/src/awkward/operations/ak_from_regular.py @@ -2,6 +2,7 @@ __all__ = ("from_regular",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -9,6 +10,7 @@ np = NumpyMetadata.instance() +@with_operation_context def from_regular(array, axis=1, *, highlevel=True, behavior=None): """ Args: @@ -37,11 +39,7 @@ def from_regular(array, axis=1, *, highlevel=True, behavior=None): See also #ak.to_regular. """ - with ak._errors.OperationErrorContext( - "ak.from_regular", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): @@ -69,7 +67,7 @@ def action(layout, depth, **kwargs): elif posaxis == depth and layout.is_list: return layout elif layout.is_leaf: - raise np.AxisError( + raise AxisError( f"axis={axis} exceeds the depth of this array ({depth})" ) diff --git a/src/awkward/operations/ak_full_like.py b/src/awkward/operations/ak_full_like.py index e14d9a983d..faf4987f99 100644 --- a/src/awkward/operations/ak_full_like.py +++ b/src/awkward/operations/ak_full_like.py @@ -2,7 +2,8 @@ __all__ = ("full_like",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._nplikes.typetracer import ensure_known_scalar @@ -11,6 +12,7 @@ np = NumpyMetadata.instance() +@with_operation_context def full_like( array, fill_value, @@ -78,18 +80,7 @@ def full_like( (There is no equivalent of NumPy's `np.empty_like` because Awkward Arrays are immutable.) """ - with ak._errors.OperationErrorContext( - "ak.full_like", - { - "array": array, - "fill_value": fill_value, - "dtype": dtype, - "including_unknown": including_unknown, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, fill_value, highlevel, behavior, dtype, including_unknown) + return _impl(array, fill_value, highlevel, behavior, dtype, including_unknown) def _impl(array, fill_value, highlevel, behavior, dtype, including_unknown): @@ -213,6 +204,6 @@ def action(layout, backend, **kwargs): @ak._connect.numpy.implements("full_like") def _nep_18_impl( - a, fill_value, dtype=None, order=unsupported, subok=unsupported, shape=unsupported + a, fill_value, dtype=None, order=UNSUPPORTED, subok=UNSUPPORTED, shape=UNSUPPORTED ): return full_like(a, fill_value=fill_value, dtype=dtype) diff --git a/src/awkward/operations/ak_is_categorical.py b/src/awkward/operations/ak_is_categorical.py index c38691bb7b..e25e4ecf2a 100644 --- a/src/awkward/operations/ak_is_categorical.py +++ b/src/awkward/operations/ak_is_categorical.py @@ -1,9 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("is_categorical",) - import awkward as ak +from awkward._errors import with_operation_context +@with_operation_context def is_categorical(array): """ Args: @@ -16,11 +17,7 @@ def is_categorical(array): See also #ak.categories, #ak.to_categorical, #ak.from_categorical. """ - with ak._errors.OperationErrorContext( - "ak.is_categorical", - {"array": array}, - ): - return _impl(array) + return _impl(array) def _impl(array): diff --git a/src/awkward/operations/ak_is_none.py b/src/awkward/operations/ak_is_none.py index c2e04442f9..18488b1041 100644 --- a/src/awkward/operations/ak_is_none.py +++ b/src/awkward/operations/ak_is_none.py @@ -2,6 +2,7 @@ __all__ = ("is_none",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import is_integer, regularize_axis @@ -9,6 +10,7 @@ np = NumpyMetadata.instance() +@with_operation_context def is_none(array, axis=0, *, highlevel=True, behavior=None): """ Args: @@ -25,11 +27,7 @@ def is_none(array, axis=0, *, highlevel=True, behavior=None): Returns an array whose value is True where an element of `array` is None; False otherwise (at a given `axis` depth). """ - with ak._errors.OperationErrorContext( - "ak.is_none", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): @@ -57,7 +55,7 @@ def action(layout, depth, lateral_context, **kwargs): ) elif layout.is_leaf: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") out = ak._do.recursively_apply(layout, action, behavior, numpy_to_regular=True) diff --git a/src/awkward/operations/ak_is_tuple.py b/src/awkward/operations/ak_is_tuple.py index c41c739b04..d059ad384e 100644 --- a/src/awkward/operations/ak_is_tuple.py +++ b/src/awkward/operations/ak_is_tuple.py @@ -1,9 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("is_tuple",) - import awkward as ak +from awkward._errors import with_operation_context +@with_operation_context def is_tuple(array): """ Args: @@ -12,11 +13,7 @@ def is_tuple(array): If `array` is a record, this returns True if the record is a tuple. If `array` is an array, this returns True if the outermost record is a tuple. """ - with ak._errors.OperationErrorContext( - "ak.is_tuple", - {"array": array}, - ): - return _impl(array) + return _impl(array) def _impl(array): diff --git a/src/awkward/operations/ak_is_valid.py b/src/awkward/operations/ak_is_valid.py index ea8d46eadf..677aeb5284 100644 --- a/src/awkward/operations/ak_is_valid.py +++ b/src/awkward/operations/ak_is_valid.py @@ -1,9 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("is_valid",) - import awkward as ak +from awkward._errors import with_operation_context +@with_operation_context def is_valid(array, *, exception=False): """ Args: @@ -18,11 +19,7 @@ def is_valid(array, *, exception=False): See also #ak.validity_error. """ - with ak._errors.OperationErrorContext( - "ak.is_valid", - {"array": array, "exception": exception}, - ): - return _impl(array, exception) + return _impl(array, exception) def _impl(array, exception): diff --git a/src/awkward/operations/ak_isclose.py b/src/awkward/operations/ak_isclose.py index 3cd838563e..a9fa2f4709 100644 --- a/src/awkward/operations/ak_isclose.py +++ b/src/awkward/operations/ak_isclose.py @@ -2,12 +2,14 @@ __all__ = ("isclose",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def isclose( a, b, rtol=1e-05, atol=1e-08, equal_nan=False, *, highlevel=True, behavior=None ): @@ -27,19 +29,7 @@ def isclose( Implements [np.isclose](https://numpy.org/doc/stable/reference/generated/numpy.isclose.html) for Awkward Arrays. """ - with ak._errors.OperationErrorContext( - "ak.isclose", - { - "a": a, - "b": b, - "rtol": rtol, - "atol": atol, - "equal_nan": equal_nan, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(a, b, rtol, atol, equal_nan, highlevel, behavior) + return _impl(a, b, rtol, atol, equal_nan, highlevel, behavior) def _impl(a, b, rtol, atol, equal_nan, highlevel, behavior): diff --git a/src/awkward/operations/ak_linear_fit.py b/src/awkward/operations/ak_linear_fit.py index 9e37855751..2ed836fa93 100644 --- a/src/awkward/operations/ak_linear_fit.py +++ b/src/awkward/operations/ak_linear_fit.py @@ -3,15 +3,16 @@ import awkward as ak from awkward._backends.dispatch import backend_of from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes import ufuncs from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def linear_fit( x, y, @@ -20,7 +21,6 @@ def linear_fit( *, keepdims=False, mask_identity=False, - flatten_records=unset, ): """ Args: @@ -43,8 +43,6 @@ def linear_fit( empty lists results in None (an option type); otherwise, the calculation is followed through with the reducers' identities, usually resulting in floating-point `nan`. - flatten_records (bool): If True, axis=None combines fields from - different records; otherwise, records raise an error. Computes the linear fit of `y` with respect to `x` (many types supported, including all Awkward Arrays and Records, must be broadcastable to each @@ -76,18 +74,7 @@ def linear_fit( missing values (None) in reducers, and #ak.mean for an example with another non-reducer. """ - with ak._errors.OperationErrorContext( - "ak.linear_fit", - { - "x": x, - "y": y, - "weight": weight, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - return _impl(x, y, weight, axis, keepdims, mask_identity) + return _impl(x, y, weight, axis, keepdims, mask_identity) def _impl(x, y, weight, axis, keepdims, mask_identity): diff --git a/src/awkward/operations/ak_local_index.py b/src/awkward/operations/ak_local_index.py index f4656218f7..aa095be4b6 100644 --- a/src/awkward/operations/ak_local_index.py +++ b/src/awkward/operations/ak_local_index.py @@ -1,6 +1,7 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("local_index",) import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -8,6 +9,7 @@ np = NumpyMetadata.instance() +@with_operation_context def local_index(array, axis=-1, *, highlevel=True, behavior=None): """ Args: @@ -72,11 +74,7 @@ def local_index(array, axis=-1, *, highlevel=True, behavior=None): 2 8.8 3 9.9 """ - with ak._errors.OperationErrorContext( - "ak.local_index", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): diff --git a/src/awkward/operations/ak_mask.py b/src/awkward/operations/ak_mask.py index cdcec31105..46c27aa772 100644 --- a/src/awkward/operations/ak_mask.py +++ b/src/awkward/operations/ak_mask.py @@ -2,12 +2,14 @@ __all__ = ("mask",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def mask(array, mask, *, valid_when=True, highlevel=True, behavior=None): """ Args: @@ -88,17 +90,7 @@ def mask(array, mask, *, valid_when=True, highlevel=True, behavior=None): (which is 5 characters away from simply filtering the `array`). """ - with ak._errors.OperationErrorContext( - "ak.mask", - { - "array": array, - "mask": mask, - "valid_when": valid_when, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, mask, valid_when, highlevel, behavior) + return _impl(array, mask, valid_when, highlevel, behavior) def _impl(array, mask, valid_when, highlevel, behavior): @@ -107,7 +99,7 @@ def action(inputs, backend, **kwargs): if isinstance(layoutmask, ak.contents.NumpyArray): m = backend.nplike.asarray(layoutmask) if not issubclass(m.dtype.type, (bool, np.bool_)): - raise ValueError(f"mask must have boolean type, not {repr(m.dtype)}") + raise ValueError(f"mask must have boolean type, not {m.dtype!r}") bytemask = ak.index.Index8(m.view(np.int8)) return ( ak.contents.ByteMaskedArray.simplified( diff --git a/src/awkward/operations/ak_max.py b/src/awkward/operations/ak_max.py index 8735ef8f7d..5b43ab1ab7 100644 --- a/src/awkward/operations/ak_max.py +++ b/src/awkward/operations/ak_max.py @@ -2,15 +2,16 @@ __all__ = ("max",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def max( array, axis=None, @@ -18,7 +19,6 @@ def max( keepdims=False, initial=None, mask_identity=True, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -61,39 +61,18 @@ def max( See also #ak.nanmax. """ - with ak._errors.OperationErrorContext( - "ak.max", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "initial": initial, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl( - array, - axis, - keepdims, - initial, - mask_identity, - highlevel, - behavior, - ) + return _impl( + array, + axis, + keepdims, + initial, + mask_identity, + highlevel, + behavior, + ) +@with_operation_context def nanmax( array, axis=None, @@ -101,7 +80,6 @@ def nanmax( keepdims=False, initial=None, mask_identity=True, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -135,39 +113,15 @@ def nanmax( See also #ak.max. """ - with ak._errors.OperationErrorContext( - "ak.nanmax", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "initial": initial, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - array = ak.operations.ak_nan_to_none._impl(array, False, None) - - return _impl( - array, - axis, - keepdims, - initial, - mask_identity, - highlevel, - behavior, - ) + return _impl( + ak.operations.ak_nan_to_none._impl(array, False, None), + axis, + keepdims, + initial, + mask_identity, + highlevel, + behavior, + ) def _impl(array, axis, keepdims, initial, mask_identity, highlevel, behavior): @@ -192,13 +146,13 @@ def _impl(array, axis, keepdims, initial, mask_identity, highlevel, behavior): @ak._connect.numpy.implements("amax") def _nep_18_impl_amax( - a, axis=None, out=unsupported, keepdims=False, initial=None, where=unsupported + a, axis=None, out=UNSUPPORTED, keepdims=False, initial=None, where=UNSUPPORTED ): return max(a, axis=axis, keepdims=keepdims, initial=initial) @ak._connect.numpy.implements("nanmax") def _nep_18_impl_nanmax( - a, axis=None, out=unsupported, keepdims=False, initial=None, where=unsupported + a, axis=None, out=UNSUPPORTED, keepdims=False, initial=None, where=UNSUPPORTED ): return nanmax(a, axis=axis, keepdims=keepdims, initial=initial) diff --git a/src/awkward/operations/ak_mean.py b/src/awkward/operations/ak_mean.py index cc9d98a77f..f0d37cafef 100644 --- a/src/awkward/operations/ak_mean.py +++ b/src/awkward/operations/ak_mean.py @@ -2,15 +2,16 @@ __all__ = ("mean",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import maybe_posaxis from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def mean( x, weight=None, @@ -18,7 +19,6 @@ def mean( *, keepdims=False, mask_identity=False, - flatten_records=unset, ): """ Args: @@ -82,29 +82,10 @@ def mean( See also #ak.nanmean. """ - with ak._errors.OperationErrorContext( - "ak.mean", - { - "x": x, - "weight": weight, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(x, weight, axis, keepdims, mask_identity) + return _impl(x, weight, axis, keepdims, mask_identity) +@with_operation_context def nanmean( x, weight=None, @@ -112,7 +93,6 @@ def nanmean( *, keepdims=False, mask_identity=True, - flatten_records=unset, ): """ Args: @@ -145,31 +125,16 @@ def nanmean( See also #ak.mean. """ - with ak._errors.OperationErrorContext( - "ak.nanmean", - { - "x": x, - "weight": weight, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - x = ak.operations.ak_nan_to_none._impl(x, False, None) - if weight is not None: - weight = ak.operations.ak_nan_to_none._impl(weight, False, None) - - return _impl(x, weight, axis, keepdims, mask_identity) + if weight is not None: + weight = ak.operations.ak_nan_to_none._impl(weight, False, None) + + return _impl( + ak.operations.ak_nan_to_none._impl(x, False, None), + weight, + axis, + keepdims, + mask_identity, + ) def _impl(x, weight, axis, keepdims, mask_identity): @@ -241,11 +206,11 @@ def _impl(x, weight, axis, keepdims, mask_identity): def _nep_18_impl_mean( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, keepdims=False, *, - where=unsupported, + where=UNSUPPORTED, ): return mean(a, axis=axis, keepdims=keepdims) @@ -254,10 +219,10 @@ def _nep_18_impl_mean( def _nep_18_impl_nanmean( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, keepdims=False, *, - where=unsupported, + where=UNSUPPORTED, ): return nanmean(a, axis=axis, keepdims=keepdims) diff --git a/src/awkward/operations/ak_merge_option_of_records.py b/src/awkward/operations/ak_merge_option_of_records.py index d8c0f3621b..915e7050fc 100644 --- a/src/awkward/operations/ak_merge_option_of_records.py +++ b/src/awkward/operations/ak_merge_option_of_records.py @@ -3,6 +3,7 @@ import awkward as ak from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -11,6 +12,7 @@ cpu = NumpyBackend.instance() +@with_operation_context def merge_option_of_records(array, axis=-1, *, highlevel=True, behavior=None): """ Args: @@ -33,11 +35,7 @@ def merge_option_of_records(array, axis=-1, *, highlevel=True, behavior=None): >>> ak.merge_option_of_records(array) """ - with ak._errors.OperationErrorContext( - "ak.merge_option_of_records", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): @@ -68,7 +66,7 @@ def apply_displace_index(layout, backend, **kwargs): def apply(layout, depth, backend, **kwargs): posaxis = maybe_posaxis(layout, axis, depth) if depth < posaxis + 1 and layout.is_leaf: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") elif depth == posaxis + 1 and layout.is_option and layout.content.is_record: layout = layout.to_IndexedOptionArray64() diff --git a/src/awkward/operations/ak_merge_union_of_records.py b/src/awkward/operations/ak_merge_union_of_records.py index 3a54f1004f..ffc7fc888f 100644 --- a/src/awkward/operations/ak_merge_union_of_records.py +++ b/src/awkward/operations/ak_merge_union_of_records.py @@ -3,6 +3,7 @@ import awkward as ak from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import ArrayLike, NumpyMetadata from awkward._regularize import regularize_axis @@ -11,6 +12,7 @@ cpu = NumpyBackend.instance() +@with_operation_context def merge_union_of_records(array, axis=-1, *, highlevel=True, behavior=None): """ Args: @@ -43,11 +45,7 @@ def merge_union_of_records(array, axis=-1, *, highlevel=True, behavior=None): >>> ak.merge_union_of_records(array) """ - with ak._errors.OperationErrorContext( - "ak.merge_union_of_records", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): @@ -155,7 +153,7 @@ def compact_option_index(index: ArrayLike, *, backend) -> ArrayLike: def apply(layout, depth, backend, **kwargs): posaxis = maybe_posaxis(layout, axis, depth) if depth < posaxis + 1 and layout.is_leaf: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") elif depth == posaxis + 1 and layout.is_union: if not all( x.is_record or x.is_indexed or x.is_option for x in layout.contents diff --git a/src/awkward/operations/ak_metadata_from_parquet.py b/src/awkward/operations/ak_metadata_from_parquet.py index f0034ede3d..00cb52d4d7 100644 --- a/src/awkward/operations/ak_metadata_from_parquet.py +++ b/src/awkward/operations/ak_metadata_from_parquet.py @@ -1,9 +1,9 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("metadata_from_parquet",) - import collections import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() @@ -15,6 +15,7 @@ ) +@with_operation_context def metadata_from_parquet( path, *, @@ -59,20 +60,13 @@ def metadata_from_parquet( """ import awkward._connect.pyarrow # noqa: F401 - with ak._errors.OperationErrorContext( - "ak.metadata_from_parquet", - { - "path": path, - "storage_options": storage_options, - }, - ): - return _impl( - path, - storage_options, - row_groups=row_groups, - ignore_metadata=ignore_metadata, - scan_files=scan_files, - ) + return _impl( + path, + storage_options, + row_groups=row_groups, + ignore_metadata=ignore_metadata, + scan_files=scan_files, + ) def _impl( diff --git a/src/awkward/operations/ak_min.py b/src/awkward/operations/ak_min.py index 13c3bfad99..d976cb5a7d 100644 --- a/src/awkward/operations/ak_min.py +++ b/src/awkward/operations/ak_min.py @@ -2,15 +2,16 @@ __all__ = ("min",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def min( array, axis=None, @@ -18,7 +19,6 @@ def min( keepdims=False, initial=None, mask_identity=True, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -61,37 +61,18 @@ def min( See also #ak.nanmin. """ - with ak._errors.OperationErrorContext( - "ak.min", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "initial": initial, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl( - array, - axis, - keepdims, - initial, - mask_identity, - highlevel, - behavior, - ) + return _impl( + array, + axis, + keepdims, + initial, + mask_identity, + highlevel, + behavior, + ) +@with_operation_context def nanmin( array, axis=None, @@ -99,7 +80,6 @@ def nanmin( keepdims=False, initial=None, mask_identity=True, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -133,39 +113,15 @@ def nanmin( See also #ak.min. """ - with ak._errors.OperationErrorContext( - "ak.nanmin", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "initial": initial, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - array = ak.operations.ak_nan_to_none._impl(array, False, None) - - return _impl( - array, - axis, - keepdims, - initial, - mask_identity, - highlevel, - behavior, - ) + return _impl( + ak.operations.ak_nan_to_none._impl(array, False, None), + axis, + keepdims, + initial, + mask_identity, + highlevel, + behavior, + ) def _impl(array, axis, keepdims, initial, mask_identity, highlevel, behavior): @@ -192,10 +148,10 @@ def _impl(array, axis, keepdims, initial, mask_identity, highlevel, behavior): def _nep_18_impl_amin( a, axis=None, - out=unsupported, + out=UNSUPPORTED, keepdims=False, initial=None, - where=unsupported, + where=UNSUPPORTED, ): return min(a, axis=axis, keepdims=keepdims, initial=initial) @@ -204,9 +160,9 @@ def _nep_18_impl_amin( def _nep_18_impl_nanmin( a, axis=None, - out=unsupported, + out=UNSUPPORTED, keepdims=False, initial=None, - where=unsupported, + where=UNSUPPORTED, ): return nanmin(a, axis=axis, keepdims=keepdims, initial=initial) diff --git a/src/awkward/operations/ak_moment.py b/src/awkward/operations/ak_moment.py index 3e5be46688..a1d1792b23 100644 --- a/src/awkward/operations/ak_moment.py +++ b/src/awkward/operations/ak_moment.py @@ -2,13 +2,14 @@ __all__ = ("moment",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def moment( x, n, @@ -17,7 +18,6 @@ def moment( *, keepdims=False, mask_identity=False, - flatten_records=unset, ): """ Args: @@ -60,28 +60,7 @@ def moment( missing values (None) in reducers, and #ak.mean for an example with another non-reducer. """ - with ak._errors.OperationErrorContext( - "ak.moment", - { - "x": x, - "n": n, - "weight": weight, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(x, n, weight, axis, keepdims, mask_identity) + return _impl(x, n, weight, axis, keepdims, mask_identity) def _impl(x, n, weight, axis, keepdims, mask_identity): diff --git a/src/awkward/operations/ak_nan_to_none.py b/src/awkward/operations/ak_nan_to_none.py index d5c87703a6..5e6693b27a 100644 --- a/src/awkward/operations/ak_nan_to_none.py +++ b/src/awkward/operations/ak_nan_to_none.py @@ -2,12 +2,14 @@ __all__ = ("nan_to_none",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def nan_to_none(array, *, highlevel=True, behavior=None): """ Args: @@ -21,15 +23,7 @@ def nan_to_none(array, *, highlevel=True, behavior=None): See also #ak.nan_to_num to convert NaN or infinity to specified values. """ - with ak._errors.OperationErrorContext( - "ak.nan_to_none", - { - "array": array, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, highlevel, behavior) + return _impl(array, highlevel, behavior) def _impl(array, highlevel, behavior): diff --git a/src/awkward/operations/ak_nan_to_num.py b/src/awkward/operations/ak_nan_to_num.py index a9bb2315c9..913a9f6e5f 100644 --- a/src/awkward/operations/ak_nan_to_num.py +++ b/src/awkward/operations/ak_nan_to_num.py @@ -2,12 +2,14 @@ __all__ = ("nan_to_num",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def nan_to_num( array, copy=True, @@ -37,19 +39,7 @@ def nan_to_num( See also #ak.nan_to_none to convert NaN to None, i.e. missing values with option-type. """ - with ak._errors.OperationErrorContext( - "ak.nan_to_num", - { - "array": array, - "copy": copy, - "nan": nan, - "posinf": posinf, - "neginf": neginf, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, copy, nan, posinf, neginf, highlevel, behavior) + return _impl(array, copy, nan, posinf, neginf, highlevel, behavior) def _impl(array, copy, nan, posinf, neginf, highlevel, behavior): diff --git a/src/awkward/operations/ak_num.py b/src/awkward/operations/ak_num.py index bf99a42388..fc76e68c8d 100644 --- a/src/awkward/operations/ak_num.py +++ b/src/awkward/operations/ak_num.py @@ -2,6 +2,7 @@ __all__ = ("num",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import is_integer, regularize_axis @@ -9,6 +10,7 @@ np = NumpyMetadata.instance() +@with_operation_context def num(array, axis=1, *, highlevel=True, behavior=None): """ Args: @@ -68,11 +70,7 @@ def num(array, axis=1, *, highlevel=True, behavior=None): >>> array.mask[ak.num(array) > 0][:, 0] """ - with ak._errors.OperationErrorContext( - "ak.num", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): @@ -96,7 +94,7 @@ def action(layout, depth, **kwargs): return ak.contents.NumpyArray(layout.stops.data - layout.starts.data) elif layout.is_leaf: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") out = ak._do.recursively_apply(layout, action, behavior, numpy_to_regular=True) diff --git a/src/awkward/operations/ak_ones_like.py b/src/awkward/operations/ak_ones_like.py index c8cce94e0a..2c61078e5c 100644 --- a/src/awkward/operations/ak_ones_like.py +++ b/src/awkward/operations/ak_ones_like.py @@ -1,13 +1,14 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("ones_like",) - import awkward as ak -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def ones_like( array, *, dtype=None, including_unknown=False, highlevel=True, behavior=None ): @@ -30,17 +31,7 @@ def ones_like( (There is no equivalent of NumPy's `np.empty_like` because Awkward Arrays are immutable.) """ - with ak._errors.OperationErrorContext( - "ak.ones_like", - { - "array": array, - "dtype": dtype, - "including_unknown": including_unknown, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, highlevel, behavior, dtype, including_unknown) + return _impl(array, highlevel, behavior, dtype, including_unknown) def _impl(array, highlevel, behavior, dtype, including_unknown): @@ -51,6 +42,6 @@ def _impl(array, highlevel, behavior, dtype, including_unknown): @ak._connect.numpy.implements("ones_like") def _nep_18_impl( - a, dtype=None, order=unsupported, subok=unsupported, shape=unsupported + a, dtype=None, order=UNSUPPORTED, subok=UNSUPPORTED, shape=UNSUPPORTED ): return ones_like(a, dtype=dtype) diff --git a/src/awkward/operations/ak_pad_none.py b/src/awkward/operations/ak_pad_none.py index db3b289485..cf0cef78b6 100644 --- a/src/awkward/operations/ak_pad_none.py +++ b/src/awkward/operations/ak_pad_none.py @@ -1,6 +1,7 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("pad_none",) import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -8,6 +9,7 @@ np = NumpyMetadata.instance() +@with_operation_context def pad_none(array, target, axis=1, *, clip=False, highlevel=True, behavior=None): """ Args: @@ -95,18 +97,7 @@ def pad_none(array, target, axis=1, *, clip=False, highlevel=True, behavior=None >>> ak.pad_none(array, 2, axis=2, clip=True).type.show() 3 * var * 2 * ?float64 """ - with ak._errors.OperationErrorContext( - "ak.pad_none", - { - "array": array, - "target": target, - "axis": axis, - "clip": clip, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, target, axis, clip, highlevel, behavior) + return _impl(array, target, axis, clip, highlevel, behavior) def _impl(array, target, axis, clip, highlevel, behavior): diff --git a/src/awkward/operations/ak_parameters.py b/src/awkward/operations/ak_parameters.py index cb0bfa6aa9..862245b691 100644 --- a/src/awkward/operations/ak_parameters.py +++ b/src/awkward/operations/ak_parameters.py @@ -1,17 +1,18 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("parameters",) - import copy import numbers from awkward_cpp.lib import _ext import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def parameters(array): """ Args: @@ -28,11 +29,7 @@ def parameters(array): See #ak.Array and #ak.behavior for a more complete description of behaviors. """ - with ak._errors.OperationErrorContext( - "ak.parameters", - {"array": array}, - ): - return _impl(array) + return _impl(array) def _impl(array): diff --git a/src/awkward/operations/ak_prod.py b/src/awkward/operations/ak_prod.py index 6b7aee570d..8d43c236ca 100644 --- a/src/awkward/operations/ak_prod.py +++ b/src/awkward/operations/ak_prod.py @@ -2,22 +2,22 @@ __all__ = ("prod",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def prod( array, axis=None, *, keepdims=False, mask_identity=False, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -53,37 +53,16 @@ def prod( See also #ak.nanprod. """ - with ak._errors.OperationErrorContext( - "ak.prod", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) +@with_operation_context def nanprod( array, axis=None, *, keepdims=False, mask_identity=False, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -113,30 +92,14 @@ def nanprod( See also #ak.prod. """ - with ak._errors.OperationErrorContext( - "ak.nanprod", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - array = ak.operations.ak_nan_to_none._impl(array, False, None) - - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl( + ak.operations.ak_nan_to_none._impl(array, False, None), + axis, + keepdims, + mask_identity, + highlevel, + behavior, + ) def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @@ -163,11 +126,11 @@ def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): def _nep_18_impl_prod( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, keepdims=False, - initial=unsupported, - where=unsupported, + initial=UNSUPPORTED, + where=UNSUPPORTED, ): return prod(a, axis=axis, keepdims=keepdims) @@ -176,10 +139,10 @@ def _nep_18_impl_prod( def _nep_18_impl_nanprod( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, keepdims=False, - initial=unsupported, - where=unsupported, + initial=UNSUPPORTED, + where=UNSUPPORTED, ): return nanprod(a, axis=axis, keepdims=keepdims) diff --git a/src/awkward/operations/ak_ptp.py b/src/awkward/operations/ak_ptp.py index f6019c6172..f55eda3ca3 100644 --- a/src/awkward/operations/ak_ptp.py +++ b/src/awkward/operations/ak_ptp.py @@ -2,16 +2,17 @@ __all__ = ("ptp",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import maybe_posaxis from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() -def ptp(array, axis=None, *, keepdims=False, mask_identity=True, flatten_records=unset): +@with_operation_context +def ptp(array, axis=None, *, keepdims=False, mask_identity=True): """ Args: array: Array-like data (anything #ak.to_layout recognizes). @@ -58,26 +59,7 @@ def ptp(array, axis=None, *, keepdims=False, mask_identity=True, flatten_records See #ak.sum for a more complete description of nested list and missing value (None) handling in reducers. """ - with ak._errors.OperationErrorContext( - "ak.ptp", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(array, axis, keepdims, mask_identity) + return _impl(array, axis, keepdims, mask_identity) def _impl(array, axis, keepdims, mask_identity): @@ -124,5 +106,5 @@ def _impl(array, axis, keepdims, mask_identity): @ak._connect.numpy.implements("ptp") -def _nep_18_impl(a, axis=None, out=unsupported, keepdims=False): +def _nep_18_impl(a, axis=None, out=UNSUPPORTED, keepdims=False): return ptp(a, axis=axis, keepdims=keepdims) diff --git a/src/awkward/operations/ak_ravel.py b/src/awkward/operations/ak_ravel.py index 8d85e3cd0a..7b27a7e016 100644 --- a/src/awkward/operations/ak_ravel.py +++ b/src/awkward/operations/ak_ravel.py @@ -1,13 +1,15 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("ravel",) import awkward as ak -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def ravel(array, *, highlevel=True, behavior=None): """ Args: @@ -49,11 +51,7 @@ def ravel(array, *, highlevel=True, behavior=None): Missing values are not eliminated by flattening. See #ak.flatten with `axis=None` for an equivalent function that eliminates the option type. """ - with ak._errors.OperationErrorContext( - "ak.ravel", - {"array": array, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, highlevel, behavior) + return _impl(array, highlevel, behavior) def _impl(array, highlevel, behavior): @@ -70,5 +68,5 @@ def _impl(array, highlevel, behavior): @ak._connect.numpy.implements("ravel") -def _nep_18_impl(a, order=unsupported): +def _nep_18_impl(a, order=UNSUPPORTED): return ravel(a) diff --git a/src/awkward/operations/ak_run_lengths.py b/src/awkward/operations/ak_run_lengths.py index 0110df71d7..facf139851 100644 --- a/src/awkward/operations/ak_run_lengths.py +++ b/src/awkward/operations/ak_run_lengths.py @@ -4,6 +4,7 @@ from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._nplikes.shape import unknown_length @@ -12,6 +13,7 @@ cpu = NumpyBackend.instance() +@with_operation_context def run_lengths(array, *, highlevel=True, behavior=None): """ Args: @@ -86,15 +88,7 @@ def run_lengths(array, *, highlevel=True, behavior=None): See also #ak.num, #ak.argsort, #ak.unflatten. """ - with ak._errors.OperationErrorContext( - "ak.run_lengths", - { - "array": array, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, highlevel, behavior) + return _impl(array, highlevel, behavior) def _impl(array, highlevel, behavior): diff --git a/src/awkward/operations/ak_singletons.py b/src/awkward/operations/ak_singletons.py index 5f44340293..eb4ece2431 100644 --- a/src/awkward/operations/ak_singletons.py +++ b/src/awkward/operations/ak_singletons.py @@ -2,6 +2,7 @@ __all__ = ("singletons",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import is_integer, regularize_axis @@ -9,6 +10,7 @@ np = NumpyMetadata.instance() +@with_operation_context def singletons(array, axis=0, *, highlevel=True, behavior=None): """ Args: @@ -40,11 +42,7 @@ def singletons(array, axis=0, *, highlevel=True, behavior=None): See #ak.firsts to invert this function. """ - with ak._errors.OperationErrorContext( - "ak.singletons", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): @@ -80,7 +78,7 @@ def action(layout, depth, **kwargs): return ak.contents.RegularArray(layout, 1).to_ListOffsetArray64(True) elif layout.is_leaf: - raise np.AxisError(f"axis={axis} exceeds the depth of this array ({depth})") + raise AxisError(f"axis={axis} exceeds the depth of this array ({depth})") out = ak._do.recursively_apply(layout, action, behavior, numpy_to_regular=True) diff --git a/src/awkward/operations/ak_softmax.py b/src/awkward/operations/ak_softmax.py index 95c920c384..0cf9db49c7 100644 --- a/src/awkward/operations/ak_softmax.py +++ b/src/awkward/operations/ak_softmax.py @@ -2,17 +2,16 @@ __all__ = ("softmax",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._nplikes import ufuncs from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() -def softmax( - x, axis=None, *, keepdims=False, mask_identity=False, flatten_records=unset -): +@with_operation_context +def softmax(x, axis=None, *, keepdims=False, mask_identity=False): """ Args: x: The data on which to compute the softmax (anything #ak.to_layout recognizes). @@ -45,26 +44,7 @@ def softmax( missing values (None) in reducers, and #ak.mean for an example with another non-reducer. """ - with ak._errors.OperationErrorContext( - "ak.softmax", - { - "x": x, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(x, axis, keepdims, mask_identity) + return _impl(x, axis, keepdims, mask_identity) def _impl(x, axis, keepdims, mask_identity): diff --git a/src/awkward/operations/ak_sort.py b/src/awkward/operations/ak_sort.py index 02762007dc..e660c1b31b 100644 --- a/src/awkward/operations/ak_sort.py +++ b/src/awkward/operations/ak_sort.py @@ -1,7 +1,8 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("sort",) import awkward as ak -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -9,6 +10,7 @@ np = NumpyMetadata.instance() +@with_operation_context def sort(array, axis=-1, *, ascending=True, stable=True, highlevel=True, behavior=None): """ Args: @@ -34,18 +36,7 @@ def sort(array, axis=-1, *, ascending=True, stable=True, highlevel=True, behavio >>> ak.sort(ak.Array([[7, 5, 7], [], [2], [8, 2]])) """ - with ak._errors.OperationErrorContext( - "ak.sort", - { - "array": array, - "axis": axis, - "ascending": ascending, - "stable": stable, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, axis, ascending, stable, highlevel, behavior) + return _impl(array, axis, ascending, stable, highlevel, behavior) def _impl(array, axis, ascending, stable, highlevel, behavior): @@ -56,7 +47,7 @@ def _impl(array, axis, ascending, stable, highlevel, behavior): @ak._connect.numpy.implements("sort") -def _nep_18_impl(a, axis=-1, kind=None, order=unsupported): +def _nep_18_impl(a, axis=-1, kind=None, order=UNSUPPORTED): if kind is None: stable = False elif kind in ("stable", "mergesort"): diff --git a/src/awkward/operations/ak_std.py b/src/awkward/operations/ak_std.py index 7507441ed8..9271b8249a 100644 --- a/src/awkward/operations/ak_std.py +++ b/src/awkward/operations/ak_std.py @@ -2,16 +2,17 @@ __all__ = ("std",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import maybe_posaxis from awkward._nplikes import ufuncs from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def std( x, weight=None, @@ -20,7 +21,6 @@ def std( *, keepdims=False, mask_identity=False, - flatten_records=unset, ): """ Args: @@ -65,30 +65,10 @@ def std( See also #ak.nanstd. """ - with ak._errors.OperationErrorContext( - "ak.std", - { - "x": x, - "weight": weight, - "ddof": ddof, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(x, weight, ddof, axis, keepdims, mask_identity) + return _impl(x, weight, ddof, axis, keepdims, mask_identity) +@with_operation_context def nanstd( x, weight=None, @@ -97,7 +77,6 @@ def nanstd( *, keepdims=False, mask_identity=True, - flatten_records=unset, ): """ Args: @@ -133,32 +112,17 @@ def nanstd( See also #ak.std. """ - with ak._errors.OperationErrorContext( - "ak.nanstd", - { - "x": x, - "weight": weight, - "ddof": ddof, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - x = ak.operations.ak_nan_to_none._impl(x, False, None) - if weight is not None: - weight = ak.operations.ak_nan_to_none._impl(weight, False, None) - - return _impl(x, weight, ddof, axis, keepdims, mask_identity) + if weight is not None: + weight = ak.operations.ak_nan_to_none._impl(weight, False, None) + + return _impl( + ak.operations.ak_nan_to_none._impl(x, False, None), + weight, + ddof, + axis, + keepdims, + mask_identity, + ) def _impl(x, weight, ddof, axis, keepdims, mask_identity): @@ -204,12 +168,12 @@ def _impl(x, weight, ddof, axis, keepdims, mask_identity): def _nep_18_impl_std( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, ddof=0, keepdims=False, *, - where=unsupported, + where=UNSUPPORTED, ): return std(a, axis=axis, keepdims=keepdims, ddof=ddof) @@ -218,11 +182,11 @@ def _nep_18_impl_std( def _nep_18_impl_nanstd( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, ddof=0, keepdims=False, *, - where=unsupported, + where=UNSUPPORTED, ): return nanstd(a, axis=axis, keepdims=keepdims, ddof=ddof) diff --git a/src/awkward/operations/ak_strings_astype.py b/src/awkward/operations/ak_strings_astype.py index 4b6a0811b8..e128b5a5d3 100644 --- a/src/awkward/operations/ak_strings_astype.py +++ b/src/awkward/operations/ak_strings_astype.py @@ -2,6 +2,7 @@ __all__ = ("strings_astype",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyMetadata @@ -10,6 +11,7 @@ numpy = Numpy.instance() +@with_operation_context def strings_astype(array, to, *, highlevel=True, behavior=None): """ Args: @@ -43,11 +45,7 @@ def strings_astype(array, to, *, highlevel=True, behavior=None): See also #ak.numbers_astype. """ - with ak._errors.OperationErrorContext( - "ak.strings_astype", - {"array": array, "to": to, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, to, highlevel, behavior) + return _impl(array, to, highlevel, behavior) def _impl(array, to, highlevel, behavior): diff --git a/src/awkward/operations/ak_sum.py b/src/awkward/operations/ak_sum.py index 2df5de72e8..24f1e4b01c 100644 --- a/src/awkward/operations/ak_sum.py +++ b/src/awkward/operations/ak_sum.py @@ -2,22 +2,22 @@ __all__ = ("sum",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def sum( array, axis=None, *, keepdims=False, mask_identity=False, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -197,37 +197,16 @@ def sum( See also #ak.nansum. """ - with ak._errors.OperationErrorContext( - "ak.sum", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) +@with_operation_context def nansum( array, axis=None, *, keepdims=False, mask_identity=False, - flatten_records=unset, highlevel=True, behavior=None, ): @@ -261,30 +240,14 @@ def nansum( See also #ak.sum. """ - with ak._errors.OperationErrorContext( - "ak.nansum", - { - "array": array, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - array = ak.operations.ak_nan_to_none._impl(array, False, None) - - return _impl(array, axis, keepdims, mask_identity, highlevel, behavior) + return _impl( + ak.operations.ak_nan_to_none._impl(array, False, None), + axis, + keepdims, + mask_identity, + highlevel, + behavior, + ) def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): @@ -311,11 +274,11 @@ def _impl(array, axis, keepdims, mask_identity, highlevel, behavior): def _nep_18_impl_sum( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, keepdims=False, - initial=unsupported, - where=unsupported, + initial=UNSUPPORTED, + where=UNSUPPORTED, ): return sum(a, axis=axis, keepdims=keepdims) @@ -324,10 +287,10 @@ def _nep_18_impl_sum( def _nep_18_impl_nansum( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, keepdims=False, - initial=unsupported, - where=unsupported, + initial=UNSUPPORTED, + where=UNSUPPORTED, ): return nansum(a, axis=axis, keepdims=keepdims) diff --git a/src/awkward/operations/ak_to_arrow.py b/src/awkward/operations/ak_to_arrow.py index 5f3475ab12..d8f0268014 100644 --- a/src/awkward/operations/ak_to_arrow.py +++ b/src/awkward/operations/ak_to_arrow.py @@ -1,12 +1,13 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_arrow",) - import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def to_arrow( array, *, @@ -64,29 +65,16 @@ def to_arrow( See also #ak.from_arrow, #ak.to_arrow_table, #ak.to_parquet, #ak.from_arrow_schema. """ - with ak._errors.OperationErrorContext( - "ak.to_arrow", - { - "array": array, - "list_to32": list_to32, - "string_to32": string_to32, - "bytestring_to32": bytestring_to32, - "emptyarray_to": emptyarray_to, - "categorical_as_dictionary": categorical_as_dictionary, - "extensionarray": extensionarray, - "count_nulls": count_nulls, - }, - ): - return _impl( - array, - list_to32, - string_to32, - bytestring_to32, - emptyarray_to, - categorical_as_dictionary, - extensionarray, - count_nulls, - ) + return _impl( + array, + list_to32, + string_to32, + bytestring_to32, + emptyarray_to, + categorical_as_dictionary, + extensionarray, + count_nulls, + ) def _impl( diff --git a/src/awkward/operations/ak_to_arrow_table.py b/src/awkward/operations/ak_to_arrow_table.py index 96e6128f41..be802a90a6 100644 --- a/src/awkward/operations/ak_to_arrow_table.py +++ b/src/awkward/operations/ak_to_arrow_table.py @@ -1,14 +1,15 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_arrow_table",) - import json import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def to_arrow_table( array, *, @@ -65,29 +66,16 @@ def to_arrow_table( See also #ak.from_arrow, #ak.to_arrow, #ak.to_parquet. """ - with ak._errors.OperationErrorContext( - "ak.to_arrow_table", - { - "array": array, - "list_to32": list_to32, - "string_to32": string_to32, - "bytestring_to32": bytestring_to32, - "emptyarray_to": emptyarray_to, - "categorical_as_dictionary": categorical_as_dictionary, - "extensionarray": extensionarray, - "count_nulls": count_nulls, - }, - ): - return _impl( - array, - list_to32, - string_to32, - bytestring_to32, - emptyarray_to, - categorical_as_dictionary, - extensionarray, - count_nulls, - ) + return _impl( + array, + list_to32, + string_to32, + bytestring_to32, + emptyarray_to, + categorical_as_dictionary, + extensionarray, + count_nulls, + ) def _impl( diff --git a/src/awkward/operations/ak_to_backend.py b/src/awkward/operations/ak_to_backend.py index 986a6505eb..6b2f3a68e1 100644 --- a/src/awkward/operations/ak_to_backend.py +++ b/src/awkward/operations/ak_to_backend.py @@ -3,12 +3,14 @@ import awkward as ak from awkward._backends.dispatch import regularize_backend from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def to_backend(array, backend, *, highlevel=True, behavior=None): """ Args: @@ -48,16 +50,7 @@ def to_backend(array, backend, *, highlevel=True, behavior=None): See #ak.kernels. """ - with ak._errors.OperationErrorContext( - "ak.to_backend", - { - "array": array, - "backend": backend, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, backend, highlevel, behavior) + return _impl(array, backend, highlevel, behavior) def _impl(array, backend, highlevel, behavior): diff --git a/src/awkward/operations/ak_to_buffers.py b/src/awkward/operations/ak_to_buffers.py index 16253f808a..7a460e3747 100644 --- a/src/awkward/operations/ak_to_buffers.py +++ b/src/awkward/operations/ak_to_buffers.py @@ -1,13 +1,14 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_buffers",) - import awkward as ak from awkward._backends.dispatch import regularize_backend +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def to_buffers( array, container=None, @@ -119,21 +120,7 @@ def to_buffers( See also #ak.from_buffers and #ak.to_packed. """ - with ak._errors.OperationErrorContext( - "ak.to_buffers", - { - "array": array, - "container": container, - "buffer_key": buffer_key, - "form_key": form_key, - "id_start": id_start, - "backend": backend, - "byteorder": byteorder, - }, - ): - return _impl( - array, container, buffer_key, form_key, id_start, backend, byteorder - ) + return _impl(array, container, buffer_key, form_key, id_start, backend, byteorder) def _impl(array, container, buffer_key, form_key, id_start, backend, byteorder): diff --git a/src/awkward/operations/ak_to_categorical.py b/src/awkward/operations/ak_to_categorical.py index 463e98a139..f399880191 100644 --- a/src/awkward/operations/ak_to_categorical.py +++ b/src/awkward/operations/ak_to_categorical.py @@ -2,6 +2,7 @@ __all__ = ("to_categorical",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyMetadata @@ -10,6 +11,7 @@ numpy = Numpy.instance() +@with_operation_context def to_categorical(array, *, highlevel=True, behavior=None): """ Args: @@ -81,11 +83,7 @@ def to_categorical(array, *, highlevel=True, behavior=None): See also #ak.is_categorical, #ak.categories, #ak.from_categorical. """ - with ak._errors.OperationErrorContext( - "ak.to_categorical", - {"array": array, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, highlevel, behavior) + return _impl(array, highlevel, behavior) def _impl(array, highlevel, behavior): diff --git a/src/awkward/operations/ak_to_cupy.py b/src/awkward/operations/ak_to_cupy.py index 782bfdd843..1517c0ed79 100644 --- a/src/awkward/operations/ak_to_cupy.py +++ b/src/awkward/operations/ak_to_cupy.py @@ -1,10 +1,11 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_cupy",) - import awkward as ak from awkward._backends.cupy import CupyBackend +from awkward._errors import with_operation_context +@with_operation_context def to_cupy(array): """ Args: @@ -22,11 +23,7 @@ def to_cupy(array): See also #ak.from_cupy and #ak.to_numpy. """ - with ak._errors.OperationErrorContext( - "ak.to_cupy", - {"array": array}, - ): - return _impl(array) + return _impl(array) def _impl(array): diff --git a/src/awkward/operations/ak_to_dataframe.py b/src/awkward/operations/ak_to_dataframe.py index aabc124f48..3e1ea30ca2 100644 --- a/src/awkward/operations/ak_to_dataframe.py +++ b/src/awkward/operations/ak_to_dataframe.py @@ -1,7 +1,7 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_dataframe",) - import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyMetadata @@ -9,6 +9,7 @@ np = NumpyMetadata.instance() +@with_operation_context def to_dataframe( array, *, how="inner", levelname=lambda i: "sub" * i + "entry", anonymous="values" ): @@ -122,16 +123,7 @@ def to_dataframe( 2 3.0 NaN 3 4.0 NaN """ - with ak._errors.OperationErrorContext( - "ak.to_dataframe", - { - "array": array, - "how": how, - "levelname": levelname, - "anonymous": anonymous, - }, - ): - return _impl(array, how, levelname, anonymous) + return _impl(array, how, levelname, anonymous) def _impl(array, how, levelname, anonymous): diff --git a/src/awkward/operations/ak_to_jax.py b/src/awkward/operations/ak_to_jax.py index 6862ba6824..37a1a9d499 100644 --- a/src/awkward/operations/ak_to_jax.py +++ b/src/awkward/operations/ak_to_jax.py @@ -1,10 +1,11 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_jax",) - import awkward as ak from awkward._backends.jax import JaxBackend +from awkward._errors import with_operation_context +@with_operation_context def to_jax(array): """ Args: @@ -22,11 +23,7 @@ def to_jax(array): See also #ak.from_jax and #ak.to_numpy. """ - with ak._errors.OperationErrorContext( - "ak.to_jax", - {"array": array}, - ): - return _impl(array) + return _impl(array) def _impl(array): diff --git a/src/awkward/operations/ak_to_json.py b/src/awkward/operations/ak_to_json.py index 05bee35d4a..c1b3c26c9a 100644 --- a/src/awkward/operations/ak_to_json.py +++ b/src/awkward/operations/ak_to_json.py @@ -1,14 +1,15 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_json",) import json -import pathlib from numbers import Number +from os import PathLike, fsdecode from urllib.parse import urlparse from awkward_cpp.lib import _ext import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._nplikes.numpy import Numpy from awkward._nplikes.numpylike import NumpyMetadata @@ -16,6 +17,7 @@ numpy = Numpy.instance() +@with_operation_context def to_json( array, file=None, @@ -33,7 +35,7 @@ def to_json( """ Args: array: Array-like data (anything #ak.to_layout recognizes). - file (None, str/pathlib.Path, or file-like object): If None, this function returns + file (None, path-like, or file-like object): If None, this function returns JSON-encoded bytes. Otherwise, this function has no return value. If a string/pathlib.Path, this function opens a file with that name, writes JSON data, and closes the file. If that path has a URI protocol (like @@ -111,35 +113,19 @@ def to_json( See also #ak.from_json. """ - with ak._errors.OperationErrorContext( - "ak.to_json", - { - "array": array, - "file": file, - "line_delimited": line_delimited, - "num_indent_spaces": num_indent_spaces, - "num_readability_spaces": num_readability_spaces, - "nan_string": nan_string, - "posinf_string": posinf_string, - "neginf_string": neginf_string, - "complex_record_fields": complex_record_fields, - "convert_bytes": convert_bytes, - "convert_other": convert_other, - }, - ): - return _impl( - array, - file, - line_delimited, - num_indent_spaces, - num_readability_spaces, - nan_string, - posinf_string, - neginf_string, - complex_record_fields, - convert_bytes, - convert_other, - ) + return _impl( + array, + file, + line_delimited, + num_indent_spaces, + num_readability_spaces, + nan_string, + posinf_string, + neginf_string, + complex_record_fields, + convert_bytes, + convert_other, + ) def _impl( @@ -185,7 +171,7 @@ def _impl( out = ak.contents.NumpyArray(array) else: - raise TypeError(f"unrecognized array type: {repr(array)}") + raise TypeError(f"unrecognized array type: {array!r}") jsondata = out.to_json( nan_string=nan_string, @@ -205,8 +191,8 @@ def _impl( ) if file is not None: - if isinstance(file, (str, pathlib.Path)): - parsed_url = urlparse(file) + if isinstance(file, (str, bytes, PathLike)): + parsed_url = urlparse(fsdecode(file)) if parsed_url.scheme == "" or parsed_url.netloc == "": def opener(): diff --git a/src/awkward/operations/ak_to_layout.py b/src/awkward/operations/ak_to_layout.py index 8628609eee..aa6ef51290 100644 --- a/src/awkward/operations/ak_to_layout.py +++ b/src/awkward/operations/ak_to_layout.py @@ -1,13 +1,12 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_layout",) - from collections.abc import Iterable from awkward_cpp.lib import _ext import awkward as ak -from awkward import _errors from awkward._backends.typetracer import TypeTracerBackend +from awkward._errors import with_operation_context from awkward._nplikes.cupy import Cupy from awkward._nplikes.jax import Jax from awkward._nplikes.numpy import Numpy @@ -18,6 +17,7 @@ numpy = Numpy.instance() +@with_operation_context def to_layout(array, *, allow_record=True, allow_other=False, regulararray=True): """ Args: @@ -41,16 +41,7 @@ def to_layout(array, *, allow_record=True, allow_other=False, regulararray=True) would rarely be used in a data analysis because #ak.contents.Content and #ak.record.Record are lower-level than #ak.Array. """ - with _errors.OperationErrorContext( - "ak.to_layout", - { - "array": array, - "allow_record": allow_record, - "allow_other": allow_other, - "regulararray": regulararray, - }, - ): - return _impl(array, allow_record, allow_other, regulararray=regulararray) + return _impl(array, allow_record, allow_other, regulararray=regulararray) def _impl(array, allow_record, allow_other, regulararray): diff --git a/src/awkward/operations/ak_to_list.py b/src/awkward/operations/ak_to_list.py index 155ab512ff..918716f54a 100644 --- a/src/awkward/operations/ak_to_list.py +++ b/src/awkward/operations/ak_to_list.py @@ -1,16 +1,17 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_list",) - from collections.abc import Iterable, Mapping from awkward_cpp.lib import _ext import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def to_list(array): """ Args: @@ -38,11 +39,7 @@ def to_list(array): See also #ak.from_iter and #ak.Array.tolist. """ - with ak._errors.OperationErrorContext( - "ak.to_list", - {"array": array}, - ): - return _impl(array) + return _impl(array) def _impl(array): diff --git a/src/awkward/operations/ak_to_numpy.py b/src/awkward/operations/ak_to_numpy.py index dc1c608e4f..89f2f9989a 100644 --- a/src/awkward/operations/ak_to_numpy.py +++ b/src/awkward/operations/ak_to_numpy.py @@ -2,8 +2,10 @@ __all__ = ("to_numpy",) import awkward as ak from awkward._backends.numpy import NumpyBackend +from awkward._errors import with_operation_context +@with_operation_context def to_numpy(array, *, allow_missing=True): """ Args: @@ -35,11 +37,7 @@ def to_numpy(array, *, allow_missing=True): See also #ak.from_numpy and #ak.to_cupy. """ - with ak._errors.OperationErrorContext( - "ak.to_numpy", - {"array": array, "allow_missing": allow_missing}, - ): - return _impl(array, allow_missing) + return _impl(array, allow_missing) def _impl(array, allow_missing): diff --git a/src/awkward/operations/ak_to_packed.py b/src/awkward/operations/ak_to_packed.py index 0e20c92bd6..cd802aae54 100644 --- a/src/awkward/operations/ak_to_packed.py +++ b/src/awkward/operations/ak_to_packed.py @@ -1,12 +1,14 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_packed",) import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def to_packed(array, *, highlevel=True, behavior=None): """ Args: @@ -65,11 +67,7 @@ def to_packed(array, *, highlevel=True, behavior=None): See also #ak.to_buffers. """ - with ak._errors.OperationErrorContext( - "ak.to_packed", - {"array": array, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, highlevel, behavior) + return _impl(array, highlevel, behavior) def _impl(array, highlevel, behavior): diff --git a/src/awkward/operations/ak_to_parquet.py b/src/awkward/operations/ak_to_parquet.py index b4fe934821..4dbccfd794 100644 --- a/src/awkward/operations/ak_to_parquet.py +++ b/src/awkward/operations/ak_to_parquet.py @@ -1,14 +1,16 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("to_parquet",) - from collections.abc import Mapping, Sequence +from os import fsdecode import awkward as ak +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata metadata = NumpyMetadata.instance() +@with_operation_context def to_parquet( array, destination, @@ -39,8 +41,8 @@ def to_parquet( """ Args: array: Array-like data (anything #ak.to_layout recognizes). - destination (str): Name of the output file, file path, or remote URL passed to - [fsspec.core.url_to_fs](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.core.url_to_fs) + destination (path-like): Name of the output file, file path, or + remote URL passed to [fsspec.core.url_to_fs](https://filesystem-spec.readthedocs.io/en/latest/api.html#fsspec.core.url_to_fs) for remote writing. list_to32 (bool): If True, convert Awkward lists into 32-bit Arrow lists if they're small enough, even if it means an extra conversion. Otherwise, @@ -291,6 +293,13 @@ def parquet_columns(specifier, only=None): if parquet_extra_options is None: parquet_extra_options = {} + try: + destination = fsdecode(destination) + except TypeError: + raise TypeError( + f"'destination' argument of 'ak.to_parquet' must be a path-like, not {type(destination).__name__} ('array' argument is first; 'destination' second)" + ) from None + fs, destination = fsspec.core.url_to_fs(destination, **(storage_options or {})) metalist = [] with pyarrow_parquet.ParquetWriter( diff --git a/src/awkward/operations/ak_to_rdataframe.py b/src/awkward/operations/ak_to_rdataframe.py index e0f90b9221..2b4160df30 100644 --- a/src/awkward/operations/ak_to_rdataframe.py +++ b/src/awkward/operations/ak_to_rdataframe.py @@ -4,10 +4,12 @@ import awkward as ak from awkward._backends.numpy import NumpyBackend +from awkward._errors import with_operation_context cpu = NumpyBackend.instance() +@with_operation_context def to_rdataframe(arrays, *, flatlist_as_rvec=True): """ Args: @@ -40,14 +42,10 @@ def to_rdataframe(arrays, *, flatlist_as_rvec=True): See also #ak.from_rdataframe. """ - with ak._errors.OperationErrorContext( - "ak.to_rdataframe", - {"arrays": arrays}, - ): - return _impl( - arrays, - flatlist_as_rvec=flatlist_as_rvec, - ) + return _impl( + arrays, + flatlist_as_rvec=flatlist_as_rvec, + ) def _impl( diff --git a/src/awkward/operations/ak_to_regular.py b/src/awkward/operations/ak_to_regular.py index 0754fc6b61..5603f26985 100644 --- a/src/awkward/operations/ak_to_regular.py +++ b/src/awkward/operations/ak_to_regular.py @@ -2,6 +2,7 @@ __all__ = ("to_regular",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import AxisError, with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis @@ -9,6 +10,7 @@ np = NumpyMetadata.instance() +@with_operation_context def to_regular(array, axis=1, *, highlevel=True, behavior=None): """ Args: @@ -50,11 +52,7 @@ def to_regular(array, axis=1, *, highlevel=True, behavior=None): See also #ak.from_regular. """ - with ak._errors.OperationErrorContext( - "ak.to_regular", - {"array": array, "axis": axis, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, axis, highlevel, behavior) + return _impl(array, axis, highlevel, behavior) def _impl(array, axis, highlevel, behavior): @@ -81,7 +79,7 @@ def action(layout, depth, **kwargs): return layout.to_RegularArray() elif layout.is_leaf: - raise np.AxisError( + raise AxisError( f"axis={axis} exceeds the depth of this array ({depth})" ) diff --git a/src/awkward/operations/ak_transform.py b/src/awkward/operations/ak_transform.py index d664a775db..99725cd7e9 100644 --- a/src/awkward/operations/ak_transform.py +++ b/src/awkward/operations/ak_transform.py @@ -6,11 +6,13 @@ from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout cpu = NumpyBackend.instance() +@with_operation_context def transform( transformation, array, @@ -409,41 +411,22 @@ def transform( See also: #ak.is_valid and #ak.valid_when to check the validity of transformed outputs. """ - with ak._errors.OperationErrorContext( - "ak.transform", - { - "transformation": transformation, - "array": array, - "more_arrays": more_arrays, - "depth_context": depth_context, - "lateral_context": lateral_context, - "allow_records": allow_records, - "broadcast_parameters_rule": broadcast_parameters_rule, - "left_broadcast": left_broadcast, - "right_broadcast": right_broadcast, - "numpy_to_regular": numpy_to_regular, - "regular_to_jagged": regular_to_jagged, - "return_value": return_value, - "behavior": behavior, - "highlevel": highlevel, - }, - ): - return _impl( - transformation, - array, - more_arrays, - depth_context, - lateral_context, - allow_records, - broadcast_parameters_rule, - left_broadcast, - right_broadcast, - numpy_to_regular, - regular_to_jagged, - return_value, - behavior, - highlevel, - ) + return _impl( + transformation, + array, + more_arrays, + depth_context, + lateral_context, + allow_records, + broadcast_parameters_rule, + left_broadcast, + right_broadcast, + numpy_to_regular, + regular_to_jagged, + return_value, + behavior, + highlevel, + ) def _impl( diff --git a/src/awkward/operations/ak_type.py b/src/awkward/operations/ak_type.py index 818ee7085c..29ffb286d2 100644 --- a/src/awkward/operations/ak_type.py +++ b/src/awkward/operations/ak_type.py @@ -7,11 +7,13 @@ import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def type(array, *, behavior=None): """ Args: @@ -73,11 +75,7 @@ def type(array, *, behavior=None): similar to existing type-constructors, so it's a plausible addition to the language.) """ - with ak._errors.OperationErrorContext( - "ak.type", - {"array": array, "behavior": behavior}, - ): - return _impl(array, behavior) + return _impl(array, behavior) def _impl(array, behavior): @@ -85,13 +83,13 @@ def _impl(array, behavior): if isinstance(array, _ext.ArrayBuilder): form = ak.forms.from_json(array.form()) - return ak.types.ArrayType(form.type_from_behavior(behavior), len(array)) + return ak.types.ArrayType(form.type, len(array), behavior=behavior) elif isinstance(array, ak.record.Record): - return ak.types.ScalarType(array.array.form.type_from_behavior(behavior)) + return ak.types.ScalarType(array.array.form.type, behavior=behavior) elif isinstance(array, ak.contents.Content): - return ak.types.ArrayType(array.form.type_from_behavior(behavior), array.length) + return ak.types.ArrayType(array.form.type, array.length, behavior=behavior) elif isinstance(array, (np.dtype, np.generic)): return ak.types.ScalarType( @@ -99,22 +97,22 @@ def _impl(array, behavior): ) elif isinstance(array, bool): # np.bool_ in np.generic (above) - return ak.types.ScalarType(ak.types.NumpyType("bool")) + return ak.types.ScalarType(ak.types.NumpyType("bool"), behavior=behavior) elif isinstance(array, numbers.Integral): - return ak.types.ScalarType(ak.types.NumpyType("int64")) + return ak.types.ScalarType(ak.types.NumpyType("int64"), behavior=behavior) elif isinstance(array, numbers.Real): - return ak.types.ScalarType(ak.types.NumpyType("float64")) + return ak.types.ScalarType(ak.types.NumpyType("float64"), behavior=behavior) elif isinstance(array, numbers.Complex): - return ak.types.ScalarType(ak.types.NumpyType("complex128")) + return ak.types.ScalarType(ak.types.NumpyType("complex128"), behavior=behavior) elif isinstance(array, datetime): # np.datetime64 in np.generic (above) - return ak.types.ScalarType(ak.types.NumpyType("datetime64")) + return ak.types.ScalarType(ak.types.NumpyType("datetime64"), behavior=behavior) elif isinstance(array, timedelta): # np.timedelta64 in np.generic (above) - return ak.types.ScalarType(ak.types.NumpyType("timedelta")) + return ak.types.ScalarType(ak.types.NumpyType("timedelta"), behavior=behavior) elif isinstance(array, ak.highlevel.ArrayBuilder): # Don't go through `to_layout`: we want to avoid snapshotting this array @@ -123,7 +121,7 @@ def _impl(array, behavior): else: layout = ak.to_layout(array, allow_other=True, allow_record=True) if layout is None: - return ak.types.ScalarType(ak.types.UnknownType()) + return ak.types.ScalarType(ak.types.UnknownType(), behavior=behavior) elif isinstance(layout, (ak.contents.Content, ak.record.Record)): return _impl(layout, behavior) diff --git a/src/awkward/operations/ak_unflatten.py b/src/awkward/operations/ak_unflatten.py index a723c47fce..c83c75059b 100644 --- a/src/awkward/operations/ak_unflatten.py +++ b/src/awkward/operations/ak_unflatten.py @@ -2,6 +2,7 @@ __all__ = ("unflatten",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import maybe_posaxis, wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._nplikes.shape import unknown_length @@ -11,6 +12,7 @@ np = NumpyMetadata.instance() +@with_operation_context def unflatten(array, counts, axis=0, *, highlevel=True, behavior=None): """ Args: @@ -74,17 +76,7 @@ def unflatten(array, counts, axis=0, *, highlevel=True, behavior=None): See also #ak.num and #ak.flatten. """ - with ak._errors.OperationErrorContext( - "ak.unflatten", - { - "array": array, - "counts": counts, - "axis": axis, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, counts, axis, highlevel, behavior) + return _impl(array, counts, axis, highlevel, behavior) def _impl(array, counts, axis, highlevel, behavior): diff --git a/src/awkward/operations/ak_unzip.py b/src/awkward/operations/ak_unzip.py index 135d508828..25594a0d42 100644 --- a/src/awkward/operations/ak_unzip.py +++ b/src/awkward/operations/ak_unzip.py @@ -2,12 +2,14 @@ __all__ = ("unzip",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def unzip(array, *, highlevel=True, behavior=None): """ Args: @@ -34,11 +36,7 @@ def unzip(array, *, highlevel=True, behavior=None): >>> y """ - with ak._errors.OperationErrorContext( - "ak.unzip", - {"array": array, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, highlevel, behavior) + return _impl(array, highlevel, behavior) def _impl(array, highlevel, behavior): diff --git a/src/awkward/operations/ak_validity_error.py b/src/awkward/operations/ak_validity_error.py index 0b220b6bd6..06132d480e 100644 --- a/src/awkward/operations/ak_validity_error.py +++ b/src/awkward/operations/ak_validity_error.py @@ -1,9 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("validity_error",) - import awkward as ak +from awkward._errors import with_operation_context +@with_operation_context def validity_error(array, *, exception=False): """ Args: @@ -19,11 +20,7 @@ def validity_error(array, *, exception=False): See also #ak.is_valid. """ - with ak._errors.OperationErrorContext( - "ak.validity_error", - {"array": array, "exception": exception}, - ): - return _impl(array, exception) + return _impl(array, exception) def _impl(array, exception): diff --git a/src/awkward/operations/ak_values_astype.py b/src/awkward/operations/ak_values_astype.py index 76fb254526..ea021a770b 100644 --- a/src/awkward/operations/ak_values_astype.py +++ b/src/awkward/operations/ak_values_astype.py @@ -1,12 +1,14 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("values_astype",) import awkward as ak +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def values_astype(array, to, *, including_unknown=False, highlevel=True, behavior=None): """ Args: @@ -52,17 +54,7 @@ def values_astype(array, to, *, including_unknown=False, highlevel=True, behavio See also #ak.strings_astype. """ - with ak._errors.OperationErrorContext( - "ak.values_astype", - { - "array": array, - "to": to, - "including_unknown": including_unknown, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, to, including_unknown, highlevel, behavior) + return _impl(array, to, including_unknown, highlevel, behavior) def _impl(array, to, including_unknown, highlevel, behavior): diff --git a/src/awkward/operations/ak_var.py b/src/awkward/operations/ak_var.py index c69044bbb2..e1cb68f643 100644 --- a/src/awkward/operations/ak_var.py +++ b/src/awkward/operations/ak_var.py @@ -2,15 +2,16 @@ __all__ = ("var",) import awkward as ak from awkward._behavior import behavior_of -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._layout import maybe_posaxis from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import regularize_axis -from awkward._util import unset np = NumpyMetadata.instance() +@with_operation_context def var( x, weight=None, @@ -19,7 +20,6 @@ def var( *, keepdims=False, mask_identity=False, - flatten_records=unset, ): """ Args: @@ -70,30 +70,10 @@ def var( See also #ak.nanvar. """ - with ak._errors.OperationErrorContext( - "ak.var", - { - "x": x, - "weight": weight, - "ddof": ddof, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - return _impl(x, weight, ddof, axis, keepdims, mask_identity) + return _impl(x, weight, ddof, axis, keepdims, mask_identity) +@with_operation_context def nanvar( x, weight=None, @@ -102,7 +82,6 @@ def nanvar( *, keepdims=False, mask_identity=True, - flatten_records=unset, ): """ Args: @@ -138,32 +117,17 @@ def nanvar( See also #ak.var. """ - with ak._errors.OperationErrorContext( - "ak.nanvar", - { - "x": x, - "weight": weight, - "ddof": ddof, - "axis": axis, - "keepdims": keepdims, - "mask_identity": mask_identity, - }, - ): - if flatten_records is not unset: - message = ( - "`flatten_records` is no longer a supported argument for reducers. " - "Instead, use `ak.ravel(array)` first to remove the record structure " - "and flatten the array." - ) - if flatten_records: - raise ValueError(message) - else: - ak._errors.deprecate(message, "2.2.0") - x = ak.operations.ak_nan_to_none._impl(x, False, None) - if weight is not None: - weight = ak.operations.ak_nan_to_none._impl(weight, False, None) - - return _impl(x, weight, ddof, axis, keepdims, mask_identity) + if weight is not None: + weight = ak.operations.ak_nan_to_none._impl(weight, False, None) + + return _impl( + ak.operations.ak_nan_to_none._impl(x, False, None), + weight, + ddof, + axis, + keepdims, + mask_identity, + ) def _impl(x, weight, ddof, axis, keepdims, mask_identity): @@ -240,12 +204,12 @@ def _impl(x, weight, ddof, axis, keepdims, mask_identity): def _nep_18_impl_var( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, ddof=0, keepdims=False, *, - where=unsupported, + where=UNSUPPORTED, ): return var(a, axis=axis, keepdims=keepdims, ddof=ddof) @@ -254,11 +218,11 @@ def _nep_18_impl_var( def _nep_18_impl_nanvar( a, axis=None, - dtype=unsupported, - out=unsupported, + dtype=UNSUPPORTED, + out=UNSUPPORTED, ddof=0, keepdims=False, *, - where=unsupported, + where=UNSUPPORTED, ): return nanvar(a, axis=axis, keepdims=keepdims, ddof=ddof) diff --git a/src/awkward/operations/ak_where.py b/src/awkward/operations/ak_where.py index dcf31f678b..0ea24acac2 100644 --- a/src/awkward/operations/ak_where.py +++ b/src/awkward/operations/ak_where.py @@ -4,6 +4,7 @@ from awkward._backends.dispatch import backend_of from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata @@ -12,6 +13,7 @@ @ak._connect.numpy.implements("where") +@with_operation_context def where(condition, *args, mergebool=True, highlevel=True, behavior=None): """ Args: @@ -44,28 +46,14 @@ def where(condition, *args, mergebool=True, highlevel=True, behavior=None): they are incompatible types, the output will have #ak.type.UnionType. """ if len(args) == 0: - with ak._errors.OperationErrorContext( - "ak.where", - {"condition": condition, "mergebool": mergebool, "highlevel": highlevel}, - ): - return _impl1(condition, mergebool, highlevel, behavior) + return _impl1(condition, mergebool, highlevel, behavior) elif len(args) == 1: raise ValueError("either both or neither of x and y should be given") elif len(args) == 2: x, y = args - with ak._errors.OperationErrorContext( - "ak.where", - { - "condition": condition, - "x": x, - "y": y, - "mergebool": mergebool, - "highlevel": highlevel, - }, - ): - return _impl3(condition, x, y, mergebool, highlevel, behavior) + return _impl3(condition, x, y, mergebool, highlevel, behavior) else: raise TypeError( @@ -119,10 +107,18 @@ def action(inputs, **kwargs): nplike=backend.index_nplike, ) if not isinstance(left, ak.contents.Content): - left = ak.contents.NumpyArray(backend.nplike.repeat(left, tags.length)) + left = ak.contents.NumpyArray( + backend.nplike.repeat( + backend.nplike.asarray(left), + backend.nplike.shape_item_as_index(tags.length), + ) + ) if not isinstance(right, ak.contents.Content): right = ak.contents.NumpyArray( - backend.nplike.repeat(right, tags.length) + backend.nplike.repeat( + backend.nplike.asarray(right), + backend.nplike.shape_item_as_index(tags.length), + ) ) return ( ak.contents.UnionArray.simplified( diff --git a/src/awkward/operations/ak_with_field.py b/src/awkward/operations/ak_with_field.py index dce6c0d441..2ac0511e36 100644 --- a/src/awkward/operations/ak_with_field.py +++ b/src/awkward/operations/ak_with_field.py @@ -3,7 +3,10 @@ import copy import awkward as ak +from awkward._backends.dispatch import backend_of +from awkward._backends.numpy import NumpyBackend from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata from awkward._regularize import is_non_string_like_sequence @@ -11,6 +14,10 @@ np = NumpyMetadata.instance() +cpu = NumpyBackend.instance() + + +@with_operation_context def with_field(array, what, where=None, *, highlevel=True, behavior=None): """ Args: @@ -34,17 +41,7 @@ def with_field(array, what, where=None, *, highlevel=True, behavior=None): #ak.with_field, so performance is not a factor in choosing one over the other.) """ - with ak._errors.OperationErrorContext( - "ak.with_field", - { - "array": array, - "what": what, - "where": where, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, what, where, highlevel, behavior) + return _impl(array, what, where, highlevel, behavior) def _impl(base, what, where, highlevel, behavior): @@ -81,8 +78,14 @@ def _impl(base, what, where, highlevel, behavior): where = where[0] behavior = behavior_of(base, what, behavior=behavior) - base = ak.operations.to_layout(base, allow_record=True, allow_other=False) + backend = backend_of(base, what, default=cpu) + + base = ak.operations.to_layout( + base, allow_record=True, allow_other=False + ).to_backend(backend) what = ak.operations.to_layout(what, allow_record=True, allow_other=True) + if isinstance(what, (ak.contents.Content, ak.record.Record)): + what = what.to_backend(backend) keys = copy.copy(base.fields) if where in base.fields: @@ -117,14 +120,17 @@ def action(inputs, **kwargs): if what is None: what = ak.contents.IndexedOptionArray( ak.index.Index64( - backend.index_nplike.full(len(base), -1, dtype=np.int64), + backend.index_nplike.full(base.length, -1, dtype=np.int64), nplike=backend.index_nplike, ), ak.contents.EmptyArray(), ) elif not isinstance(what, ak.contents.Content): what = ak.contents.NumpyArray( - backend.nplike.repeat(what, len(base)) + backend.nplike.repeat( + backend.nplike.asarray(what), + backend.nplike.shape_item_as_index(base.length), + ) ) if base.is_tuple: # Preserve tuple-ness diff --git a/src/awkward/operations/ak_with_name.py b/src/awkward/operations/ak_with_name.py index cfbe7a3b64..ae345dbac0 100644 --- a/src/awkward/operations/ak_with_name.py +++ b/src/awkward/operations/ak_with_name.py @@ -2,12 +2,14 @@ __all__ = ("with_name",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def with_name(array, name, *, highlevel=True, behavior=None): """ Args: @@ -31,11 +33,7 @@ def with_name(array, name, *, highlevel=True, behavior=None): to the data; see #ak.Array and #ak.behavior for a more complete description. """ - with ak._errors.OperationErrorContext( - "ak.with_name", - {"array": array, "name": name, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, name, highlevel, behavior) + return _impl(array, name, highlevel, behavior) def _impl(array, name, highlevel, behavior): @@ -44,10 +42,11 @@ def _impl(array, name, highlevel, behavior): def action(layout, **ignore): if isinstance(layout, ak.contents.RecordArray): - parameters = dict(layout.parameters) - parameters["__record__"] = name return ak.contents.RecordArray( - layout.contents, layout.fields, layout.length, parameters=parameters + layout._contents, + layout._fields, + layout._length, + parameters={**layout.parameters, "__record__": name}, ) else: return None diff --git a/src/awkward/operations/ak_with_parameter.py b/src/awkward/operations/ak_with_parameter.py index f20583ae67..16bbea3b6d 100644 --- a/src/awkward/operations/ak_with_parameter.py +++ b/src/awkward/operations/ak_with_parameter.py @@ -2,12 +2,14 @@ __all__ = ("with_parameter",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def with_parameter(array, parameter, value, *, highlevel=True, behavior=None): """ Args: @@ -28,17 +30,7 @@ def with_parameter(array, parameter, value, *, highlevel=True, behavior=None): You can also remove a single parameter with this function, since setting a parameter to None is equivalent to removing it. """ - with ak._errors.OperationErrorContext( - "ak.with_parameter", - { - "array": array, - "parameter": parameter, - "value": value, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, parameter, value, highlevel, behavior) + return _impl(array, parameter, value, highlevel, behavior) def _impl(array, parameter, value, highlevel, behavior): diff --git a/src/awkward/operations/ak_without_field.py b/src/awkward/operations/ak_without_field.py index d49d696ca3..2a76443007 100644 --- a/src/awkward/operations/ak_without_field.py +++ b/src/awkward/operations/ak_without_field.py @@ -4,12 +4,14 @@ import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def without_field(array, where, *, highlevel=True, behavior=None): """ Args: @@ -31,11 +33,7 @@ def without_field(array, where, *, highlevel=True, behavior=None): #ak.without_field, so performance is not a factor in choosing one over the other.) """ - with ak._errors.OperationErrorContext( - "ak.without_field", - {"array": array, "where": where, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, where, highlevel, behavior) + return _impl(array, where, highlevel, behavior) def _impl(base, where, highlevel, behavior): diff --git a/src/awkward/operations/ak_without_parameters.py b/src/awkward/operations/ak_without_parameters.py index f13141a76a..b853ba37e1 100644 --- a/src/awkward/operations/ak_without_parameters.py +++ b/src/awkward/operations/ak_without_parameters.py @@ -2,12 +2,14 @@ __all__ = ("without_parameters",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def without_parameters(array, *, highlevel=True, behavior=None): """ Args: @@ -23,11 +25,7 @@ def without_parameters(array, *, highlevel=True, behavior=None): Note that a "new array" is a lightweight shallow copy, not a duplication of large data buffers. """ - with ak._errors.OperationErrorContext( - "ak.without_parameters", - {"array": array, "highlevel": highlevel, "behavior": behavior}, - ): - return _impl(array, highlevel, behavior) + return _impl(array, highlevel, behavior) def _impl(array, highlevel, behavior): diff --git a/src/awkward/operations/ak_zeros_like.py b/src/awkward/operations/ak_zeros_like.py index 61b6607fb3..f20e78a01b 100644 --- a/src/awkward/operations/ak_zeros_like.py +++ b/src/awkward/operations/ak_zeros_like.py @@ -1,8 +1,8 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE __all__ = ("zeros_like",) - import awkward as ak -from awkward._connect.numpy import unsupported +from awkward._connect.numpy import UNSUPPORTED +from awkward._errors import with_operation_context from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() @@ -11,6 +11,7 @@ _ZEROS = object() +@with_operation_context def zeros_like( array, *, dtype=None, including_unknown=False, highlevel=True, behavior=None ): @@ -33,17 +34,7 @@ def zeros_like( (There is no equivalent of NumPy's `np.empty_like` because Awkward Arrays are immutable.) """ - with ak._errors.OperationErrorContext( - "ak.zeros_like", - { - "array": array, - "dtype": dtype, - "including_unknown": including_unknown, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl(array, highlevel, behavior, dtype, including_unknown) + return _impl(array, highlevel, behavior, dtype, including_unknown) def _impl(array, highlevel, behavior, dtype, including_unknown): @@ -58,6 +49,6 @@ def _impl(array, highlevel, behavior, dtype, including_unknown): @ak._connect.numpy.implements("zeros_like") def _nep_18_impl( - a, dtype=None, order=unsupported, subok=unsupported, shape=unsupported + a, dtype=None, order=UNSUPPORTED, subok=UNSUPPORTED, shape=UNSUPPORTED ): return zeros_like(a, dtype=dtype) diff --git a/src/awkward/operations/ak_zip.py b/src/awkward/operations/ak_zip.py index dcc77d80fb..066bfc10d0 100644 --- a/src/awkward/operations/ak_zip.py +++ b/src/awkward/operations/ak_zip.py @@ -2,12 +2,14 @@ __all__ = ("zip",) import awkward as ak from awkward._behavior import behavior_of +from awkward._errors import with_operation_context from awkward._layout import wrap_layout from awkward._nplikes.numpylike import NumpyMetadata np = NumpyMetadata.instance() +@with_operation_context def zip( arrays, depth_limit=None, @@ -131,29 +133,16 @@ def zip( >>> ak.zip([one, two], optiontype_outside_record=True) """ - with ak._errors.OperationErrorContext( - "ak.zip", - { - "arrays": arrays, - "depth_limit": depth_limit, - "parameters": parameters, - "with_name": with_name, - "right_broadcast": right_broadcast, - "optiontype_outside_record": optiontype_outside_record, - "highlevel": highlevel, - "behavior": behavior, - }, - ): - return _impl( - arrays, - depth_limit, - parameters, - with_name, - right_broadcast, - optiontype_outside_record, - highlevel, - behavior, - ) + return _impl( + arrays, + depth_limit, + parameters, + with_name, + right_broadcast, + optiontype_outside_record, + highlevel, + behavior, + ) def _impl( diff --git a/src/awkward/record.py b/src/awkward/record.py index 5aa6f222eb..782be21534 100644 --- a/src/awkward/record.py +++ b/src/awkward/record.py @@ -16,7 +16,7 @@ from awkward._nplikes.shape import unknown_length from awkward._regularize import is_integer from awkward._typing import Self -from awkward._util import unset +from awkward._util import UNSET from awkward.contents.content import Content np = NumpyMetadata.instance() @@ -244,9 +244,9 @@ def __copy__(self) -> Self: def __deepcopy__(self, memo): return Record(copy.deepcopy(self._array, memo), self._at) - def copy(self, array=unset, at=unset) -> Self: + def copy(self, array=UNSET, at=UNSET) -> Self: return Record( - self._array if array is unset else array, self._at if at is unset else at + self._array if array is UNSET else array, self._at if at is UNSET else at ) diff --git a/src/awkward/types/arraytype.py b/src/awkward/types/arraytype.py index 80c52a5faa..5152835231 100644 --- a/src/awkward/types/arraytype.py +++ b/src/awkward/types/arraytype.py @@ -9,7 +9,7 @@ class ArrayType: - def __init__(self, content, length): + def __init__(self, content, length, behavior=None): if not isinstance(content, ak.types.Type): raise TypeError( "{} all 'contents' must be Type subclasses, not {}".format( @@ -24,6 +24,7 @@ def __init__(self, content, length): ) self._content = content self._length = length + self._behavior = behavior @property def content(self): @@ -33,6 +34,10 @@ def content(self): def length(self): return self._length + @property + def behavior(self): + return self._behavior + def __str__(self): return "".join(self._str("", True)) @@ -40,10 +45,17 @@ def show(self, stream=sys.stdout): stream.write("".join([*self._str("", False), "\n"])) def _str(self, indent, compact): - return [f"{self._length} * ", *self._content._str(indent, compact)] + return [ + f"{self._length} * ", + *self._content._str( + indent, + compact, + self._behavior, + ), + ] def __repr__(self): - args = [repr(self._content), repr(self._length)] + args = [repr(self._content), repr(self._length), repr(self._behavior)] return "{}({})".format(type(self).__name__, ", ".join(args)) def is_equal_to(self, other, *, all_parameters: bool = False) -> bool: diff --git a/src/awkward/types/listtype.py b/src/awkward/types/listtype.py index 4d94452360..21c06a267e 100644 --- a/src/awkward/types/listtype.py +++ b/src/awkward/types/listtype.py @@ -1,12 +1,23 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations +from awkward._behavior import find_array_typestr +from awkward._errors import deprecate from awkward._parameters import parameters_are_equal, type_parameters_equal -from awkward._typing import final +from awkward._typing import Self, final +from awkward._util import UNSET from awkward.types.type import Type @final class ListType(Type): + def copy(self, *, content: Type = UNSET, parameters=UNSET, typestr=UNSET) -> Self: + return ListType( + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, + typestr=self._typestr if typestr is UNSET else typestr, + ) + def __init__(self, content, *, parameters=None, typestr=None): if not isinstance(content, Type): raise TypeError( @@ -34,26 +45,25 @@ def __init__(self, content, *, parameters=None, typestr=None): def content(self): return self._content - def _str(self, indent, compact): + def _str(self, indent, compact, behavior): if self._typestr is not None: - out = [self._typestr] - - elif self.parameter("__array__") == "string": - out = ["string"] - - elif self.parameter("__array__") == "bytestring": - out = ["bytes"] + deprecate("typestr argument is deprecated", "2.4.0") + typestr = find_array_typestr(behavior, self._parameters, self._typestr) + if typestr is not None: + out = [typestr] else: params = self._str_parameters() if params is None: - out = ["var * ", *self._content._str(indent, compact)] + out = ["var * ", *self._content._str(indent, compact, behavior)] else: - out = ["[var * ", *self._content._str(indent, compact)] + [ - f", {params}]" + out = [ + "[var * ", + *self._content._str(indent, compact, behavior), + f", {params}]", ] - return [self._str_categorical_begin(), *out] + [self._str_categorical_end()] + return [self._str_categorical_begin(), *out, self._str_categorical_end()] def __repr__(self): args = [repr(self._content), *self._repr_args()] diff --git a/src/awkward/types/numpytype.py b/src/awkward/types/numpytype.py index e9cb2ee40a..b205d714fc 100644 --- a/src/awkward/types/numpytype.py +++ b/src/awkward/types/numpytype.py @@ -1,11 +1,15 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations import json import re +from awkward._behavior import find_array_typestr +from awkward._errors import deprecate from awkward._nplikes.numpylike import NumpyMetadata from awkward._parameters import parameters_are_equal, type_parameters_equal -from awkward._typing import final +from awkward._typing import Self, final +from awkward._util import UNSET from awkward.types.type import Type np = NumpyMetadata.instance() @@ -91,6 +95,13 @@ def dtype_to_primitive(dtype): @final class NumpyType(Type): + def copy(self, *, primitive: Type = UNSET, parameters=UNSET, typestr=UNSET) -> Self: + return NumpyType( + self._primitive if primitive is UNSET else primitive, + parameters=self._parameters if parameters is UNSET else parameters, + typestr=self._typestr if typestr is UNSET else typestr, + ) + def __init__(self, primitive, *, parameters=None, typestr=None): primitive = dtype_to_primitive(primitive_to_dtype(primitive)) if parameters is not None and not isinstance(parameters, dict): @@ -115,15 +126,13 @@ def primitive(self): _str_parameters_exclude = ("__categorical__", "__unit__") - def _str(self, indent, compact): + def _str(self, indent, compact, behavior): if self._typestr is not None: - out = [self._typestr] - - elif self.parameter("__array__") == "char": - out = ["char"] + deprecate("typestr argument is deprecated", "2.4.0") - elif self.parameter("__array__") == "byte": - out = ["byte"] + typestr = find_array_typestr(behavior, self._parameters, self._typestr) + if typestr is not None: + out = [typestr] else: if self.parameter("__unit__") is not None: @@ -146,7 +155,7 @@ def _str(self, indent, compact): params = "" out = [self._primitive, "[", units, params, "]"] - return [self._str_categorical_begin(), *out] + [self._str_categorical_end()] + return [self._str_categorical_begin(), *out, self._str_categorical_end()] def __repr__(self): args = [repr(self._primitive), *self._repr_args()] diff --git a/src/awkward/types/optiontype.py b/src/awkward/types/optiontype.py index 4563a9d61c..0ef6be32aa 100644 --- a/src/awkward/types/optiontype.py +++ b/src/awkward/types/optiontype.py @@ -1,11 +1,15 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations +from awkward._behavior import find_array_typestr +from awkward._errors import deprecate from awkward._parameters import ( parameters_are_equal, parameters_union, type_parameters_equal, ) -from awkward._typing import final +from awkward._typing import Self, final +from awkward._util import UNSET from awkward.types.listtype import ListType from awkward.types.regulartype import RegularType from awkward.types.type import Type @@ -14,6 +18,13 @@ @final class OptionType(Type): + def copy(self, *, content: Type = UNSET, parameters=UNSET, typestr=UNSET) -> Self: + return OptionType( + self._content if content is UNSET else content, + parameters=self._parameters if parameters is UNSET else parameters, + typestr=self._typestr if typestr is UNSET else typestr, + ) + def __init__(self, content, *, parameters=None, typestr=None): if not isinstance(content, Type): raise TypeError( @@ -41,14 +52,19 @@ def __init__(self, content, *, parameters=None, typestr=None): def content(self): return self._content - def _str(self, indent, compact): + def _str(self, indent, compact, behavior): + if self._typestr is not None: + deprecate("typestr argument is deprecated", "2.4.0") + + typestr = find_array_typestr(behavior, self._parameters, self._typestr) + head = [] tail = [] - if self._typestr is not None: - content_out = [self._typestr] + if typestr is not None: + content_out = [typestr] else: - content_out = self._content._str(indent, compact) + content_out = self._content._str(indent, compact, behavior) params = self._str_parameters() if params is None: if isinstance( @@ -68,11 +84,13 @@ def _str(self, indent, compact): head = ["option["] tail = [f", {params}]"] - return ( - [*head, self._str_categorical_begin(), *content_out] - + [self._str_categorical_end()] - + tail - ) + return [ + *head, + self._str_categorical_begin(), + *content_out, + self._str_categorical_end(), + *tail, + ] def __repr__(self): args = [repr(self._content), *self._repr_args()] diff --git a/src/awkward/types/recordtype.py b/src/awkward/types/recordtype.py index 8e3248a679..df42e827ed 100644 --- a/src/awkward/types/recordtype.py +++ b/src/awkward/types/recordtype.py @@ -1,4 +1,5 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations import json from collections.abc import Iterable @@ -6,13 +7,31 @@ import awkward as ak import awkward._prettyprint +from awkward._behavior import find_record_typestr +from awkward._errors import deprecate from awkward._parameters import parameters_are_equal, type_parameters_equal -from awkward._typing import final +from awkward._typing import Self, final +from awkward._util import UNSET from awkward.types.type import Type @final class RecordType(Type): + def copy( + self, + *, + contents: list[Type] = UNSET, + fields: list[str] | None = UNSET, + parameters=UNSET, + typestr=UNSET, + ) -> Self: + return RecordType( + self._contents if contents is UNSET else contents, + self._fields if fields is UNSET else fields, + parameters=self._parameters if parameters is UNSET else parameters, + typestr=self._typestr if typestr is UNSET else typestr, + ) + def __init__(self, contents, fields, *, parameters=None, typestr=None): if not isinstance(contents, Iterable): raise TypeError( @@ -66,9 +85,13 @@ def is_tuple(self): _str_parameters_exclude = ("__categorical__", "__record__") - def _str(self, indent, compact): + def _str(self, indent, compact, behavior): if self._typestr is not None: - out = [self._typestr] + deprecate("typestr argument is deprecated", "2.4.0") + + typestr = find_record_typestr(behavior, self._parameters, self._typestr) + if typestr is not None: + out = [typestr] else: if compact: @@ -80,14 +103,19 @@ def _str(self, indent, compact): for i, x in enumerate(self._contents): if i + 1 < len(self._contents): if compact: - y = [*x._str(indent, compact), ", "] + y = [*x._str(indent, compact, behavior), ", "] else: - y = [*x._str(indent + " ", compact), ",\n", indent, " "] + y = [ + *x._str(indent + " ", compact, behavior), + ",\n", + indent, + " ", + ] else: if compact: - y = x._str(indent, compact) + y = x._str(indent, compact, behavior) else: - y = x._str(indent + " ", compact) + y = x._str(indent + " ", compact, behavior) children.append(y) params = self._str_parameters() @@ -134,41 +162,31 @@ def _str(self, indent, compact): if self.is_tuple: flat_children = [y for x in children for y in x] if name is None: - out = ["(", pre, *flat_children] + [post, ")"] + out = ["(", pre, *flat_children, post, ")"] else: - out = [name, "[", pre, *flat_children] + [post, "]"] + out = [name, "[", pre, *flat_children, post, "]"] else: if name is None: - out = ["{", pre, *flat_pairs] + [post, "}"] + out = ["{", pre, *flat_pairs, post, "}"] else: - out = [name, "[", pre, *flat_pairs] + [post, "]"] + out = [name, "[", pre, *flat_pairs, post, "]"] else: if self.is_tuple: flat_children = [y for x in children for y in x] if name is None: - out = ["tuple[[", pre, *flat_children] + [ - post, - "], ", - params, - "]", - ] + out = ["tuple[[", pre, *flat_children, post, "], ", params, "]"] else: c = "" if len(self._contents) == 0 else ", " - out = [name, "[", pre, *flat_children] + [c, post, params, "]"] + out = [name, "[", pre, *flat_children, c, post, params, "]"] else: if name is None: - out = ["struct[{", pre, *flat_pairs] + [ - post, - "}, ", - params, - "]", - ] + out = ["struct[{", pre, *flat_pairs, post, "}, ", params, "]"] else: c = "" if len(self._contents) == 0 else ", " - out = [name, "[", pre, *flat_pairs] + [c, post, params, "]"] + out = [name, "[", pre, *flat_pairs, c, post, params, "]"] - return [self._str_categorical_begin(), *out] + [self._str_categorical_end()] + return [self._str_categorical_begin(), *out, self._str_categorical_end()] def __repr__(self): args = [repr(self._contents), repr(self._fields), *self._repr_args()] diff --git a/src/awkward/types/regulartype.py b/src/awkward/types/regulartype.py index 99cbdaad32..78edaf414c 100644 --- a/src/awkward/types/regulartype.py +++ b/src/awkward/types/regulartype.py @@ -1,13 +1,33 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE -from awkward._nplikes.shape import unknown_length +from __future__ import annotations + +from awkward._behavior import find_array_typestr +from awkward._errors import deprecate +from awkward._nplikes.shape import ShapeItem, unknown_length from awkward._parameters import parameters_are_equal, type_parameters_equal from awkward._regularize import is_integer -from awkward._typing import final +from awkward._typing import Self, final +from awkward._util import UNSET from awkward.types.type import Type @final class RegularType(Type): + def copy( + self, + *, + content: Type = UNSET, + size: ShapeItem = UNSET, + parameters=UNSET, + typestr=UNSET, + ) -> Self: + return RegularType( + self._content if content is UNSET else content, + size=self._size if size is UNSET else size, + parameters=self._parameters if parameters is UNSET else parameters, + typestr=self._typestr if typestr is UNSET else typestr, + ) + def __init__(self, content, size, *, parameters=None, typestr=None): if not isinstance(content, Type): raise TypeError( @@ -46,30 +66,35 @@ def content(self): def size(self): return self._size - def _str(self, indent, compact): + def _str(self, indent, compact, behavior): if self._typestr is not None: - out = [self._typestr] - - elif self.parameter("__array__") == "string": - out = [f"string[{self._size}]"] + deprecate("typestr argument is deprecated", "2.4.0") - elif self.parameter("__array__") == "bytestring": - out = [f"bytes[{self._size}]"] + typestr = find_array_typestr(behavior, self._parameters, self._typestr) + if typestr is not None: + out = [f"{typestr}[{self._size}]"] else: params = self._str_parameters() if params is None: - out = [str(self._size), " * ", *self._content._str(indent, compact)] + out = [ + str(self._size), + " * ", + *self._content._str(indent, compact, behavior), + ] else: out = [ "[", str(self._size), " * ", - *self._content._str(indent, compact), - ] + [", ", params, "]"] + *self._content._str(indent, compact, behavior), + ", ", + params, + "]", + ] - return [self._str_categorical_begin(), *out] + [self._str_categorical_end()] + return [self._str_categorical_begin(), *out, self._str_categorical_end()] def __repr__(self): args = [repr(self._content), repr(self._size), *self._repr_args()] diff --git a/src/awkward/types/scalartype.py b/src/awkward/types/scalartype.py index 2c25d5ec1a..a2d1a696b8 100644 --- a/src/awkward/types/scalartype.py +++ b/src/awkward/types/scalartype.py @@ -1,4 +1,5 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations import sys @@ -6,7 +7,7 @@ class ScalarType: - def __init__(self, content): + def __init__(self, content, behavior=None): if not isinstance(content, ak.types.Type): raise TypeError( "{} all 'contents' must be Type subclasses, not {}".format( @@ -14,11 +15,16 @@ def __init__(self, content): ) ) self._content = content + self._behavior = behavior @property def content(self): return self._content + @property + def behavior(self): + return self._behavior + def __str__(self): return "".join(self._str("", True)) @@ -26,10 +32,14 @@ def show(self, stream=sys.stdout): stream.write("".join([*self._str("", False), "\n"])) def _str(self, indent, compact): - return self._content._str(indent, compact) + return self._content._str( + indent, + compact, + self._behavior, + ) def __repr__(self): - return f"{type(self).__name__}({self._content!r})" + return f"{type(self).__name__}({self._content!r}, {self._behavior!r})" def is_equal_to(self, other, *, all_parameters: bool = False) -> bool: return isinstance(other, type(self)) and self._content.is_equal_to( diff --git a/src/awkward/types/type.py b/src/awkward/types/type.py index 668e6676b8..9cda962495 100644 --- a/src/awkward/types/type.py +++ b/src/awkward/types/type.py @@ -6,12 +6,17 @@ import awkward as ak from awkward._nplikes.numpylike import NumpyMetadata +from awkward._typing import Self +from awkward._util import UNSET from awkward.types._awkward_datashape_parser import Lark_StandAlone, Transformer np = NumpyMetadata.instance() class Type: + def copy(self, *, parameters=UNSET, typestr=UNSET) -> Self: + raise NotImplementedError + @property def parameters(self): if self._parameters is None: # pylint: disable=E0203 @@ -29,10 +34,14 @@ def typestr(self): return self._typestr def __str__(self): - return "".join(self._str("", True)) + return "".join(self._str("", True, None)) + + def _str(self, indent: str, compact: bool, behavior: dict | None) -> list[str]: + raise NotImplementedError def show(self, stream=sys.stdout): - stream.write("".join([*self._str("", False), "\n"])) + # TODO: deprecate lowlevel show + stream.write("".join([*self._str("", False, None), "\n"])) _str_parameters_exclude = ("__categorical__",) @@ -305,8 +314,8 @@ def from_datashape(datashape, highlevel=True): the return type is #ak.types.ArrayType, representing an #ak.highlevel.Array. If `highlevel=True` and the type string starts with a record indicator (e.g. `{`), - the return type is #ak.types.RecordType, representing an #ak.highlevel.Record, - rather than an array of them. + the return type is #ak.types.ScalarType with an #ak.types.RecordType content, + representing a scalar #ak.highlevel.Record rather than an array of them. Other strings (e.g. starting with `var *`, `?`, `option`, etc.) are not compatible with `highlevel=True`; an exception would be raised. @@ -317,6 +326,7 @@ def from_datashape(datashape, highlevel=True): from awkward.types.arraytype import ArrayType from awkward.types.recordtype import RecordType from awkward.types.regulartype import RegularType + from awkward.types.scalartype import ScalarType parser = Lark_StandAlone(transformer=_DataShapeTransformer()) out = parser.parse(datashape) @@ -325,7 +335,7 @@ def from_datashape(datashape, highlevel=True): if isinstance(out, RegularType): return ArrayType(out.content, out.size) elif isinstance(out, RecordType): - return out + return ScalarType(out) else: raise ValueError( f"type {type(out).__name__!r} is not compatible with highlevel=True" diff --git a/src/awkward/types/uniontype.py b/src/awkward/types/uniontype.py index 6585900860..fc7950392a 100644 --- a/src/awkward/types/uniontype.py +++ b/src/awkward/types/uniontype.py @@ -1,15 +1,28 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations from collections.abc import Iterable from itertools import permutations +from awkward._behavior import find_array_typestr +from awkward._errors import deprecate from awkward._parameters import parameters_are_equal, type_parameters_equal -from awkward._typing import final +from awkward._typing import Self, final +from awkward._util import UNSET from awkward.types.type import Type @final class UnionType(Type): + def copy( + self, *, contents: list[Type] = UNSET, parameters=UNSET, typestr=UNSET + ) -> Self: + return UnionType( + self._contents if contents is UNSET else contents, + parameters=self._parameters if parameters is UNSET else parameters, + typestr=self._typestr if typestr is UNSET else typestr, + ) + def __init__(self, contents, *, parameters=None, typestr=None): if not isinstance(contents, Iterable): raise TypeError( @@ -46,9 +59,13 @@ def __init__(self, contents, *, parameters=None, typestr=None): def contents(self): return self._contents - def _str(self, indent, compact): + def _str(self, indent, compact, behavior): if self._typestr is not None: - out = [self._typestr] + deprecate("typestr argument is deprecated", "2.4.0") + + typestr = find_array_typestr(behavior, self._parameters, self._typestr) + if typestr is not None: + out = [typestr] else: if compact: @@ -60,25 +77,30 @@ def _str(self, indent, compact): for i, x in enumerate(self._contents): if i + 1 < len(self._contents): if compact: - y = [*x._str(indent, compact), ", "] + y = [*x._str(indent, compact, behavior), ", "] else: - y = [*x._str(indent + " ", compact), ",\n", indent, " "] + y = [ + *x._str(indent + " ", compact, behavior), + ",\n", + indent, + " ", + ] else: if compact: - y = x._str(indent, compact) + y = x._str(indent, compact, behavior) else: - y = x._str(indent + " ", compact) + y = x._str(indent + " ", compact, behavior) children.append(y) flat_children = [y for x in children for y in x] params = self._str_parameters() if params is None: - out = ["union[", pre, *flat_children] + [post, "]"] + out = ["union[", pre, *flat_children, post, "]"] else: - out = ["union[", pre, *flat_children] + [", ", post, params, "]"] + out = ["union[", pre, *flat_children, ", ", post, params, "]"] - return [self._str_categorical_begin(), *out] + [self._str_categorical_end()] + return [self._str_categorical_begin(), *out, self._str_categorical_end()] def __repr__(self): args = [repr(self._contents), *self._repr_args()] diff --git a/src/awkward/types/unknowntype.py b/src/awkward/types/unknowntype.py index d797c9d948..611e9ee579 100644 --- a/src/awkward/types/unknowntype.py +++ b/src/awkward/types/unknowntype.py @@ -1,13 +1,22 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE +from __future__ import annotations +from awkward._behavior import find_array_typestr from awkward._errors import deprecate from awkward._parameters import parameters_are_equal, type_parameters_equal -from awkward._typing import final +from awkward._typing import Self, final +from awkward._util import UNSET from awkward.types.type import Type @final class UnknownType(Type): + def copy(self, *, parameters=UNSET, typestr=UNSET) -> Self: + return UnknownType( + parameters=self._parameters if parameters is UNSET else parameters, + typestr=self._typestr if typestr is UNSET else typestr, + ) + def __init__(self, *, parameters=None, typestr=None): if parameters is not None: deprecate( @@ -28,9 +37,13 @@ def __init__(self, *, parameters=None, typestr=None): self._parameters = parameters self._typestr = typestr - def _str(self, indent, compact): + def _str(self, indent, compact, behavior): if self._typestr is not None: - out = [self._typestr] + deprecate("typestr argument is deprecated", "2.4.0") + + typestr = find_array_typestr(behavior, self._parameters, self._typestr) + if typestr is not None: + out = [typestr] else: params = self._str_parameters() @@ -39,7 +52,7 @@ def _str(self, indent, compact): else: out = ["unknown[", params, "]"] - return [self._str_categorical_begin(), *out] + [self._str_categorical_end()] + return [self._str_categorical_begin(), *out, self._str_categorical_end()] def __repr__(self): args = self._repr_args() diff --git a/src/awkward/typetracer.py b/src/awkward/typetracer.py index 8be0f61cd5..0fba624ce9 100644 --- a/src/awkward/typetracer.py +++ b/src/awkward/typetracer.py @@ -1,5 +1,60 @@ from __future__ import annotations -__all__ = ["is_unknown_array", "is_unknown_scalar"] +__all__ = [ + "is_unknown_array", + "is_unknown_scalar", + "empty_if_typetracer", + "TypeTracerReport", + "typetracer_with_report", + "PlaceholderArray", + "unknown_length", +] -from awkward._nplikes.typetracer import is_unknown_array, is_unknown_scalar +from awkward._backends.typetracer import TypeTracerBackend +from awkward._behavior import behavior_of +from awkward._errors import deprecate +from awkward._layout import wrap_layout +from awkward._nplikes.placeholder import PlaceholderArray +from awkward._nplikes.shape import unknown_length +from awkward._nplikes.typetracer import ( + TypeTracerReport, + is_unknown_array, + is_unknown_scalar, + typetracer_with_report, +) +from awkward._typing import TypeVar +from awkward.forms import Form +from awkward.highlevel import Array, Record +from awkward.operations.ak_to_layout import to_layout + +T = TypeVar("T", Array, Record) + + +def _length_0_1_if_typetracer(array: T, function): + typetracer_backend = TypeTracerBackend.instance() + + layout = to_layout(array, allow_other=False) + behavior = behavior_of(array) + + if layout.backend is typetracer_backend: + layout._touch_data(True) + layout = function(layout.form, highlevel=False) + + return wrap_layout(layout, behavior=behavior) + + +def empty_if_typetracer(array: T) -> T: + deprecate( + "'empty_if_typetracer' is being replaced by 'length_zero_if_typetracer' (change name)", + "2.4.0", + ) + + return length_zero_if_typetracer(array) + + +def length_zero_if_typetracer(array: T) -> T: + return _length_0_1_if_typetracer(array, Form.length_zero_array) + + +def length_one_if_typetracer(array: T) -> T: + return _length_0_1_if_typetracer(array, Form.length_one_array) diff --git a/tests-cuda/test_1276_cuda_transfers.py b/tests-cuda/test_1276_cuda_transfers.py index f521ce959b..a4b6fa0ecc 100644 --- a/tests-cuda/test_1276_cuda_transfers.py +++ b/tests-cuda/test_1276_cuda_transfers.py @@ -2,7 +2,6 @@ import cupy as cp # noqa: F401 import numpy as np -import pytest import awkward as ak @@ -45,9 +44,6 @@ def test_tocuda(): assert ak.to_list(copyback_array) == ak.to_list(array) -@pytest.mark.skip( - reason="Can't test this right now because of unimplemented CUDA Kernels (awkward_ListOffsetArray_compact_offsets)" -) def test_tocuda_unimplementedkernels(): content = ak.contents.NumpyArray( np.array([1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9]) diff --git a/tests-cuda/test_1276_from_cupy.py b/tests-cuda/test_1276_from_cupy.py index 343398a022..81dc62e058 100644 --- a/tests-cuda/test_1276_from_cupy.py +++ b/tests-cuda/test_1276_from_cupy.py @@ -2,7 +2,6 @@ import cupy as cp import numpy as np -import pytest import awkward as ak @@ -35,9 +34,6 @@ def test_NumpyArray_constructor(): assert ak.backend(ak.contents.NumpyArray(cp.array([1, 2, 3]))) == "cuda" -@pytest.mark.skip( - reason="Can't test this right now because of unimplemented CUDA Kernels (awkward_ListOffsetArray_compact_offsets" -) def test_add(): one = ak.Array([[1.1, 2.2, 3.3], [], [4.4, 5.5]], backend="cuda") two = ak.Array([100, 200, 300], backend="cuda") diff --git a/tests/test_0032_replace_dressedtype.py b/tests/test_0032_replace_dressedtype.py index 51a9e249a3..9e5930342a 100644 --- a/tests/test_0032_replace_dressedtype.py +++ b/tests/test_0032_replace_dressedtype.py @@ -93,7 +93,6 @@ def __str__(self): def test_record_name(): - typestrs = {} builder = ak.highlevel.ArrayBuilder() builder.begin_record("Dummy") @@ -112,8 +111,8 @@ def test_record_name(): a = builder.snapshot() - assert str(a.layout.form._type(typestrs)) == "Dummy[one: int64, two: float64]" - assert a.layout.form._type(typestrs).parameters == {"__record__": "Dummy"} + assert str(a.layout.form.type) == "Dummy[one: int64, two: float64]" + assert a.layout.form.type.parameters == {"__record__": "Dummy"} def test_builder_string(): diff --git a/tests/test_0674_categorical_validation.py b/tests/test_0674_categorical_validation.py index 54a78772a7..aac5358d1d 100644 --- a/tests/test_0674_categorical_validation.py +++ b/tests/test_0674_categorical_validation.py @@ -48,7 +48,7 @@ def test_categorical_from_arrow_ChunkedArray(): ) batches = [batch] * 3 - batches_mixed_schema = [batch] + [batch_new_schema] + batches_mixed_schema = [batch, batch_new_schema] table = pyarrow.Table.from_batches(batches) table_mixed_schema = pyarrow.Table.from_batches(batches_mixed_schema) diff --git a/tests/test_0773_typeparser.py b/tests/test_0773_typeparser.py index b676deec0c..98080d5a75 100644 --- a/tests/test_0773_typeparser.py +++ b/tests/test_0773_typeparser.py @@ -437,7 +437,7 @@ def test_hardcoded(): def test_record_highlevel(): text = "Thingy[x: int64, y: float64]" parsedtype = ak.types.from_datashape(text, highlevel=True) - assert isinstance(parsedtype, ak.types.RecordType) + assert isinstance(parsedtype, ak.types.ScalarType) assert str(parsedtype) == text diff --git a/tests/test_0914_types_and_forms.py b/tests/test_0914_types_and_forms.py index 012193c4f8..9f92213c04 100644 --- a/tests/test_0914_types_and_forms.py +++ b/tests/test_0914_types_and_forms.py @@ -6,6 +6,22 @@ import awkward as ak +def assert_overrides_typestr(type_, typestr: str = "override", expected: str = None): + # Assume typestr is expected result + if expected is None: + expected = typestr + # Set appropriate array or record parameter + if isinstance(type_, ak.types.RecordType): + parameters = {**type_.parameters, "__record__": "custom"} + else: + parameters = {**type_.parameters, "__array__": "custom"} + behavior = {("__typestr__", "custom"): typestr} + # Build highlevel type with custom behavior + with_parameter = type_.copy(parameters=parameters) + as_str = "".join(with_parameter._str("", False, behavior)) + assert as_str == expected + + def test_UnknownType(): assert str(ak.types.unknowntype.UnknownType()) == "unknown" with pytest.warns(DeprecationWarning): @@ -13,18 +29,11 @@ def test_UnknownType(): str(ak.types.unknowntype.UnknownType(parameters={"x": 123})) == 'unknown[parameters={"x": 123}]' ) - assert ( - str(ak.types.unknowntype.UnknownType(parameters=None, typestr="override")) - == "override" - ) with pytest.warns(DeprecationWarning): - assert ( - str( - ak.types.unknowntype.UnknownType( - parameters={"x": 123}, typestr="override" - ) - ) - == "override" + assert_overrides_typestr(ak.types.unknowntype.UnknownType()) + + assert_overrides_typestr( + ak.types.unknowntype.UnknownType(parameters={"x": 123}) ) assert ( str(ak.types.unknowntype.UnknownType(parameters={"__categorical__": True})) @@ -38,24 +47,18 @@ def test_UnknownType(): ) == 'categorical[type=unknown[parameters={"x": 123}]]' ) - assert ( - str( - ak.types.unknowntype.UnknownType( - parameters={"__categorical__": True}, typestr="override" - ) - ) - == "categorical[type=override]" + assert_overrides_typestr( + ak.types.unknowntype.UnknownType( + parameters={"__categorical__": True, "x": 123} + ), + expected="categorical[type=override]", ) assert repr(ak.types.unknowntype.UnknownType()) == "UnknownType()" with pytest.warns(DeprecationWarning): assert ( - repr( - ak.types.unknowntype.UnknownType( - parameters={"__categorical__": True}, typestr="override" - ) - ) - == "UnknownType(parameters={'__categorical__': True}, typestr='override')" + repr(ak.types.unknowntype.UnknownType(parameters={"__categorical__": True})) + == "UnknownType(parameters={'__categorical__': True})" ) @@ -87,17 +90,10 @@ def test_NumpyType(): str(ak.types.numpytype.NumpyType("bool", parameters={"x": 123})) == 'bool[parameters={"x": 123}]' ) - assert ( - str(ak.types.numpytype.NumpyType("bool", parameters=None, typestr="override")) - == "override" - ) - assert ( - str( - ak.types.numpytype.NumpyType( - "bool", parameters={"x": 123}, typestr="override" - ) - ) - == "override" + assert_overrides_typestr(ak.types.numpytype.NumpyType("bool")) + + assert_overrides_typestr( + ak.types.numpytype.NumpyType("bool", parameters={"x": 123}) ) assert ( str(ak.types.numpytype.NumpyType("bool", parameters={"__categorical__": True})) @@ -111,13 +107,10 @@ def test_NumpyType(): ) == 'categorical[type=bool[parameters={"x": 123}]]' ) - assert ( - str( - ak.types.numpytype.NumpyType( - "bool", parameters={"__categorical__": True}, typestr="override" - ) - ) - == "categorical[type=override]" + + assert_overrides_typestr( + ak.types.numpytype.NumpyType("bool", parameters={"__categorical__": True}), + expected="categorical[type=override]", ) assert str(ak.types.numpytype.NumpyType("datetime64")) == "datetime64" assert ( @@ -277,12 +270,10 @@ def test_NumpyType(): assert ( repr( ak.types.numpytype.NumpyType( - primitive="bool", - parameters={"__categorical__": True}, - typestr="override", + primitive="bool", parameters={"__categorical__": True} ) ) - == "NumpyType('bool', parameters={'__categorical__': True}, typestr='override')" + == "NumpyType('bool', parameters={'__categorical__': True})" ) assert ( repr( @@ -329,27 +320,19 @@ def test_RegularType(): ) == '[10 * unknown, parameters={"x": 123}]' ) - assert ( - str( - ak.types.regulartype.RegularType( - ak.types.unknowntype.UnknownType(), - 10, - parameters=None, - typestr="override", - ) - ) - == "override" + + assert_overrides_typestr( + ak.types.regulartype.RegularType(ak.types.unknowntype.UnknownType(), 10), + expected="override[10]", ) - assert ( - str( - ak.types.regulartype.RegularType( - ak.types.unknowntype.UnknownType(), - 10, - parameters={"x": 123}, - typestr="override", - ) - ) - == "override" + + assert_overrides_typestr( + ak.types.regulartype.RegularType( + ak.types.unknowntype.UnknownType(), + 10, + parameters={"x": 123}, + ), + expected="override[10]", ) assert ( str( @@ -371,16 +354,13 @@ def test_RegularType(): ) == 'categorical[type=[10 * unknown, parameters={"x": 123}]]' ) - assert ( - str( - ak.types.regulartype.RegularType( - ak.types.unknowntype.UnknownType(), - 10, - parameters={"__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" + assert_overrides_typestr( + ak.types.regulartype.RegularType( + ak.types.unknowntype.UnknownType(), + 10, + parameters={"__categorical__": True}, + ), + expected="categorical[type=override[10]]", ) assert ( str( @@ -417,10 +397,9 @@ def test_RegularType(): content=ak.types.unknowntype.UnknownType(), size=10, parameters={"__categorical__": True}, - typestr="override", ) ) - == "RegularType(UnknownType(), 10, parameters={'__categorical__': True}, typestr='override')" + == "RegularType(UnknownType(), 10, parameters={'__categorical__': True})" ) assert ( repr( @@ -461,23 +440,14 @@ def test_ListType(): ) == '[var * unknown, parameters={"x": 123}]' ) - assert ( - str( - ak.types.listtype.ListType( - ak.types.unknowntype.UnknownType(), parameters=None, typestr="override" - ) - ) - == "override" + assert_overrides_typestr( + ak.types.listtype.ListType(ak.types.unknowntype.UnknownType()) ) - assert ( - str( - ak.types.listtype.ListType( - ak.types.unknowntype.UnknownType(), - parameters={"x": 123}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.listtype.ListType( + ak.types.unknowntype.UnknownType(), + parameters={"x": 123}, ) - == "override" ) assert ( str( @@ -496,15 +466,12 @@ def test_ListType(): ) == 'categorical[type=[var * unknown, parameters={"x": 123}]]' ) - assert ( - str( - ak.types.listtype.ListType( - ak.types.unknowntype.UnknownType(), - parameters={"__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" + assert_overrides_typestr( + ak.types.listtype.ListType( + ak.types.unknowntype.UnknownType(), + parameters={"__categorical__": True}, + ), + expected="categorical[type=override]", ) assert ( str( @@ -534,10 +501,9 @@ def test_ListType(): ak.types.listtype.ListType( content=ak.types.unknowntype.UnknownType(), parameters={"__categorical__": True}, - typestr="override", ) ) - == "ListType(UnknownType(), parameters={'__categorical__': True}, typestr='override')" + == "ListType(UnknownType(), parameters={'__categorical__': True})" ) assert ( repr( @@ -614,61 +580,43 @@ def test_RecordType(): ) == "Name[x: unknown, y: bool]" ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - None, - parameters=None, - typestr="override", - ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + None, ) - == "override" ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - ["x", "y"], - parameters=None, - typestr="override", - ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + ["x", "y"], ) - == "override" ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - None, - parameters={"__record__": "Name"}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + None, + parameters={"__record__": "Name"}, ) - == "override" ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - ["x", "y"], - parameters={"__record__": "Name"}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + ["x", "y"], + parameters={"__record__": "Name"}, ) - == "override" ) assert ( str( @@ -722,61 +670,45 @@ def test_RecordType(): ) == 'Name[x: unknown, y: bool, parameters={"x": 123}]' ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - None, - parameters={"x": 123}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + None, + parameters={"x": 123}, ) - == "override" ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - ["x", "y"], - parameters={"x": 123}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + ["x", "y"], + parameters={"x": 123}, ) - == "override" ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - None, - parameters={"__record__": "Name", "x": 123}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + None, + parameters={"__record__": "Name", "x": 123}, ) - == "override" ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - ["x", "y"], - parameters={"__record__": "Name", "x": 123}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + ["x", "y"], + parameters={"__record__": "Name", "x": 123}, ) - == "override" ) assert ( str( @@ -830,6 +762,50 @@ def test_RecordType(): ) == "categorical[type=Name[x: unknown, y: bool]]" ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + None, + parameters={"__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + ["x", "y"], + parameters={"__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + None, + parameters={"__record__": "Name", "__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + ["x", "y"], + parameters={"__record__": "Name", "__categorical__": True}, + ), + expected="categorical[type=override]", + ) assert ( str( ak.types.recordtype.RecordType( @@ -838,11 +814,10 @@ def test_RecordType(): ak.types.numpytype.NumpyType("bool"), ], None, - parameters={"__categorical__": True}, - typestr="override", + parameters={"x": 123, "__categorical__": True}, ) ) - == "categorical[type=override]" + == 'categorical[type=tuple[[unknown, bool], parameters={"x": 123}]]' ) assert ( str( @@ -852,11 +827,10 @@ def test_RecordType(): ak.types.numpytype.NumpyType("bool"), ], ["x", "y"], - parameters={"__categorical__": True}, - typestr="override", + parameters={"x": 123, "__categorical__": True}, ) ) - == "categorical[type=override]" + == 'categorical[type=struct[{x: unknown, y: bool}, parameters={"x": 123}]]' ) assert ( str( @@ -866,11 +840,10 @@ def test_RecordType(): ak.types.numpytype.NumpyType("bool"), ], None, - parameters={"__record__": "Name", "__categorical__": True}, - typestr="override", + parameters={"__record__": "Name", "x": 123, "__categorical__": True}, ) ) - == "categorical[type=override]" + == 'categorical[type=Name[unknown, bool, parameters={"x": 123}]]' ) assert ( str( @@ -880,192 +853,125 @@ def test_RecordType(): ak.types.numpytype.NumpyType("bool"), ], ["x", "y"], - parameters={"__record__": "Name", "__categorical__": True}, - typestr="override", + parameters={"__record__": "Name", "x": 123, "__categorical__": True}, ) ) - == "categorical[type=override]" + == 'categorical[type=Name[x: unknown, y: bool, parameters={"x": 123}]]' ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + None, + parameters={"x": 123, "__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + ["x", "y"], + parameters={"x": 123, "__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + None, + parameters={"__record__": "Name", "x": 123, "__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.recordtype.RecordType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + ["x", "y"], + parameters={"__record__": "Name", "x": 123, "__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert ( - str( + repr( ak.types.recordtype.RecordType( - [ + contents=[ ak.types.unknowntype.UnknownType(), ak.types.numpytype.NumpyType("bool"), ], - None, - parameters={"x": 123, "__categorical__": True}, + fields=None, ) ) - == 'categorical[type=tuple[[unknown, bool], parameters={"x": 123}]]' + == "RecordType([UnknownType(), NumpyType('bool')], None)" ) assert ( - str( + repr( ak.types.recordtype.RecordType( - [ + contents=[ ak.types.unknowntype.UnknownType(), ak.types.numpytype.NumpyType("bool"), ], - ["x", "y"], - parameters={"x": 123, "__categorical__": True}, + fields=["x", "y"], ) ) - == 'categorical[type=struct[{x: unknown, y: bool}, parameters={"x": 123}]]' + == "RecordType([UnknownType(), NumpyType('bool')], ['x', 'y'])" ) assert ( - str( + repr( ak.types.recordtype.RecordType( - [ + contents=[ ak.types.unknowntype.UnknownType(), ak.types.numpytype.NumpyType("bool"), ], - None, + fields=None, parameters={"__record__": "Name", "x": 123, "__categorical__": True}, ) ) - == 'categorical[type=Name[unknown, bool, parameters={"x": 123}]]' + == "RecordType([UnknownType(), NumpyType('bool')], None, parameters={'__record__': 'Name', 'x': 123, '__categorical__': True})" ) assert ( - str( + repr( ak.types.recordtype.RecordType( - [ + contents=[ ak.types.unknowntype.UnknownType(), ak.types.numpytype.NumpyType("bool"), ], - ["x", "y"], + fields=None, parameters={"__record__": "Name", "x": 123, "__categorical__": True}, ) ) - == 'categorical[type=Name[x: unknown, y: bool, parameters={"x": 123}]]' + == "RecordType([UnknownType(), NumpyType('bool')], None, parameters={'__record__': 'Name', 'x': 123, '__categorical__': True})" ) assert ( - str( + repr( ak.types.recordtype.RecordType( - [ + contents=[ ak.types.unknowntype.UnknownType(), ak.types.numpytype.NumpyType("bool"), ], - None, - parameters={"x": 123, "__categorical__": True}, - typestr="override", + fields=["x", "y"], + parameters={"__record__": "Name", "x": 123, "__categorical__": True}, ) ) - == "categorical[type=override]" - ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - ["x", "y"], - parameters={"x": 123, "__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" - ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - None, - parameters={"__record__": "Name", "x": 123, "__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" - ) - assert ( - str( - ak.types.recordtype.RecordType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - ["x", "y"], - parameters={"__record__": "Name", "x": 123, "__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" - ) - - assert ( - repr( - ak.types.recordtype.RecordType( - contents=[ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - fields=None, - ) - ) - == "RecordType([UnknownType(), NumpyType('bool')], None)" - ) - assert ( - repr( - ak.types.recordtype.RecordType( - contents=[ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - fields=["x", "y"], - ) - ) - == "RecordType([UnknownType(), NumpyType('bool')], ['x', 'y'])" - ) - assert ( - repr( - ak.types.recordtype.RecordType( - contents=[ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - fields=None, - parameters={"__record__": "Name", "x": 123, "__categorical__": True}, - typestr="override", - ) - ) - == "RecordType([UnknownType(), NumpyType('bool')], None, parameters={'__record__': 'Name', 'x': 123, '__categorical__': True}, typestr='override')" - ) - assert ( - repr( - ak.types.recordtype.RecordType( - contents=[ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - fields=None, - parameters={"__record__": "Name", "x": 123, "__categorical__": True}, - ) - ) - == "RecordType([UnknownType(), NumpyType('bool')], None, parameters={'__record__': 'Name', 'x': 123, '__categorical__': True})" - ) - assert ( - repr( - ak.types.recordtype.RecordType( - contents=[ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - fields=["x", "y"], - parameters={"__record__": "Name", "x": 123, "__categorical__": True}, - typestr="override", - ) - ) - == "RecordType([UnknownType(), NumpyType('bool')], ['x', 'y'], parameters={'__record__': 'Name', 'x': 123, '__categorical__': True}, typestr='override')" - ) - - -def test_OptionType(): - assert ( - str(ak.types.optiontype.OptionType(ak.types.unknowntype.UnknownType())) - == "?unknown" + == "RecordType([UnknownType(), NumpyType('bool')], ['x', 'y'], parameters={'__record__': 'Name', 'x': 123, '__categorical__': True})" + ) + + +def test_OptionType(): + assert ( + str(ak.types.optiontype.OptionType(ak.types.unknowntype.UnknownType())) + == "?unknown" ) assert ( str( @@ -1111,67 +1017,39 @@ def test_OptionType(): ) == 'option[10 * unknown, parameters={"x": 123}]' ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.unknowntype.UnknownType(), parameters=None, typestr="override" - ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.unknowntype.UnknownType(), parameters=None ) - == "override" ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.listtype.ListType(ak.types.unknowntype.UnknownType()), - parameters=None, - typestr="override", - ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.listtype.ListType(ak.types.unknowntype.UnknownType()), + parameters=None, ) - == "override" ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.regulartype.RegularType( - ak.types.unknowntype.UnknownType(), 10 - ), - parameters=None, - typestr="override", - ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.regulartype.RegularType(ak.types.unknowntype.UnknownType(), 10) ) - == "override" ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.unknowntype.UnknownType(), - parameters={"x": 123}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.unknowntype.UnknownType(), + parameters={"x": 123}, ) - == "override" ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.listtype.ListType(ak.types.unknowntype.UnknownType()), - parameters={"x": 123}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.listtype.ListType(ak.types.unknowntype.UnknownType()), + parameters={"x": 123}, ) - == "override" ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.regulartype.RegularType( - ak.types.unknowntype.UnknownType(), 10 - ), - parameters={"x": 123}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.regulartype.RegularType(ak.types.unknowntype.UnknownType(), 10), + parameters={"x": 123}, ) - == "override" ) assert ( str( @@ -1230,69 +1108,47 @@ def test_OptionType(): ) == 'option[categorical[type=10 * unknown], parameters={"x": 123}]' ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.unknowntype.UnknownType(), - parameters={"__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" - ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.listtype.ListType(ak.types.unknowntype.UnknownType()), - parameters={"__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" - ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.regulartype.RegularType( - ak.types.unknowntype.UnknownType(), 10 - ), - parameters={"__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" - ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.unknowntype.UnknownType(), - parameters={"x": 123, "__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" - ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.listtype.ListType(ak.types.unknowntype.UnknownType()), - parameters={"x": 123, "__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" - ) - assert ( - str( - ak.types.optiontype.OptionType( - ak.types.regulartype.RegularType( - ak.types.unknowntype.UnknownType(), 10 - ), - parameters={"x": 123, "__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.unknowntype.UnknownType(), + parameters={"__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.listtype.ListType(ak.types.unknowntype.UnknownType()), + parameters={"__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.regulartype.RegularType(ak.types.unknowntype.UnknownType(), 10), + parameters={"__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.unknowntype.UnknownType(), + parameters={"x": 123, "__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.listtype.ListType(ak.types.unknowntype.UnknownType()), + parameters={"x": 123, "__categorical__": True}, + ), + expected="categorical[type=override]", + ) + assert_overrides_typestr( + ak.types.optiontype.OptionType( + ak.types.regulartype.RegularType(ak.types.unknowntype.UnknownType(), 10), + parameters={"x": 123, "__categorical__": True}, + ), + expected="categorical[type=override]", ) assert ( @@ -1314,10 +1170,9 @@ def test_OptionType(): ak.types.unknowntype.UnknownType(), 10 ), parameters={"x": 123, "__categorical__": True}, - typestr="override", ) ) - == "OptionType(RegularType(UnknownType(), 10), parameters={'x': 123, '__categorical__': True}, typestr='override')" + == "OptionType(RegularType(UnknownType(), 10), parameters={'x': 123, '__categorical__': True})" ) @@ -1345,31 +1200,23 @@ def test_UnionType(): ) == 'union[unknown, bool, parameters={"x": 123}]' ) - assert ( - str( - ak.types.uniontype.UnionType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - parameters=None, - typestr="override", - ) + assert_overrides_typestr( + ak.types.uniontype.UnionType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + parameters=None, ) - == "override" ) - assert ( - str( - ak.types.uniontype.UnionType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - parameters={"x": 123}, - typestr="override", - ) + assert_overrides_typestr( + ak.types.uniontype.UnionType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + parameters={"x": 123}, ) - == "override" ) assert ( str( @@ -1395,31 +1242,25 @@ def test_UnionType(): ) == 'categorical[type=union[unknown, bool, parameters={"x": 123}]]' ) - assert ( - str( - ak.types.uniontype.UnionType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - parameters={"__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" + assert_overrides_typestr( + ak.types.uniontype.UnionType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + parameters={"__categorical__": True}, + ), + expected="categorical[type=override]", ) - assert ( - str( - ak.types.uniontype.UnionType( - [ - ak.types.unknowntype.UnknownType(), - ak.types.numpytype.NumpyType("bool"), - ], - parameters={"x": 123, "__categorical__": True}, - typestr="override", - ) - ) - == "categorical[type=override]" + assert_overrides_typestr( + ak.types.uniontype.UnionType( + [ + ak.types.unknowntype.UnknownType(), + ak.types.numpytype.NumpyType("bool"), + ], + parameters={"x": 123, "__categorical__": True}, + ), + expected="categorical[type=override]", ) assert ( @@ -1441,10 +1282,9 @@ def test_UnionType(): ak.types.numpytype.NumpyType("bool"), ], parameters={"x": 123, "__categorical__": True}, - typestr="override", ) ) - == "UnionType([UnknownType(), NumpyType('bool')], parameters={'x': 123, '__categorical__': True}, typestr='override')" + == "UnionType([UnknownType(), NumpyType('bool')], parameters={'x': 123, '__categorical__': True})" ) @@ -1461,11 +1301,9 @@ def test_ArrayType(): ak.types.arraytype.ArrayType(ak.types.unknowntype.UnknownType(), -1) # ArrayType should not have these arguments (should not be a Type subclass) - with pytest.raises(TypeError): - ak.types.arraytype.ArrayType(ak.types.unknowntype.UnknownType(), 10, {"x": 123}) with pytest.raises(TypeError): ak.types.arraytype.ArrayType( - ak.types.unknowntype.UnknownType(), 10, None, typestr="override" + ak.types.arraytype.ArrayType(ak.types.unknowntype.UnknownType(), 10), 10 ) assert ( @@ -1474,7 +1312,32 @@ def test_ArrayType(): content=ak.types.unknowntype.UnknownType(), length=10 ) ) - == "ArrayType(UnknownType(), 10)" + == "ArrayType(UnknownType(), 10, None)" + ) + + assert ( + str( + ak.types.arraytype.ArrayType( + content=ak.types.numpytype.NumpyType( + "int64", parameters={"__array__": "custom"} + ), + length=10, + behavior={("__typestr__", "custom"): "override"}, + ) + ) + == "10 * override" + ) + + assert ( + str( + ak.types.arraytype.ArrayType( + content=ak.types.numpytype.NumpyType( + "int64", parameters={"__array__": "custom"} + ), + length=10, + ) + ) + == '10 * int64[parameters={"__array__": "custom"}]' ) @@ -1691,132 +1554,197 @@ def test_NumpyForm(): "parameters": {"__unit__": "s", "x": 123}, } - assert ak.forms.numpyform.from_dtype(np.dtype("bool")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "bool", - } - assert ak.forms.numpyform.from_dtype(np.dtype("int8")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "int8", - } - assert ak.forms.numpyform.from_dtype(np.dtype("uint8")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "uint8", - } - assert ak.forms.numpyform.from_dtype(np.dtype("int16")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "int16", - } - assert ak.forms.numpyform.from_dtype(np.dtype("uint16")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "uint16", - } - assert ak.forms.numpyform.from_dtype(np.dtype("int32")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "int32", - } - assert ak.forms.numpyform.from_dtype(np.dtype("uint32")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "uint32", - } - assert ak.forms.numpyform.from_dtype(np.dtype("int64")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "int64", - } - assert ak.forms.numpyform.from_dtype(np.dtype("uint64")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "uint64", - } - if hasattr(np, "float16"): - assert ak.forms.numpyform.from_dtype(np.dtype("float16")).to_dict( + with pytest.warns(DeprecationWarning): + assert ak.forms.numpyform.from_dtype(np.dtype("bool")).to_dict( verbose=False ) == { "class": "NumpyArray", - "primitive": "float16", + "primitive": "bool", } - assert ak.forms.numpyform.from_dtype(np.dtype("float32")).to_dict( - verbose=False - ) == { - "class": "NumpyArray", - "primitive": "float32", - } - assert ak.forms.numpyform.from_dtype(np.dtype("float64")).to_dict( - verbose=False - ) == { - "class": "NumpyArray", - "primitive": "float64", - } - if hasattr(np, "float128"): - assert ak.forms.numpyform.from_dtype(np.dtype("float128")).to_dict( + assert ak.forms.numpyform.from_dtype(np.dtype("int8")).to_dict( verbose=False ) == { "class": "NumpyArray", - "primitive": "float128", + "primitive": "int8", } - assert ak.forms.numpyform.from_dtype(np.dtype("complex64")).to_dict( - verbose=False - ) == { - "class": "NumpyArray", - "primitive": "complex64", - } - assert ak.forms.numpyform.from_dtype(np.dtype("complex128")).to_dict( - verbose=False - ) == { - "class": "NumpyArray", - "primitive": "complex128", - } - if hasattr(np, "complex256"): - assert ak.forms.numpyform.from_dtype(np.dtype("complex256")).to_dict( + assert ak.forms.numpyform.from_dtype(np.dtype("uint8")).to_dict( verbose=False ) == { "class": "NumpyArray", - "primitive": "complex256", + "primitive": "uint8", } - assert ak.forms.numpyform.from_dtype(np.dtype("M8")).to_dict(verbose=False) == { - "class": "NumpyArray", - "primitive": "datetime64", - } - assert ak.forms.numpyform.from_dtype(np.dtype("M8[s]")).to_dict(verbose=False) == { + assert ak.forms.numpyform.from_dtype(np.dtype("int16")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "int16", + } + assert ak.forms.numpyform.from_dtype(np.dtype("uint16")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "uint16", + } + assert ak.forms.numpyform.from_dtype(np.dtype("int32")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "int32", + } + assert ak.forms.numpyform.from_dtype(np.dtype("uint32")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "uint32", + } + assert ak.forms.numpyform.from_dtype(np.dtype("int64")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "int64", + } + assert ak.forms.numpyform.from_dtype(np.dtype("uint64")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "uint64", + } + if hasattr(np, "float16"): + assert ak.forms.numpyform.from_dtype(np.dtype("float16")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "float16", + } + assert ak.forms.numpyform.from_dtype(np.dtype("float32")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "float32", + } + assert ak.forms.numpyform.from_dtype(np.dtype("float64")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "float64", + } + if hasattr(np, "float128"): + assert ak.forms.numpyform.from_dtype(np.dtype("float128")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "float128", + } + assert ak.forms.numpyform.from_dtype(np.dtype("complex64")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "complex64", + } + assert ak.forms.numpyform.from_dtype(np.dtype("complex128")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "complex128", + } + if hasattr(np, "complex256"): + assert ak.forms.numpyform.from_dtype(np.dtype("complex256")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "complex256", + } + assert ak.forms.numpyform.from_dtype(np.dtype("M8")).to_dict(verbose=False) == { + "class": "NumpyArray", + "primitive": "datetime64", + } + assert ak.forms.numpyform.from_dtype(np.dtype("M8[s]")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "datetime64", + "parameters": {"__unit__": "s"}, + } + assert ak.forms.numpyform.from_dtype( + np.dtype("M8[s]"), parameters={"x": 123} + ).to_dict(verbose=False) == { + "class": "NumpyArray", + "primitive": "datetime64", + "parameters": {"__unit__": "s", "x": 123}, + } + assert ak.forms.numpyform.from_dtype(np.dtype("m8")).to_dict(verbose=False) == { + "class": "NumpyArray", + "primitive": "timedelta64", + } + assert ak.forms.numpyform.from_dtype(np.dtype("m8[s]")).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "timedelta64", + "parameters": {"__unit__": "s"}, + } + assert ak.forms.numpyform.from_dtype( + np.dtype("m8[s]"), parameters={"x": 123} + ).to_dict(verbose=False) == { + "class": "NumpyArray", + "primitive": "timedelta64", + "parameters": {"__unit__": "s", "x": 123}, + } + assert ak.forms.numpyform.from_dtype(np.dtype(("bool", (1, 2, 3)))).to_dict( + verbose=False + ) == { + "class": "NumpyArray", + "primitive": "bool", + "inner_shape": [1, 2, 3], + } + + assert ak.forms.numpyform.from_dtype( + np.dtype("M8"), time_units_as_parameter=False + ).to_dict(verbose=False) == { "class": "NumpyArray", "primitive": "datetime64", - "parameters": {"__unit__": "s"}, } assert ak.forms.numpyform.from_dtype( - np.dtype("M8[s]"), parameters={"x": 123} + np.dtype("M8[s]"), time_units_as_parameter=False ).to_dict(verbose=False) == { "class": "NumpyArray", - "primitive": "datetime64", - "parameters": {"__unit__": "s", "x": 123}, + "primitive": "datetime64[s]", } - assert ak.forms.numpyform.from_dtype(np.dtype("m8")).to_dict(verbose=False) == { + assert ak.forms.numpyform.from_dtype( + np.dtype("M8[s]"), time_units_as_parameter=False, parameters={"x": 123} + ).to_dict(verbose=False) == { "class": "NumpyArray", - "primitive": "timedelta64", + "primitive": "datetime64[s]", + "parameters": {"x": 123}, } - assert ak.forms.numpyform.from_dtype(np.dtype("m8[s]")).to_dict(verbose=False) == { + assert ak.forms.numpyform.from_dtype( + np.dtype("m8"), time_units_as_parameter=False + ).to_dict(verbose=False) == { "class": "NumpyArray", "primitive": "timedelta64", - "parameters": {"__unit__": "s"}, } assert ak.forms.numpyform.from_dtype( - np.dtype("m8[s]"), parameters={"x": 123} + np.dtype("m8[s]"), time_units_as_parameter=False ).to_dict(verbose=False) == { "class": "NumpyArray", - "primitive": "timedelta64", - "parameters": {"__unit__": "s", "x": 123}, + "primitive": "timedelta64[s]", } - assert ak.forms.numpyform.from_dtype(np.dtype(("bool", (1, 2, 3)))).to_dict( - verbose=False - ) == { + assert ak.forms.numpyform.from_dtype( + np.dtype("m8[s]"), parameters={"x": 123}, time_units_as_parameter=False + ).to_dict(verbose=False) == { "class": "NumpyArray", - "primitive": "bool", - "inner_shape": [1, 2, 3], + "primitive": "timedelta64[s]", + "parameters": {"x": 123}, } with pytest.raises(TypeError): - ak.forms.from_dtype(np.dtype("O")).to_dict(verbose=False) - with pytest.raises(TypeError): - ak.forms.from_dtype(np.dtype([("one", np.int64), ("two", np.float64)])).to_dict( + ak.forms.from_dtype(np.dtype("O"), time_units_as_parameter=False).to_dict( verbose=False ) + with pytest.raises(TypeError): + ak.forms.from_dtype( + np.dtype([("one", np.int64), ("two", np.float64)]), + time_units_as_parameter=False, + ).to_dict(verbose=False) assert ak.forms.from_dict("bool").to_dict(verbose=False) == { "class": "NumpyArray", "primitive": "bool", diff --git a/tests/test_1125_to_arrow_from_arrow.py b/tests/test_1125_to_arrow_from_arrow.py index 03cb835045..344d54eddd 100644 --- a/tests/test_1125_to_arrow_from_arrow.py +++ b/tests/test_1125_to_arrow_from_arrow.py @@ -623,9 +623,11 @@ def test_unionarray(tmp_path, extensionarray): ak.index.Index8(np.array([0, 0, 1, 1, 1, 0, 1], dtype=np.int8)), ak.index.Index64(np.array([0, 1, 3, 2, 1, 2, 0], dtype=np.int64)), [ - ak.contents.NumpyArray( - np.array([0.0, 1.1, 2.2]), - parameters={"which": "inner1"}, + ak.contents.UnmaskedArray( + ak.contents.NumpyArray( + np.array([0.0, 1.1, 2.2]), + parameters={"which": "inner1"}, + ) ), ak.contents.ByteMaskedArray( ak.index.Index8(np.array([False, False, True, False]).view(np.int8)), @@ -674,8 +676,10 @@ def test_unionarray(tmp_path, extensionarray): ak.index.Index8(np.array([0, 0, 1, 1, 1, 0, 1], dtype=np.int8)), ak.index.Index64(np.array([0, 1, 3, 2, 1, 2, 0], dtype=np.int64)), [ - ak.contents.NumpyArray( - np.array([0.0, 1.1, 2.2]), parameters={"which": "inner1"} + ak.contents.UnmaskedArray( + ak.contents.NumpyArray( + np.array([0.0, 1.1, 2.2]), parameters={"which": "inner1"} + ) ), ak.contents.ByteMaskedArray( ak.index.Index8( diff --git a/tests/test_1240_v2_implementation_of_numba_1.py b/tests/test_1240_v2_implementation_of_numba_1.py index 01b3c25d91..1ba44ab497 100644 --- a/tests/test_1240_v2_implementation_of_numba_1.py +++ b/tests/test_1240_v2_implementation_of_numba_1.py @@ -22,7 +22,7 @@ def roundtrip(layout): lookup = ak._lookup.Lookup(layout) assert isinstance(lookup, ak._lookup.Lookup) - numbatype = ak_numba_arrayview.tonumbatype(layout.form) + numbatype = ak_numba_arrayview.to_numbatype(layout.form) assert isinstance(numbatype, ak_numba_layout.ContentType) layout2 = numbatype.tolayout(lookup, 0, ()) diff --git a/tests/test_1294_to_and_from_parquet.py b/tests/test_1294_to_and_from_parquet.py index 048f569043..e79e7babb7 100644 --- a/tests/test_1294_to_and_from_parquet.py +++ b/tests/test_1294_to_and_from_parquet.py @@ -740,9 +740,11 @@ def test_unionarray(tmp_path, through, extensionarray): ak.index.Index8(np.array([0, 0, 1, 1, 1, 0, 1], dtype=np.int8)), ak.index.Index64(np.array([0, 1, 3, 2, 1, 2, 0], dtype=np.int64)), [ - ak.contents.NumpyArray( - np.array([0.0, 1.1, 2.2]), - parameters={"which": "inner1"}, + ak.contents.UnmaskedArray( + ak.contents.NumpyArray( + np.array([0.0, 1.1, 2.2]), + parameters={"which": "inner1"}, + ) ), ak.contents.ByteMaskedArray( ak.index.Index8(np.array([False, False, True, False]).view(np.int8)), @@ -801,8 +803,10 @@ def test_unionarray(tmp_path, through, extensionarray): ak.index.Index8(np.array([0, 0, 1, 1, 1, 0, 1], dtype=np.int8)), ak.index.Index64(np.array([0, 1, 3, 2, 1, 2, 0], dtype=np.int64)), [ - ak.contents.NumpyArray( - np.array([0.0, 1.1, 2.2]), parameters={"which": "inner1"} + ak.contents.UnmaskedArray( + ak.contents.NumpyArray( + np.array([0.0, 1.1, 2.2]), parameters={"which": "inner1"} + ) ), ak.contents.ByteMaskedArray( ak.index.Index8( diff --git a/tests/test_1607_no_reducers_on_records.py b/tests/test_1607_no_reducers_on_records.py index ef985394dd..76c56debd5 100644 --- a/tests/test_1607_no_reducers_on_records.py +++ b/tests/test_1607_no_reducers_on_records.py @@ -57,11 +57,11 @@ def test_reducers(): def test_overloaded_reducers(): - def overload_add(array, axis=-1): + def overload_add(array, mask): return ak.contents.RecordArray( [ - ak.contents.NumpyArray(np.asarray([ak.sum(array["rho"], axis=axis)])), - ak.contents.NumpyArray(np.asarray([ak.sum(array["phi"], axis=axis)])), + ak.sum(array["rho"], axis=-1, mask_identity=False, highlevel=False), + ak.sum(array["phi"], axis=-1, mask_identity=False, highlevel=False), ], ["rho", "phi"], ) @@ -75,15 +75,17 @@ def overload_add(array, axis=-1): behavior=behavior, ) - with pytest.raises(NotImplementedError): - assert ak.to_list(ak.sum(array, axis=1)) == [{"rho": 0, "phi": 0}] + assert ak.to_list(ak.sum(array, axis=1)) == [{"rho": 0, "phi": 0}] - with pytest.raises(TypeError): + with pytest.raises( + TypeError, match=r"overloads for custom types: VectorArray2D, int" + ): ak.to_list(array + 1) - def overload_add2(array): + def overload_add2(array, mask): return ak.contents.RecordArray( - [ak.contents.NumpyArray(np.asarray([2.4, 3, 4.5, 6]))], ["rho"] + [ak.contents.NumpyArray(np.asarray([2.4, 3, 4.5, 6], dtype=np.float64))], + ["rho"], ) behavior = {} @@ -95,8 +97,7 @@ def overload_add2(array): behavior=behavior, ) - with pytest.raises(NotImplementedError): - assert ak.to_list(ak.sum(array, axis=1)) == [{"rho": 2.4}] + assert ak.to_list(ak.sum(array, axis=1)) == [{"rho": 2.4}] array = ak.highlevel.Array( ak.contents.ByteMaskedArray( @@ -115,5 +116,30 @@ def overload_add2(array): ) ) - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=r"overloads for custom types: a, b"): ak.to_list(ak.sum(array, axis=0)) + + def overload_argmax(array, mask): + return ak.argmax(array["rho"], axis=-1, mask_identity=False, highlevel=False) + + behavior = {} + behavior[ak.argmax, "VectorArray2D"] = overload_argmax + + array = ak.Array( + [ + [ + {"rho": -1.1, "phi": -0.1}, + {"rho": 1.1, "phi": 0.1}, + {"rho": -1.1, "phi": 0.3}, + ], + [ + {"rho": 1.1, "phi": 0.1}, + {"rho": -1.1, "phi": 0.3}, + {"rho": -1.1, "phi": -0.1}, + ], + ], + with_name="VectorArray2D", + behavior=behavior, + ) + + assert ak.to_list(ak.argmax(array, axis=1)) == [1, 0] diff --git a/tests/test_1928_replace_simplify_method_with_classmethod_constructor.py b/tests/test_1928_replace_simplify_method_with_classmethod_constructor.py index 40d25723a4..b1d36d4a89 100644 --- a/tests/test_1928_replace_simplify_method_with_classmethod_constructor.py +++ b/tests/test_1928_replace_simplify_method_with_classmethod_constructor.py @@ -1,6 +1,7 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE import numpy as np +import pytest import awkward as ak @@ -40,7 +41,21 @@ def test_indexedoption_of_union(): def test_indexedoption_of_union_of_option_1(): - unionarray = ak.contents.UnionArray( + with pytest.raises( + TypeError, match=r" must either be comprised of entirely optional contents" + ): + ak.contents.UnionArray( + ak.index.Index8(np.array([0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1], dtype=np.int8)), + ak.index.Index64( + np.array([0, 1, 0, 2, 1, 2, 3, 3, 4, 5, 4], dtype=np.int64) + ), + [ + ak.from_iter([0.0, 1.1, 2.2, 3.3, None, 5.5], highlevel=False), + ak.from_iter(["zero", "one", "two", "three", "four"], highlevel=False), + ], + ) + + unionarray = ak.contents.UnionArray.simplified( ak.index.Index8(np.array([0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1], dtype=np.int8)), ak.index.Index64(np.array([0, 1, 0, 2, 1, 2, 3, 3, 4, 5, 4], dtype=np.int64)), [ @@ -66,7 +81,21 @@ def test_indexedoption_of_union_of_option_1(): def test_indexedoption_of_union_of_option_2(): - unionarray = ak.contents.UnionArray( + with pytest.raises( + TypeError, match=r"must either be comprised of entirely optional contents" + ): + ak.contents.UnionArray( + ak.index.Index8(np.array([0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1], dtype=np.int8)), + ak.index.Index64( + np.array([0, 1, 0, 2, 1, 2, 3, 3, 4, 5, 4], dtype=np.int64) + ), + [ + ak.from_iter([0.0, 1.1, 2.2, 3.3, 4.4, 5.5], highlevel=False), + ak.from_iter(["zero", None, "two", "three", "four"], highlevel=False), + ], + ) + + unionarray = ak.contents.UnionArray.simplified( ak.index.Index8(np.array([0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1], dtype=np.int8)), ak.index.Index64(np.array([0, 1, 0, 2, 1, 2, 3, 3, 4, 5, 4], dtype=np.int64)), [ diff --git a/tests/test_2027_add_data_touch_reporting_to_TypeTracerArray.py b/tests/test_2027_add_data_touch_reporting_to_TypeTracerArray.py index dc566d3bfe..eb2daa0ad6 100644 --- a/tests/test_2027_add_data_touch_reporting_to_TypeTracerArray.py +++ b/tests/test_2027_add_data_touch_reporting_to_TypeTracerArray.py @@ -5,7 +5,7 @@ import numpy as np import awkward as ak -from awkward._nplikes.typetracer import typetracer_with_report +from awkward.typetracer import typetracer_with_report def test_prototypical_example(): diff --git a/tests/test_2085_empty_if_typetracer.py b/tests/test_2085_empty_if_typetracer.py new file mode 100644 index 0000000000..a17d205eb2 --- /dev/null +++ b/tests/test_2085_empty_if_typetracer.py @@ -0,0 +1,59 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import numpy as np +import pytest + +import awkward as ak +from awkward.typetracer import ( + length_one_if_typetracer, + length_zero_if_typetracer, + typetracer_with_report, +) + + +@pytest.mark.parametrize( + "function", [length_zero_if_typetracer, length_one_if_typetracer] +) +def test_typetracer(function): + def func(array): + assert ak.backend(array) == "typetracer" + + radius = np.sqrt(array.x**2 + array.y**2) + radius = function(radius) + assert ak.backend(radius) == "cpu" + if function is length_zero_if_typetracer: + assert len(radius) == 0 + else: + assert len(radius) == 1 + + hist_contents, hist_edges = np.histogram(ak.flatten(radius, axis=None)) + + return hist_contents + + array = ak.zip( + { + "x": [[0.2, 0.3, 0.4], [1, 2, 3], [1, 1, 2]], + "y": [[0.1, 0.1, 0.2], [3, 1, 2], [2, 1, 2]], + "z": [[0.1, 0.1, 0.2], [3, 1, 2], [2, 1, 2]], + } + ) + layout = ak.to_layout(array) + form = layout.form_with_key("node{id}") + + meta, report = typetracer_with_report(form) + meta = ak.Array(meta) + + func(meta) + assert report.data_touched == ["node0", "node2", "node3"] + + +@pytest.mark.parametrize("regulararray", [False, True]) +def test_multiplier(regulararray): + a = np.arange(2 * 3 * 5, dtype=np.int64).reshape(2, 3, 5) + + b = ak.from_numpy(a, regulararray=regulararray) + assert str(b.type) == "2 * 3 * 5 * int64" + + c = b.layout.form.length_one_array() + assert str(c.type) == "1 * 3 * 5 * int64" + assert c.tolist() == [[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]] diff --git a/tests/test_2198_almost_equal.py b/tests/test_2198_almost_equal.py index 7959cf6bde..e32a5e2eef 100644 --- a/tests/test_2198_almost_equal.py +++ b/tests/test_2198_almost_equal.py @@ -149,3 +149,19 @@ def test_typetracer(): array = ak.Array([[[1, 2, 3]], [[5, 4]]], backend="typetracer") with pytest.raises(NotImplementedError): ak.almost_equal(array, 2 * array) + + +def test_indexed(): + assert ak.almost_equal( + ak.contents.ListOffsetArray( + ak.index.Index64([0, 2, 4, 8]), + ak.contents.IndexedArray( + ak.index.Index64([0, 1, 2, 3, 2, 1, 0, 5]), + ak.contents.NumpyArray(np.arange(6, dtype=np.int64)), + ), + ), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 2, 4, 8]), + ak.contents.NumpyArray(np.array([0, 1, 2, 3, 2, 1, 0, 5], dtype=np.int64)), + ), + ) diff --git a/tests/test_2236_merge_union_of_records_option.py b/tests/test_2236_merge_union_of_records_option.py index 3ae0d34fac..a3e5b17bfb 100644 --- a/tests/test_2236_merge_union_of_records_option.py +++ b/tests/test_2236_merge_union_of_records_option.py @@ -58,9 +58,11 @@ def test_option(): assert z.type == ak.types.ArrayType( ak.types.UnionType( [ - ak.types.RecordType( - [ak.types.NumpyType("int64"), ak.types.NumpyType("int64")], - ["a", "b"], + ak.types.OptionType( + ak.types.RecordType( + [ak.types.NumpyType("int64"), ak.types.NumpyType("int64")], + ["a", "b"], + ) ), ak.types.OptionType( ak.types.RecordType( @@ -104,9 +106,11 @@ def test_option_unmasked(): assert z.type == ak.types.ArrayType( ak.types.UnionType( [ - ak.types.RecordType( - [ak.types.NumpyType("int64"), ak.types.NumpyType("int64")], - ["a", "b"], + ak.types.OptionType( + ak.types.RecordType( + [ak.types.NumpyType("int64"), ak.types.NumpyType("int64")], + ["a", "b"], + ) ), ak.types.OptionType( ak.types.RecordType( diff --git a/tests/test_2296_duplicate_field.py b/tests/test_2296_duplicate_field.py new file mode 100644 index 0000000000..4c8bdc0cb4 --- /dev/null +++ b/tests/test_2296_duplicate_field.py @@ -0,0 +1,29 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import re + +import pytest # noqa: F401 + +import awkward as ak + + +def test_invalid(): + layout = ak.contents.RecordArray( + [ + ak.contents.NumpyArray([1, 2, 3]), + ak.contents.NumpyArray([1, 2, 3]), + ], + ["x", "x"], + ) + assert re.match(r".*duplicate field 'x'.*", ak.validity_error(layout)) is not None + + +def test_valid(): + layout = ak.contents.RecordArray( + [ + ak.contents.NumpyArray([1, 2, 3]), + ak.contents.NumpyArray([1, 2, 3]), + ], + ["x", "y"], + ) + assert re.match(r".*duplicate field 'x'.*", ak.validity_error(layout)) is None diff --git a/tests/test_2364_empty_list_of_string.py b/tests/test_2364_empty_list_of_string.py new file mode 100644 index 0000000000..c72c8b118b --- /dev/null +++ b/tests/test_2364_empty_list_of_string.py @@ -0,0 +1,33 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import numpy as np + +import awkward as ak + + +def test_non_empty_string(): + array = ak.Array(["this", "that", "foo", "bar"]) + result = ak.to_numpy(array) + assert result.dtype == np.dtype("U4") + assert result.tolist() == array.tolist() + + +def test_non_empty_bytestring(): + array = ak.Array([b"this", b"that", b"foo", b"bar"]) + result = ak.to_numpy(array) + assert result.dtype == np.dtype("S4") + assert result.tolist() == array.tolist() + + +def test_empty_string(): + array = ak.Array(["this", "that", "foo", "bar"]) + result = ak.to_numpy(array[:0]) + assert result.dtype == np.dtype("U1") + assert result.tolist() == [] + + +def test_empty_bytestring(): + array = ak.Array([b"this", b"that", b"foo", b"bar"]) + result = ak.to_numpy(array[:0]) + assert result.dtype == np.dtype("S1") + assert result.tolist() == [] diff --git a/tests/test_2365_enforce_type.py b/tests/test_2365_enforce_type.py new file mode 100644 index 0000000000..91e4d15b65 --- /dev/null +++ b/tests/test_2365_enforce_type.py @@ -0,0 +1,1075 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import numpy +import pytest + +import awkward as ak + + +def test_record(): + ## record → record + result = ak.enforce_type( + ak.to_layout([{"x": [1, 2]}], regulararray=False), + ak.types.from_datashape("{x: var * int64}", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.RecordArray( + [ + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 2], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 2], dtype=numpy.int64)), + ) + ], + ["x"], + ) + ) + + ## record → record + result = ak.enforce_type( + ak.to_layout([{"x": [1, 0]}], regulararray=False), + ak.types.from_datashape("{x: var * bool}", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.RecordArray( + [ + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 2], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 0], dtype=numpy.bool_)), + ) + ], + ["x"], + ) + ) + + ## record → different tuple + with pytest.raises(ValueError, match=r"converted between records and tuples"): + ak.enforce_type( + ak.to_layout([{"x": [1, 2]}], regulararray=False), + ak.types.from_datashape("(var * float64)", highlevel=False), + ) + + with pytest.raises( + TypeError, match=r"can only add new fields to a record if they are option types" + ): + ak.enforce_type( + ak.to_layout([{"x": [1, 2]}], regulararray=False), + ak.types.from_datashape("{y: var * float64}", highlevel=False), + ) + + ## record → totally different record + result = ak.enforce_type( + ak.to_layout([{"x": [1, 2]}], regulararray=False), + ak.types.from_datashape("{y: ?var * float64}", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.RecordArray( + [ + ak.contents.IndexedOptionArray( + ak.index.Index64([-1]), + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([], dtype=numpy.float64)), + ), + ) + ], + ["y"], + ) + ) + ## record → extended record + result = ak.enforce_type( + ak.to_layout([{"x": [1, 2]}], regulararray=False), + ak.types.from_datashape("{x: var * int64, y: ?int64}", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.RecordArray( + [ + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 2], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 2], dtype=numpy.int64)), + ), + ak.contents.IndexedOptionArray( + ak.index.Index64([-1]), + ak.contents.NumpyArray(numpy.array([], dtype=numpy.int64)), + ), + ], + ["x", "y"], + ), + ) + ## record → empty record + result = ak.enforce_type( + ak.to_layout([{"x": [1, 2]}], regulararray=False), + ak.types.from_datashape("{}", highlevel=False), + ) + assert result.layout.is_equal_to(ak.contents.RecordArray([], [], length=1)) + + ############ + + ## tuple → tuple + result = ak.enforce_type( + ak.to_layout([([1, 2],)], regulararray=False), + ak.types.from_datashape("(var * int64)", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.RecordArray( + [ + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 2], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 2], dtype=numpy.int64)), + ) + ], + None, + ) + ) + + ## tuple → tuple + result = ak.enforce_type( + ak.to_layout([([1, 0],)], regulararray=False), + ak.types.from_datashape("(var * bool)", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.RecordArray( + [ + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 2], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 0], dtype=numpy.bool_)), + ) + ], + None, + ) + ) + + ## tuple → different record + with pytest.raises(ValueError, match=r"converted between records and tuples"): + ak.enforce_type( + ak.to_layout([([1, 2],)], regulararray=False), + ak.types.from_datashape("{x: var * float64}", highlevel=False), + ) + + with pytest.raises( + TypeError, match=r"can only add new slots to a tuple if they are option types" + ): + ak.enforce_type( + ak.to_layout([([1, 2],)], regulararray=False), + ak.types.from_datashape("(var * int64, float32)", highlevel=False), + ) + + ## tuple → extended tuple + result = ak.enforce_type( + ak.to_layout([([1, 2],)], regulararray=False), + ak.types.from_datashape("(var * int64, ?float32)", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.RecordArray( + [ + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 2], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 2], dtype=numpy.int64)), + ), + ak.contents.IndexedOptionArray( + ak.index.Index64([-1]), + ak.contents.NumpyArray(numpy.array([], dtype=numpy.float32)), + ), + ], + None, + ) + ) + ## tuple → empty tuple + result = ak.enforce_type( + ak.to_layout([([1, 2],)], regulararray=False), + ak.types.from_datashape("()", highlevel=False), + ) + assert result.layout.is_equal_to(ak.contents.RecordArray([], None, length=1)) + + +def test_list(): + # + # List types + result = ak.enforce_type( + ak.to_layout([[1, 2, 3]]), + ak.types.from_datashape("var * int64", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 3], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 2, 3], dtype=numpy.int64)), + ), + ) + result = ak.enforce_type( + ak.to_layout([[1, 2, 3]]), ak.types.from_datashape("3 * int64", highlevel=False) + ) + assert result.layout.is_equal_to( + ak.contents.RegularArray( + ak.contents.NumpyArray(numpy.array([1, 2, 3], dtype=numpy.int64)), size=3 + ), + ) + ## Empty list to regular shape + result = ak.enforce_type( + ak.to_layout([[]])[:0], ak.types.from_datashape("3 * int64", highlevel=False) + ) + assert result.layout.is_equal_to( + ak.contents.RegularArray( + ak.contents.NumpyArray(numpy.array([], dtype=numpy.int64)), size=3 + ), + ) + with pytest.raises(ValueError, match=r"converted .* different size"): + ak.enforce_type( + ak.to_layout([[1, 2, 3]]), + ak.types.from_datashape("4 * int64", highlevel=False), + ) + + # Regular types + result = ak.enforce_type( + ak.to_regular([[1, 2, 3]], axis=-1, highlevel=False), + ak.types.from_datashape("var * int64", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 3], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 2, 3], dtype=numpy.int64)), + ), + ) + result = ak.enforce_type( + ak.to_regular([[1, 2, 3]], axis=-1, highlevel=False), + ak.types.from_datashape("3 * int64", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.RegularArray( + ak.contents.NumpyArray(numpy.array([1, 2, 3], dtype=numpy.int64)), size=3 + ), + ) + with pytest.raises(ValueError, match=r"different size"): + ak.enforce_type( + ak.to_regular([[1, 2, 3]], axis=-1, highlevel=False), + ak.types.from_datashape("4 * int64", highlevel=False), + ) + + +def test_option(): + # Options + ## option → option + result = ak.enforce_type( + ak.to_layout([1, None]), + ak.types.from_datashape("?int64", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.IndexedOptionArray( + ak.index.Index(numpy.array([0, -1], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1], dtype=numpy.int64)), + ), + ) + ## option → option (packing) + result = ak.enforce_type( + ak.to_layout([1, None, 2, 3]), + ak.types.from_datashape("?float64", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.IndexedOptionArray( + ak.index.Index(numpy.array([0, -1, 1, 2], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 2, 3], dtype=numpy.float64)), + ), + ) + + ## option → no option + result = ak.enforce_type( + ak.to_layout([1, None])[:1], + ak.types.from_datashape("int64", highlevel=False), + ) + assert ak.almost_equal( + result, ak.contents.NumpyArray(numpy.array([1], dtype=numpy.int64)) + ) + + with pytest.raises(ValueError, match=r"if there are no missing values"): + ak.enforce_type( + ak.to_layout([1, None]), + ak.types.from_datashape("int64", highlevel=False), + ) + + ## Add option + result = ak.enforce_type( + ak.to_layout([1, 2]), + ak.types.from_datashape("?int64", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.UnmaskedArray( + ak.contents.NumpyArray(numpy.array([1, 2], dtype=numpy.int64)) + ), + ) + + ## option[X] → option[unknown] + layout = ak.to_layout([None, 1, 2, 3]) + result = ak.enforce_type(layout, "?unknown") + assert result.layout.is_equal_to( + ak.contents.IndexedOptionArray( + ak.index.Index64([-1, -1, -1, -1]), ak.contents.EmptyArray() + ) + ) + + +def test_numpy(): + ## NumPy + ## 1D → 1D + result = ak.enforce_type( + ak.to_layout([1, 2]), + ak.types.from_datashape("int64", highlevel=False), + ) + assert ak.almost_equal(result, numpy.array([1, 2], dtype=numpy.int64)) + + result = ak.enforce_type( + ak.to_layout([1, 2]), + ak.types.from_datashape("float32", highlevel=False), + ) + assert ak.almost_equal(result, numpy.array([1.0, 2.0], dtype=numpy.float32)) + + with pytest.raises(TypeError): + ak.enforce_type( + ak.to_layout([1, 2]), + ak.types.from_datashape("string", highlevel=False), + ) + + ## 1D → 2D + with pytest.raises(TypeError): + ak.enforce_type( + ak.to_layout([1, 2]), + ak.types.from_datashape("var * int64", highlevel=False), + ) + with pytest.raises(TypeError): + ak.enforce_type( + ak.to_layout([1, 2]), + ak.types.from_datashape("2 * float32", highlevel=False), + ) + ## 2D → 1D + with pytest.raises(TypeError): + ak.enforce_type( + ak.to_layout(numpy.zeros((2, 3)), regulararray=False), + ak.types.from_datashape("int64", highlevel=False), + ) + with pytest.raises(TypeError): + ak.enforce_type( + ak.to_layout(numpy.zeros((2, 3)), regulararray=False), + ak.types.from_datashape("float32", highlevel=False), + ) + + ## 2D → 2D + result = ak.enforce_type( + ak.to_layout(numpy.zeros((2, 3)), regulararray=False), + ak.types.from_datashape("var * int64", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 3, 6], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([0, 0, 0, 0, 0, 0], dtype=numpy.int64)), + ), + ) + + result = ak.enforce_type( + ak.to_layout(numpy.zeros((2, 3)), regulararray=False), + ak.types.from_datashape("3 * float32", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.RegularArray( + ak.contents.NumpyArray( + numpy.array([0, 0, 0, 0, 0, 0], dtype=numpy.float32) + ), + size=3, + ), + ) + + +def test_union(): + # Unions + + ## non union → union + result = ak.enforce_type( + ak.to_layout([1, 2]), + ak.types.from_datashape("union[int64, string]", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.UnionArray( + tags=ak.index.Index8([0, 0]), + index=ak.index.Index64([0, 1]), + contents=[ + ak.contents.NumpyArray(numpy.array([1, 2], dtype=numpy.int64)), + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0]), + content=ak.contents.NumpyArray( + numpy.array([], dtype=numpy.uint8), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string"}, + ), + ], + ) + ) + + with pytest.raises(TypeError): + ak.enforce_type( + ak.to_layout([1, 2]), + ak.types.from_datashape("union[var * int64, string]", highlevel=False), + ) + + ## union → no union (project) + result = ak.enforce_type( + # Build union layout, slice to test projection + ak.to_layout([1, "hi", "bye"])[1:2], + ak.types.from_datashape("string", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.IndexedArray( + ak.index.Index64([0]), + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 2, 5]), + content=ak.contents.NumpyArray( + numpy.array([104, 105, 98, 121, 101], dtype=numpy.uint8), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string"}, + ), + ) + ) + result = ak.enforce_type( + # Build union layout, slice to test projection + ak.to_layout([1, "hi", "bye"])[:1], + ak.types.from_datashape("int64", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.IndexedArray( + ak.index.Index64([0]), + ak.contents.NumpyArray(numpy.array([1], dtype=numpy.int64)), + ) + ) + + with pytest.raises(TypeError): + ak.enforce_type( + ak.to_layout([1, "hi"]), + ak.types.from_datashape("var * int64", highlevel=False), + ) + + ## union → no union (convert) + array = ak.concatenate( + [ + # {x: int64, y: float64} + [{"x": 1, "y": 2.0}], + # {y: int64} + [{"y": 3}], + # {x: int64, y: float64} + [{"x": 4, "y": 5.0}], + # {y: int64} + [{"y": 6}], + ], + ) + assert array.type == ak.types.ArrayType( + ak.types.UnionType( + [ + ak.types.RecordType( + [ak.types.NumpyType("int64"), ak.types.NumpyType("float64")], + ["x", "y"], + ), + ak.types.RecordType([ak.types.NumpyType("int64")], ["y"]), + ] + ), + 4, + ) + result = ak.enforce_type( + array, ak.types.from_datashape("{y: int64}", highlevel=False) + ) + assert result.layout.is_equal_to( + ak.contents.IndexedArray( + index=ak.index.Index64([0, 2, 1, 3]), + content=ak.contents.RecordArray( + contents=[ + ak.contents.NumpyArray( + numpy.array([2, 5, 3, 6], dtype=numpy.int64), + ) + ], + fields=["y"], + ), + ) + ) + with pytest.raises(ValueError): + ak.enforce_type( + ak.to_layout([1, "hi"]), ak.types.from_datashape("string", highlevel=False) + ) + + ## union → same union + result = ak.enforce_type( + ak.to_layout([1, "hi"]), + ak.types.UnionType( + [ + ak.types.NumpyType("int64"), + ak.types.ListType( + ak.types.NumpyType( + "uint8", parameters={"__array__": "char"}, typestr="char" + ), + parameters={"__array__": "string", "foo": "bar"}, + typestr="string", + ), + ] + ), + ) + assert result.layout.is_equal_to( + ak.contents.UnionArray( + tags=ak.index.Index8([0, 1]), + index=ak.index.Index64([0, 0]), + contents=[ + ak.contents.NumpyArray(numpy.array([1], dtype=numpy.int64)), + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 2]), + content=ak.contents.NumpyArray( + numpy.array([104, 105], dtype=numpy.uint8), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string", "foo": "bar"}, + ), + ], + ) + ) + + ## union → bigger union + result = ak.enforce_type( + ak.to_layout([1, "hi"]), + ak.types.from_datashape("union[int64, string, datetime64]", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.UnionArray( + tags=ak.index.Index8([0, 1]), + index=ak.index.Index64([0, 0]), + contents=[ + ak.contents.NumpyArray(numpy.array([1], dtype=numpy.int64)), + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 2]), + content=ak.contents.NumpyArray( + numpy.array([104, 105], dtype=numpy.uint8), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string"}, + ), + ak.contents.NumpyArray(numpy.array([], dtype=numpy.datetime64)), + ], + ) + ) + + ## union → different union (same N) + result = ak.enforce_type( + ak.to_layout([1, "hi"]), + ak.types.UnionType( + [ + ak.types.NumpyType("float32"), + ak.types.ListType( + ak.types.NumpyType( + "uint8", parameters={"__array__": "char"}, typestr="char" + ), + parameters={"__array__": "string", "foo": "bar"}, + typestr="string", + ), + ] + ), + ) + assert result.layout.is_equal_to( + ak.contents.UnionArray( + tags=ak.index.Index8([0, 1]), + index=ak.index.Index64([0, 0]), + contents=[ + ak.contents.NumpyArray(numpy.array([1], dtype=numpy.float32)), + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 2]), + content=ak.contents.NumpyArray( + numpy.array([104, 105], dtype=numpy.uint8), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string", "foo": "bar"}, + ), + ], + ) + ) + + ## union → different union (smaller N) + result = ak.enforce_type( + ak.to_layout([1, "hi", [1j, 2j]])[:2], + "union[int64, string]", + ) + assert result.layout.is_equal_to( + ak.contents.UnionArray( + tags=ak.index.Index8([0, 1]), + index=ak.index.Index64([0, 0]), + contents=[ + ak.contents.NumpyArray(numpy.array([1], dtype=numpy.int64)), + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 2]), + content=ak.contents.NumpyArray( + numpy.array([104, 105], dtype=numpy.uint8), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string"}, + ), + ], + ) + ) + + ## union → incompatible different union (same N) + with pytest.raises(TypeError): + ak.enforce_type( + ak.to_layout([1, "hi"]), + ak.types.from_datashape("union[int64, bool]", highlevel=False), + ) + + ## union → different union (same N, more than one change) + with pytest.raises(TypeError): + ak.enforce_type( + ak.to_layout([1, "hi", False]), + ak.types.from_datashape( + "union[datetime64, string, float32]", highlevel=False + ), + ) + + ## union of union → union of extended union + layout = ak.contents.UnionArray( + ak.index.Index8([0, 1]), + ak.index.Index64([0, 0]), + [ + ak.contents.NumpyArray(numpy.array([1], dtype=numpy.int64)), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 2]), + ak.contents.UnionArray( + ak.index.Index8([0, 1]), + ak.index.Index64([0, 0]), + [ + ak.contents.NumpyArray(numpy.array([2], dtype=numpy.int64)), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 2]), + ak.contents.RecordArray( + [ + ak.contents.IndexedOptionArray( + ak.index.Index64([0, -1]), + ak.contents.NumpyArray( + numpy.array([1], dtype=numpy.int64) + ), + ), + ak.contents.IndexedOptionArray( + ak.index.Index64([-1, 0]), + ak.contents.NumpyArray( + numpy.array([2], dtype=numpy.int64) + ), + ), + ], + ["x", "y"], + ), + ), + ], + ), + ), + ], + ) + result = ak.enforce_type( + layout, + """ + union[ + int64, + var * union[ + int64, + var * { + x: ?int64, + y: ?int64, + z: ?string + } + ] + ] + """, + ) + assert result.layout.is_equal_to( + ak.contents.UnionArray( + ak.index.Index8([0, 1]), + ak.index.Index64([0, 0]), + [ + ak.contents.NumpyArray(numpy.array([1], dtype=numpy.int64)), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 2]), + ak.contents.UnionArray( + ak.index.Index8([0, 1]), + ak.index.Index64([0, 0]), + [ + ak.contents.NumpyArray(numpy.array([2], dtype=numpy.int64)), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 2]), + ak.contents.RecordArray( + [ + ak.contents.IndexedOptionArray( + ak.index.Index64([0, -1]), + ak.contents.NumpyArray( + numpy.array([1], dtype=numpy.int64) + ), + ), + ak.contents.IndexedOptionArray( + ak.index.Index64([-1, 0]), + ak.contents.NumpyArray( + numpy.array([2], dtype=numpy.int64) + ), + ), + ak.contents.IndexedOptionArray( + ak.index.Index64([-1, -1]), + ak.contents.ListOffsetArray( + ak.index.Index64([0]), + ak.contents.NumpyArray( + numpy.empty(0, dtype=numpy.uint8), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string"}, + ), + ), + ], + ["x", "y", "z"], + ), + ), + ], + ), + ), + ], + ) + ) + + +def test_string(): + ## string -> bytestring + result = ak.enforce_type( + ak.to_layout(["hello world"]), + ak.types.from_datashape("bytes", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 11]), + content=ak.contents.NumpyArray( + numpy.array( + [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], + dtype=numpy.uint8, + ), + parameters={"__array__": "byte"}, + ), + parameters={"__array__": "bytestring"}, + ), + ) + + ## bytestring -> string + result = ak.enforce_type( + ak.to_layout([b"hello world"]), + ak.types.from_datashape("string", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 11]), + content=ak.contents.NumpyArray( + numpy.array( + [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], + dtype=numpy.uint8, + ), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string"}, + ), + ) + + ## string -> string + result = ak.enforce_type( + ak.to_layout(["hello world"]), + ak.types.from_datashape("string", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 11]), + content=ak.contents.NumpyArray( + numpy.array( + [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], + dtype=numpy.uint8, + ), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string"}, + ), + ) + + ## bytestring -> bytestring + result = ak.enforce_type( + ak.to_layout([b"hello world"]), + ak.types.from_datashape("bytes", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 11]), + content=ak.contents.NumpyArray( + numpy.array( + [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], + dtype=numpy.uint8, + ), + parameters={"__array__": "byte"}, + ), + parameters={"__array__": "bytestring"}, + ), + ) + + ## bytestring -> list of byte + result = ak.enforce_type( + ak.to_layout([b"hello world"]), + ak.types.from_datashape("var * byte", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 11]), + content=ak.contents.NumpyArray( + numpy.array( + [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], + dtype=numpy.uint8, + ), + parameters={"__array__": "byte"}, + ), + ), + ) + + ## bytestring -> list of int64 + result = ak.enforce_type( + ak.to_layout([b"hello world"]), + ak.types.from_datashape("var * int64", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 11]), + content=ak.contents.NumpyArray( + numpy.array( + [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], + dtype=numpy.int64, + ) + ), + ), + ) + + ## list of int64 -> string + result = ak.enforce_type( + ak.without_parameters([b"hello world"]), + ak.types.from_datashape("string", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 11]), + content=ak.contents.NumpyArray( + numpy.array( + [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100], + dtype=numpy.uint8, + ), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string"}, + ), + ) + + +def test_highlevel(): + with pytest.raises(TypeError, match=r"High-level type objects are not supported"): + ak.enforce_type( + ak.to_layout(["hello world"]), + ak.types.from_datashape("1 * bytes"), + ) + with pytest.raises(TypeError, match=r"High-level type objects are not supported"): + ak.enforce_type( + ak.to_layout([{"msg": "hello world"}]), + ak.types.ScalarType( + ak.types.RecordType( + [ + ak.types.ListType( + ak.types.NumpyType( + "uint8", parameters={"__array__": "char"} + ), + parameters={"__array__": "string"}, + ) + ], + ["msg"], + ) + ), + ) + + +def test_single_record(): + result = ak.enforce_type( + ak.Record({"x": [1, 2]}), + ak.types.from_datashape("{x: var * float64}", highlevel=False), + highlevel=False, + ) + assert isinstance(result, ak.record.Record) + assert ak.almost_equal( + result.array, + ak.contents.RecordArray( + [ + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 2], dtype=numpy.int64)), + ak.contents.NumpyArray(numpy.array([1, 2], dtype=numpy.float64)), + ) + ], + ["x"], + ), + ) + + +def test_indexed(): + # Non-packing (because dtype hasn't changed) + result = ak.enforce_type( + ak.contents.IndexedArray( + ak.index.Index64([0, 2]), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 3, 6, 9]), + ak.contents.NumpyArray(numpy.arange(9, dtype=numpy.int64)), + ), + ), + ak.types.from_datashape( + 'var * int64[parameters={"key": "value"}]', highlevel=False + ), + ) + assert result.layout.is_equal_to( + ak.contents.IndexedArray( + ak.index.Index64([0, 2]), + ak.contents.ListOffsetArray( + ak.index.Index(numpy.array([0, 3, 6, 9], dtype=numpy.int64)), + ak.contents.NumpyArray( + numpy.array([0, 1, 2, 3, 4, 5, 6, 7, 8], dtype=numpy.int64), + parameters={"key": "value"}, + ), + ), + ) + ) + # Packing + result = ak.enforce_type( + ak.contents.IndexedArray( + ak.index.Index64([0, 2]), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 3, 6, 9]), + ak.contents.NumpyArray(numpy.arange(9, dtype=numpy.int64)), + ), + ), + ak.types.from_datashape("var * float32", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.ListOffsetArray( + ak.index.Index64([0, 3, 6]), + ak.contents.NumpyArray( + numpy.array([0, 1, 2, 6, 7, 8], dtype=numpy.float32) + ), + ) + ) + + +def test_unknown(): + # unknown → unknown + layout = ak.contents.EmptyArray() + assert ak.enforce_type(layout, "unknown").layout.is_equal_to(layout) + + # unknown → other + layout = ak.contents.EmptyArray() + assert ak.enforce_type(layout, "int64").layout.is_equal_to( + ak.contents.NumpyArray(numpy.empty(0, numpy.int64)) + ) + + # other → unknown + with pytest.raises( + TypeError, match=r"cannot convert non-EmptyArray layouts to a bare UnknownType" + ): + layout = ak.contents.NumpyArray(numpy.empty(0, numpy.int64)) + ak.enforce_type(layout, "unknown") + + # unknown → other + layout = ak.contents.NumpyArray(numpy.empty(0, numpy.int64)) + assert ak.enforce_type(layout, "?unknown").layout.is_equal_to( + ak.contents.IndexedOptionArray(ak.index.Index64([]), ak.contents.EmptyArray()) + ) + + +def test_misc(): + # These tests ensure good coverage over our helper functions + ## option → option (inside indexed) + layout = ak.to_layout([{"x": [1, 2, None]}, None, {"x": [3, 4, None]}])[[0, 2], :2] + result = ak.enforce_type( + layout, + """ + ?{ + x: var * ?float32 + } + """, + ) + assert result.layout.is_equal_to( + ak.contents.IndexedOptionArray( + ak.index.Index64([0, 1]), + ak.contents.RecordArray( + [ + ak.contents.ListOffsetArray( + ak.index.Index64([0, 2, 4]), + ak.contents.IndexedOptionArray( + ak.index.Index64([0, 1, 2, 3]), + ak.contents.NumpyArray( + numpy.array([1, 2, 3, 4], dtype=numpy.float32) + ), + ), + ) + ], + ["x"], + ), + ) + ) + ## no option → option (inside indexed) + layout = ak.to_layout( + [ + {"x": [1, 2, None]}, + {"x": [9, 9, None]}, + {"x": [3, 4, None]}, + {"x": [8, 8, None]}, + ] + )[[0, 2], :2] + result = ak.enforce_type( + layout, + """ + ?{ + x: var * ?float32 + } + """, + ) + assert result.layout.is_equal_to( + ak.contents.UnmaskedArray( + ak.contents.RecordArray( + [ + ak.contents.ListOffsetArray( + ak.index.Index64([0, 2, 4]), + ak.contents.IndexedOptionArray( + ak.index.Index64([0, 1, 2, 3]), + ak.contents.NumpyArray( + numpy.array([1, 2, 3, 4], dtype=numpy.float32) + ), + ), + ) + ], + ["x"], + ), + ) + ) + + ## option (indexed) list of union → option list of no union (project) + layout = ak.to_layout([[1, "hi", "bye"], None])[[0, 1], 1:2] + assert isinstance(layout, ak.contents.IndexedOptionArray) + result = ak.enforce_type( + # Build union layout, slice to test projection/no-projection + # wrap union in outer option-of-list, and index it to produce a IndexedOptionArray (to test for packing) + layout, + ak.types.from_datashape("?var * string", highlevel=False), + ) + assert result.layout.is_equal_to( + ak.contents.IndexedOptionArray( + ak.index.Index64([0, -1]), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 1]), + # Indexed type because the string dtype doesn't change, so we don't need to back below this point + ak.contents.IndexedArray( + ak.index.Index64([0]), + ak.contents.ListOffsetArray( + offsets=ak.index.Index64([0, 2, 5]), + content=ak.contents.NumpyArray( + numpy.array([104, 105, 98, 121, 101], dtype=numpy.uint8), + parameters={"__array__": "char"}, + ), + parameters={"__array__": "string"}, + ), + ), + ), + ), + ) diff --git a/tests/test_2373_unzip_touching.py b/tests/test_2373_unzip_touching.py index dc4d12a196..f6eeefc565 100644 --- a/tests/test_2373_unzip_touching.py +++ b/tests/test_2373_unzip_touching.py @@ -116,7 +116,7 @@ def test(): } ) - ttlayout, report = ak._nplikes.typetracer.typetracer_with_report(form) + ttlayout, report = ak.typetracer.typetracer_with_report(form) ttarray = ak.Array(ttlayout) pairs = ak.cartesian([ttarray.muon, ttarray.jet], axis=1, nested=True) diff --git a/tests/test_2374_cartesian_touching.py b/tests/test_2374_cartesian_touching.py index e7357bf637..be7fbeaa08 100644 --- a/tests/test_2374_cartesian_touching.py +++ b/tests/test_2374_cartesian_touching.py @@ -120,7 +120,7 @@ def test(): } ) - ttlayout, report = ak._nplikes.typetracer.typetracer_with_report(form) + ttlayout, report = ak.typetracer.typetracer_with_report(form) ttarray = ak.Array(ttlayout) diff --git a/tests/test_2395_copy_asarray_touch.py b/tests/test_2395_copy_asarray_touch.py index e76554ca68..e06b5d06d3 100644 --- a/tests/test_2395_copy_asarray_touch.py +++ b/tests/test_2395_copy_asarray_touch.py @@ -4,7 +4,8 @@ import pytest # noqa: F401 import awkward as ak -from awkward._nplikes.typetracer import TypeTracer, typetracer_with_report +from awkward._nplikes.typetracer import TypeTracer +from awkward.typetracer import typetracer_with_report typetracer = TypeTracer.instance() diff --git a/tests/test_2410_string_broadcast.py b/tests/test_2410_string_broadcast.py new file mode 100644 index 0000000000..b21da6c8b9 --- /dev/null +++ b/tests/test_2410_string_broadcast.py @@ -0,0 +1,36 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import pytest + +import awkward as ak + + +@pytest.mark.xfail( + reason="reconstructed list should be list of string, not string of string" +) +def test_deep_string_string(): + left, right = ak.broadcast_arrays( + [["x", "yz"], ["hello", "world", "foo", "bar"]], ["x", "y"] + ) + assert right.to_list() == [["x", "x"], ["y", "y", "y", "y"]] + + +@pytest.mark.xfail( + reason="reconstructed list should be list of string, not string of string" +) +def test_deep_numbers_string(): + left, right = ak.broadcast_arrays([[1, 2], [3, 4, 5, 6]], ["x", "y"]) + assert right.to_list() == [["x", "x"], ["y", "y", "y", "y"]] + + +def test_deep_string_numbers(): + left, right = ak.broadcast_arrays( + [["x", "yz"], ["hello", "world", "foo", "bar"]], [1, 2] + ) + assert right.to_list() == [[1, 1], [2, 2, 2, 2]] + + +def test_same_depth(): + left, right = ak.broadcast_arrays(["z"], ["x", "y"]) + assert left.to_list() == ["z", "z"] + assert right.to_list() == ["x", "y"] diff --git a/tests/test_2411_cartesian_axis_validation.py b/tests/test_2411_cartesian_axis_validation.py new file mode 100644 index 0000000000..8e193d997e --- /dev/null +++ b/tests/test_2411_cartesian_axis_validation.py @@ -0,0 +1,28 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import numpy as np +import pytest + +import awkward as ak + + +def test_simple(): + left = ak.Array([1, 2, 3]) + right = ak.Array([["lambda", "sigma", "eta", "phi"], ["delta"]]) + pair = ak.cartesian([left, right], axis=0) + assert pair.ndim == 1 + assert pair.tolist() == [ + (1, ["lambda", "sigma", "eta", "phi"]), + (1, ["delta"]), + (2, ["lambda", "sigma", "eta", "phi"]), + (2, ["delta"]), + (3, ["lambda", "sigma", "eta", "phi"]), + (3, ["delta"]), + ] + + +def test_out_of_bounds(): + left = ak.Array([1, 2, 3]) + right = ak.Array([["lambda", "sigma", "eta", "phi"], ["delta"]]) + with pytest.raises(np.AxisError): + ak.cartesian([left, right], axis=2) diff --git a/tests/test_2417_bytemasked_singletons.py b/tests/test_2417_bytemasked_singletons.py new file mode 100644 index 0000000000..82ce8d494b --- /dev/null +++ b/tests/test_2417_bytemasked_singletons.py @@ -0,0 +1,26 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import pytest # noqa: F401 + +import awkward as ak + + +def test(): + array = ak.Array( + ak.contents.ByteMaskedArray( + mask=ak.index.Index8([1, 1, 0, 0]), + content=ak.contents.NumpyArray([3, 4, 2, 5]), + valid_when=True, + ) + ) + assert ( + ak.singletons(array, highlevel=False).form + == ak.singletons(ak.to_backend(array, "typetracer"), highlevel=False).form + ) + + assert ( + ak.singletons(array, highlevel=False).form + == ak.singletons( + array.layout.to_typetracer(forget_length=True), highlevel=False + ).form + ) diff --git a/tests/test_2418_union_broadcast_unknown.py b/tests/test_2418_union_broadcast_unknown.py new file mode 100644 index 0000000000..365d0f023e --- /dev/null +++ b/tests/test_2418_union_broadcast_unknown.py @@ -0,0 +1,14 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + + +import awkward as ak + + +def test(): + array = ak.Array([1, [2, 3]]) + result = array + array + + array_tt = ak.Array(array.layout.to_typetracer(forget_length=True)) + result_tt = array_tt + array_tt + + assert result_tt.layout.form == result.layout.form diff --git a/tests/test_2424_almost_equal_union_record.py b/tests/test_2424_almost_equal_union_record.py new file mode 100644 index 0000000000..c6d5ed10b1 --- /dev/null +++ b/tests/test_2424_almost_equal_union_record.py @@ -0,0 +1,49 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import numpy as np +import pytest # noqa: F401 + +import awkward as ak + + +def test_records_almost_equal(): + first = ak.contents.RecordArray( + [ + ak.contents.NumpyArray(np.array([1, 2, 3], dtype=np.int64)), + ak.contents.NumpyArray(np.array([0], dtype=np.dtype("0) reduction + # The child option introduces a missing parent: parents become _non-dense_ + # The regular array tests our regular reduction pathway + layout = ak.contents.ListOffsetArray( + ak.index.Index64([0, 3, 4, 6]), + ak.contents.ByteMaskedArray( + ak.index.Index8([1, 1, 1, 0, 1, 1]), + ak.contents.RegularArray( + ak.contents.NumpyArray( + np.array( + [0, 2, 1, 3, 1, 0, 1, 0, 3, 9, 1, 7, 7, 6, 5, 7, 4, 8], + dtype=np.int64, + ) + ), + size=3, + ), + valid_when=True, + ), + ) + result = ak.argmax(layout, axis=1, highlevel=False, mask_identity=False) + assert result.is_equal_to( + ak.contents.RegularArray( + ak.contents.NumpyArray( + np.array([1, 0, 2, -1, -1, -1, 0, 0, 1], dtype=np.int64) + ), + size=3, + ) + ) diff --git a/tests/test_2495_concatenate_typetracer.py b/tests/test_2495_concatenate_typetracer.py new file mode 100644 index 0000000000..679cbc5aca --- /dev/null +++ b/tests/test_2495_concatenate_typetracer.py @@ -0,0 +1,49 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import numpy as np +import pytest # noqa: F401 + +import awkward as ak +from awkward._nplikes.shape import unknown_length + + +def test_mixed_known_lengths(): + first = ak.from_numpy(np.arange(3 * 4).reshape(3, 4), highlevel=False) + first_tt = first.to_typetracer(forget_length=False) + + second = ak.from_numpy(6 - np.arange(3 * 4).reshape(3, 4) * 2, highlevel=False) + second_tt = second.to_typetracer(forget_length=True) + + result_tt = ak.concatenate((first_tt, second_tt), axis=1) + result = ak.concatenate((first, second), axis=1) + + assert result_tt.layout.form == result.layout.form + assert result_tt.layout.length == result.layout.length == 3 + + +def test_known_lengths(): + first = ak.from_numpy(np.arange(3 * 4).reshape(3, 4), highlevel=False) + first_tt = first.to_typetracer(forget_length=False) + + second = ak.from_numpy(6 - np.arange(3 * 4).reshape(3, 4) * 2, highlevel=False) + second_tt = second.to_typetracer(forget_length=False) + + result_tt = ak.concatenate((first_tt, second_tt), axis=1) + result = ak.concatenate((first, second), axis=1) + + assert result_tt.layout.form == result.layout.form + assert result_tt.layout.length == result.layout.length == 3 + + +def test_unknown_lengths(): + first = ak.from_numpy(np.arange(3 * 4).reshape(3, 4), highlevel=False) + first_tt = first.to_typetracer(forget_length=True) + + second = ak.from_numpy(6 - np.arange(3 * 4).reshape(3, 4) * 2, highlevel=False) + second_tt = second.to_typetracer(forget_length=True) + + result_tt = ak.concatenate((first_tt, second_tt), axis=1) + result = ak.concatenate((first, second), axis=1) + + assert result_tt.layout.form == result.layout.form + assert result_tt.layout.length is unknown_length diff --git a/tests/test_2501_positional_record_reducer.py b/tests/test_2501_positional_record_reducer.py new file mode 100644 index 0000000000..33e87c8cb4 --- /dev/null +++ b/tests/test_2501_positional_record_reducer.py @@ -0,0 +1,151 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import pytest + +import awkward as ak + + +def _min_pair(array, mask): + array = ak.typetracer.length_zero_if_typetracer(array) + + # Find location of minimum 0 slot + i_min = ak.argmin(array["0"], axis=-1, keepdims=True, mask_identity=True) + # Index into array + pair_min = ak.ravel(array[ak.from_regular(i_min)], highlevel=False) + if mask: + return pair_min + else: + form = pair_min.content.form + length_one_content = form.length_one_array( + backend=pair_min.backend, highlevel=False + ) + identity_content = ak.fill_none(length_one_content, 0, highlevel=False) + identity = ak.record.Record(identity_content, 0) + return ak.fill_none(pair_min, identity, highlevel=False) + + +def _argmin_pair(array, mask): + array = ak.typetracer.length_zero_if_typetracer(array) + + assert not mask + # Find location of minimum 0 slot + return ak.argmin(array["0"], axis=-1, keepdims=False, mask_identity=mask) + + +def _argmin_pair_bad(array, mask): + array = ak.typetracer.length_zero_if_typetracer(array) + + assert not mask + # Find location of minimum 0 slot + return ak.argmin(array["0"], axis=-1, keepdims=False, mask_identity=True) + + +def test_non_positional(): + behavior = {(ak.min, "pair"): _min_pair} + + x = ak.Array( + [ + [ + [1, 2, 3], + [5, 4, 3], + [2], + ], + [ + [8], + [], + [10, 4, 4], + ], + ] + ) + y = 2 * x - x**2 + z = ak.zip((x, y), with_name="pair", behavior=behavior) + + assert ak.almost_equal( + ak.min(z, axis=-1, mask_identity=True), + ak.Array( + [ + [(1, 1), (3, -3), (2, 0)], + [ + (8, -48), + None, + (4, -8), + ], + ], + with_name="pair", + ), + ) + + assert ak.almost_equal( + ak.min(z, axis=-1, mask_identity=False), + ak.Array( + [ + [(1, 1), (3, -3), (2, 0)], + [ + (8, -48), + (0, 0), + (4, -8), + ], + ], + with_name="pair", + ), + ) + + +def test_positional_bad(): + behavior = {(ak.argmin, "pair"): _argmin_pair_bad} + + x = ak.Array( + [ + [ + [1, 2, 3], + [5, 4, 3], + [2], + ], + [ + [8], + [], + [10, 4, 4], + ], + ] + ) + y = 2 * x - x**2 + z = ak.zip((x, y), with_name="pair", behavior=behavior) + + with pytest.raises(TypeError, match=r"'pair' returned an option"): + assert ak.almost_equal( + ak.argmin(z, axis=-1, mask_identity=True), [[0, 2, 0], [0, None, 1]] + ) + + with pytest.raises(TypeError, match=r"'pair' returned an option"): + assert ak.almost_equal( + ak.argmin(z, axis=-1, mask_identity=False), [[0, 2, 0], [0, -1, 1]] + ) + + +def test_positional_good(): + behavior = {(ak.argmin, "pair"): _argmin_pair} + + x = ak.Array( + [ + [ + [1, 2, 3], + [5, 4, 3], + [2], + ], + [ + [8], + [], + [10, 4, 4], + ], + ] + ) + y = 2 * x - x**2 + z = ak.zip((x, y), with_name="pair", behavior=behavior) + + assert ak.almost_equal( + ak.argmin(z, axis=-1, mask_identity=True), [[0, 2, 0], [0, None, 1]] + ) + + assert ak.almost_equal( + ak.argmin(z, axis=-1, mask_identity=False), [[0, 2, 0], [0, -1, 1]] + ) diff --git a/tests/test_2503_deprecate_to_numpyform.py b/tests/test_2503_deprecate_to_numpyform.py new file mode 100644 index 0000000000..72a5f39ef3 --- /dev/null +++ b/tests/test_2503_deprecate_to_numpyform.py @@ -0,0 +1,22 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import numpy as np +import pytest + +import awkward as ak + + +def test_dtype_deprecated(): + form = ak.forms.EmptyForm() + with pytest.warns( + DeprecationWarning, + match=r"the `dtype` parameter in EmptyForm\.to_NumpyForm is deprecated", + ): + next_form = form.to_NumpyForm(dtype=np.dtype(np.int64)) + assert next_form.primitive == "int64" + + +def test_primitive(): + form = ak.forms.EmptyForm() + next_form = form.to_NumpyForm(primitive="int64") + assert next_form.primitive == "int64" diff --git a/tests/test_2512_record_array_carry.py b/tests/test_2512_record_array_carry.py new file mode 100644 index 0000000000..7612e591b5 --- /dev/null +++ b/tests/test_2512_record_array_carry.py @@ -0,0 +1,160 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import numpy as np + +import awkward as ak + + +def _reduce_max_masked(array, mask): + assert mask + j = ak.from_regular( + ak.argmax(array["1"], axis=1, keepdims=True, mask_identity=True) + ) + return ak.flatten(array[j], axis=1) + + +behavior = {} +behavior[ak.max, "pair"] = _reduce_max_masked + + +def test_axis_0(): + content = ak.contents.ListArray( + ak.index.Index64([0, 2]), + ak.index.Index64([2, 4]), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 3, 6, 9, 11]), + ak.contents.RecordArray( + [ + ak.contents.NumpyArray(np.arange(11, dtype=np.int64)), + ak.contents.NumpyArray( + np.array( + [ + 0.0, + 2.0, + 4.0, + 6.0, + 8.0, + 10.0, + 1.0, + 14.0, + 16.0, + 18.0, + 20.0, + ], + dtype=np.float64, + ) + ), + ], + fields=None, + parameters={"__record__": "pair"}, + ), + ), + ) + + result = ak.max( + content, + axis=0, + keepdims=True, + mask_identity=True, + behavior=behavior, + highlevel=False, + ) + + expected_result = ak.contents.ListArray( + ak.index.Index64([0]), + ak.index.Index64([2]), + ak.contents.ListArray( + ak.index.Index64([0, 3]), + ak.index.Index64([3, 6]), + ak.contents.IndexedOptionArray( + ak.index.Index64([1, 5, 9, 3, 7, 10]), + ak.contents.RecordArray( + [ + ak.contents.NumpyArray( + np.array([0, 6, 3, 9, 1, 7, 4, 10, 2, 8, 5], dtype=np.int64) + ), + ak.contents.NumpyArray( + np.array( + [0, 1, 6, 18, 2, 14, 8, 20, 4, 16, 10], + dtype=np.float64, + ) + ), + ], + fields=None, + parameters={"__record__": "pair"}, + ), + ), + ), + ) + assert result.is_equal_to(expected_result) + + +def test_axis_1(): + content = ak.contents.ListArray( + ak.index.Index64([0, 2]), + ak.index.Index64([2, 4]), + ak.contents.ListOffsetArray( + ak.index.Index64([0, 3, 6, 9, 11]), + ak.contents.RecordArray( + [ + ak.contents.NumpyArray(np.arange(11, dtype=np.int64)), + ak.contents.NumpyArray( + np.array( + [ + 0.0, + 2.0, + 4.0, + 6.0, + 8.0, + 10.0, + 1.0, + 14.0, + 16.0, + 18.0, + 20.0, + ], + dtype=np.float64, + ) + ), + ], + fields=None, + parameters={"__record__": "pair"}, + ), + ), + ) + + result = ak.max( + content, + axis=1, + keepdims=True, + mask_identity=True, + behavior=behavior, + highlevel=False, + ) + + expected_result = ak.contents.RegularArray( + ak.contents.ListArray( + ak.index.Index64([0, 3]), + ak.index.Index64([3, 6]), + ak.contents.IndexedOptionArray( + ak.index.Index64([1, 5, 9, 3, 7, 10]), + ak.contents.RecordArray( + [ + ak.contents.NumpyArray( + np.array([0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8], dtype=np.int64) + ), + ak.contents.NumpyArray( + np.array( + [0, 6, 1, 18, 2, 8, 14, 20, 4, 10, 16], + dtype=np.float64, + ) + ), + ], + fields=None, + parameters={"__record__": "pair"}, + ), + ), + ), + size=1, + ) + assert result.is_equal_to(expected_result) diff --git a/tests/test_2518_datetime_units_as_parameter.py b/tests/test_2518_datetime_units_as_parameter.py new file mode 100644 index 0000000000..404cbc90bc --- /dev/null +++ b/tests/test_2518_datetime_units_as_parameter.py @@ -0,0 +1,32 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import numpy as np +import pytest + +import awkward as ak + + +def test_no_parameter(): + dtype = np.dtype("datetime64[15us]") + with pytest.warns( + DeprecationWarning, match=r"from_dtype conversion of temporal units" + ): + form = ak.forms.numpyform.from_dtype(dtype) + assert form.primitive == "datetime64" + assert form.parameters == {"__unit__": "15us"} + + +def test_true_parameter(): + dtype = np.dtype("datetime64[15us]") + with pytest.warns( + DeprecationWarning, match=r"from_dtype conversion of temporal units" + ): + form = ak.forms.numpyform.from_dtype(dtype, time_units_as_parameter=True) + assert form.primitive == "datetime64" + assert form.parameters == {"__unit__": "15us"} + + +def test_false_parameter(): + dtype = np.dtype("datetime64[15us]") + form = ak.forms.numpyform.from_dtype(dtype, time_units_as_parameter=False) + assert form.primitive == "datetime64[15us]"