Skip to content
Open
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
408 commits
Select commit Hold shift + click to select a range
0a120d7
add edge case for boolean mask
ClaudiaComito Apr 2, 2025
9657746
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Apr 8, 2025
b0bfa08
do not index scalar value
ClaudiaComito Apr 12, 2025
dfb0667
debugging
ClaudiaComito Apr 12, 2025
2e8001a
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Apr 12, 2025
39ab011
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito May 6, 2025
6d848d6
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Oct 29, 2025
cae4670
Merge branch '914_adv-indexing-outshape-outsplit' of github.com:helmh…
ClaudiaComito Oct 31, 2025
9d74da2
I already hate talisman after 1 day
ClaudiaComito Nov 3, 2025
b204589
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
Hakdag97 Nov 10, 2025
5a5ae6e
Fixed __setitem__ bug for unordered split_key
Hakdag97 Nov 28, 2025
0aa3ee0
Fixed bugs causing errors in test_getitem_boolean_fewer_dims
Hakdag97 Nov 28, 2025
36855d7
Bug fixes for test_setitem_edge_cases
Hakdag97 Dec 1, 2025
151d2b2
Further bug fixes
Hakdag97 Dec 1, 2025
960c5dd
All tests are running
Hakdag97 Dec 1, 2025
d67c5a9
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
Hakdag97 Dec 1, 2025
3e0e6a6
Edge case handling for test_indexing intermediate results
Hakdag97 Dec 4, 2025
25e1b34
Fixed test_indexing.py
Hakdag97 Dec 4, 2025
95c72a2
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
Hakdag97 Dec 4, 2025
0f09e7e
Bug fixes in function where()
Hakdag97 Dec 5, 2025
9956639
Merge branch '914_adv-indexing-outshape-outsplit' of github.com:helmh…
Hakdag97 Dec 5, 2025
aadcf35
Edge case handling for slice type keys in __getitem__
Hakdag97 Dec 5, 2025
b0147ce
Debugging tests for clustering - intermediate results
Hakdag97 Dec 8, 2025
f2e168c
Fixed edge case in indexing causing deadlock in kmedoids clustering
Hakdag97 Dec 8, 2025
638d1f8
Delete bug prints
Hakdag97 Dec 8, 2025
466c1f0
Edge case handling for keys like [:, -1], in order to fix test_basics
Hakdag97 Dec 10, 2025
047488c
Bug fixes for test_factories.py
Hakdag97 Dec 10, 2025
376cbb1
Fixed bug in test_cov (wrong balance)
Hakdag97 Dec 12, 2025
50f0ad1
Fixed bug in test_manipulations.py (function tile)
Hakdag97 Dec 12, 2025
c2ce57e
Drop tensor names in function tile
Hakdag97 Dec 12, 2025
595f84a
Handle edge case for test_svd and test_eigh
Hakdag97 Dec 12, 2025
28e46a1
Fix test_knn.py
Hakdag97 Dec 12, 2025
2c34b36
Added edge case neccessary for local outlier factor
Hakdag97 Dec 12, 2025
d790865
.
Hakdag97 Dec 12, 2025
b9f132e
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
Hakdag97 Dec 12, 2025
8a373c9
Fixed device mismatch in process_key
Hakdag97 Dec 15, 2025
3c9ea98
Merge branch '914_adv-indexing-outshape-outsplit' of github.com:helmh…
Hakdag97 Dec 15, 2025
bc6616b
Refine test_dndarray
Hakdag97 Dec 15, 2025
43f73c3
Handling of duplicate advanced indices
Hakdag97 Dec 15, 2025
1fc4f1e
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
Hakdag97 Dec 15, 2025
2240117
.
Hakdag97 Dec 15, 2025
e6256d5
Merge branch '914_adv-indexing-outshape-outsplit' of github.com:helmh…
Hakdag97 Dec 15, 2025
6da8259
Improved code coverage in tests
Hakdag97 Dec 15, 2025
3c9b989
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
mrfh92 Dec 17, 2025
2bfdbc5
Test debugging advanced indexing for dmd
Hakdag97 Dec 20, 2025
0149260
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
Hakdag97 Dec 20, 2025
17446a2
Fixed bug in process_key leading to failing dmd test
Hakdag97 Dec 20, 2025
9aa581e
Robustified edge cases in __process_key
Hakdag97 Dec 20, 2025
75483a7
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
Hakdag97 Jan 5, 2026
477aa2f
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
JuanPedroGHM Jan 9, 2026
4d79b0b
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
JuanPedroGHM Jan 9, 2026
df6714d
chore: minor type hints improvements for dndarray.py
JuanPedroGHM Jan 9, 2026
1c5090f
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Mar 18, 2026
82fd6bf
Merge branch '914_adv-indexing-outshape-outsplit' of github.com:helmh…
ClaudiaComito Mar 18, 2026
f445652
fix attribute assignment in DNDarray calls)
ClaudiaComito Mar 18, 2026
117bebb
fix position of split argument
ClaudiaComito Mar 18, 2026
a5c8788
add as_tuple argument for nonzero
ClaudiaComito Mar 19, 2026
1afc837
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito May 6, 2026
d680e25
move helper functions out of __getitem__/__setitem__
ClaudiaComito May 6, 2026
1108548
move most key sanitation to __process_key()
ClaudiaComito May 13, 2026
66c23ed
unbind instead of torch.split if as_tuple
ClaudiaComito May 13, 2026
0651339
extract distr logic unordered key from getitem
ClaudiaComito May 13, 2026
0a748de
extract distr logic for unordered value from setitem
ClaudiaComito May 13, 2026
a945528
process_key returns namedtuple, getitem acts as dispatch
ClaudiaComito May 14, 2026
e525f28
remove redundant _is_basic_component check
ClaudiaComito May 14, 2026
1331187
reorganize dispatching order, remove redundant checks
ClaudiaComito May 14, 2026
15ee181
refactor setitem - dispatch to appropriate helpers
ClaudiaComito May 14, 2026
a6ccbf9
fix misidentification of adv ind as mask-like
ClaudiaComito May 18, 2026
fde5b60
disentangle local from distributed masking
ClaudiaComito May 18, 2026
6470339
refactor distributed boolean mask fast-path
ClaudiaComito May 18, 2026
29c9885
fast-track local bool mask in tuple key
ClaudiaComito May 18, 2026
fe15b3f
do not fast-track mask getter with split>0
ClaudiaComito May 18, 2026
1564745
fix types call
ClaudiaComito May 18, 2026
fd36f92
distr setitem bug fixes
ClaudiaComito May 19, 2026
0ed5d9d
fix IndexError caused by list(key) on single tensor in Alltoallv
ClaudiaComito May 19, 2026
305accb
comment out print statements
ClaudiaComito May 19, 2026
7778cd1
always route distr key to unordered indexing
ClaudiaComito May 19, 2026
13df61c
expand tests
ClaudiaComito May 19, 2026
21e1ca4
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito May 19, 2026
0cedcee
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito May 20, 2026
d5eb00b
remove property decorator from stride()
ClaudiaComito May 20, 2026
51da43d
remove most itemsetting from test_matmul
ClaudiaComito May 20, 2026
ad7b8e5
adapt nonzero tests to as_tuple option
ClaudiaComito May 20, 2026
1873ef6
fix nonzero tests
ClaudiaComito May 20, 2026
0a2f383
nonzero tests
ClaudiaComito May 20, 2026
922a41a
handle 0-d bool indexing of 0-d array
ClaudiaComito May 20, 2026
b177e7d
test 0-d bool indexing of 0-d array
ClaudiaComito May 20, 2026
3a2aa67
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito May 20, 2026
ffa7cf7
reinstate CUDA deduplication
ClaudiaComito May 20, 2026
426c5d6
Issue #824, negative indices and multi-dim adv ind
ClaudiaComito May 26, 2026
8508d11
cover edge cases in #824
ClaudiaComito May 26, 2026
4239511
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito May 26, 2026
5815c79
remove dead code
ClaudiaComito May 26, 2026
ffd87cd
comment out print statements
ClaudiaComito May 26, 2026
d745001
vectorized mapping to dest ranks
ClaudiaComito May 27, 2026
8e68226
refactor unordered setitem, extract communication prep
ClaudiaComito May 27, 2026
61f1740
switch unordered getitem to Alltoallv
ClaudiaComito May 27, 2026
c8589c4
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Jun 2, 2026
86ecb5c
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Jun 2, 2026
9feaf97
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Jun 8, 2026
2d5502e
Reintegrate input sanitation in nonzero
ClaudiaComito Jun 8, 2026
6af95c2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 8, 2026
937bc18
Apply suggestions from code review
ClaudiaComito Jun 8, 2026
1ec9543
Remove edits
ClaudiaComito Jun 9, 2026
6bfb650
bring back to original state
ClaudiaComito Jun 9, 2026
199518a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 9, 2026
eaa34eb
Refactor distr_mask_fast_path
brownbaerchen Jun 9, 2026
350aaf8
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Jun 11, 2026
23ab286
remove legacy indexing leftovers
ClaudiaComito Jun 11, 2026
b3bf485
remove orphaned functions after refactoring
ClaudiaComito Jun 11, 2026
c803588
better name and docstring for tafkaprocessed_key
ClaudiaComito Jun 11, 2026
442d83e
move resolve_indexing_state out of Class
ClaudiaComito Jun 11, 2026
49406ab
rename dedup and move out of class
ClaudiaComito Jun 11, 2026
61b3799
introduce Indexer type alias
ClaudiaComito Jun 12, 2026
518d023
introduce Indexer type alias
ClaudiaComito Jun 12, 2026
ce60526
edits for readability
ClaudiaComito Jun 12, 2026
3fc2666
remove dead code
ClaudiaComito Jun 12, 2026
012b502
update getitem docstring
ClaudiaComito Jun 12, 2026
cffe445
update getitem docstring
ClaudiaComito Jun 12, 2026
9623a20
update setitem docstring
ClaudiaComito Jun 12, 2026
66b1a69
add docstrings for helper functions
ClaudiaComito Jun 12, 2026
02a4dc1
add docstrings for helper functions
ClaudiaComito Jun 12, 2026
8622766
fix split axis bookkeeping
ClaudiaComito Jun 12, 2026
fb7c5ba
revert split bookkeeping fix
ClaudiaComito Jun 12, 2026
eda3789
add indexing documentation
ClaudiaComito Jun 12, 2026
75246d2
correctly track split axis in adv indexing
ClaudiaComito Jun 13, 2026
cfaf4d2
expand tests
ClaudiaComito Jun 13, 2026
937a4cb
add indexing docs to rtd index
ClaudiaComito Jun 13, 2026
d4ce2aa
remove TMI
ClaudiaComito Jun 13, 2026
56d3b1f
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Jun 13, 2026
4c1ddde
render hyperlinks
ClaudiaComito Jun 13, 2026
324211f
remove print statements
ClaudiaComito Jun 13, 2026
e349b17
refactor indexing tests
ClaudiaComito Jun 13, 2026
70f133f
remove redundant where(cond) heuristics
ClaudiaComito Jun 13, 2026
bf8cedd
fix where tests for correct tuple output
ClaudiaComito Jun 13, 2026
425acd0
enforce consistent output split
ClaudiaComito Jun 13, 2026
447e5ca
fix nonzero tests
ClaudiaComito Jun 13, 2026
a05e0ea
Remove unnecessary stuff
brownbaerchen Jun 16, 2026
9f0543b
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
brownbaerchen Jun 16, 2026
f415953
Moved changes re batchparallelclustering to their own PR #2359
brownbaerchen Jun 16, 2026
76c5c85
Merge branch '914_adv-indexing-outshape-outsplit' of github.com:helmh…
brownbaerchen Jun 16, 2026
102b005
Cast numpy to torch in `_resolve_indexing_state` (#2369)
brownbaerchen Jul 14, 2026
405dadd
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Aug 27, 2026
3577c32
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Aug 27, 2026
f366f25
fix strides call
ClaudiaComito Aug 27, 2026
32f4a5d
adapt tests to int64 arange default
ClaudiaComito Aug 27, 2026
2f734db
fix op path for distr boolean in tuple key
ClaudiaComito Sep 7, 2026
6185446
add tests for distr boolean in tuple key
ClaudiaComito Sep 7, 2026
bc8394e
update torch_proxy
ClaudiaComito Sep 7, 2026
7c2fee9
normalize indexing keys early in resolve_indexing_state
ClaudiaComito Sep 7, 2026
522633a
adopt meta tensors in torch_proxy and remove named tensors deps
ClaudiaComito Sep 7, 2026
c6441dd
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Sep 7, 2026
8a3536d
adapt torch_proxy tests
ClaudiaComito Sep 7, 2026
8b78bbb
remove ref to named tensors
ClaudiaComito Sep 7, 2026
5e44038
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Sep 7, 2026
eaf9f15
refactor scalar checks
ClaudiaComito Sep 7, 2026
13b2d9f
refactor scalar checks incl. boolean
ClaudiaComito Sep 7, 2026
a5230c4
extract dim expantion from resolve_indexing_state
ClaudiaComito Sep 7, 2026
4f7e48e
take distr_path and 1d_boolean checks out of main function
ClaudiaComito Sep 8, 2026
e0fd374
take sanitation of int indices out of main function
ClaudiaComito Sep 8, 2026
33bb4b5
take slice idx processing out of main function
ClaudiaComito Sep 8, 2026
c13e52a
take adv idx axes processing out of main function
ClaudiaComito Sep 8, 2026
64db9a0
take op type assessment out of main function
ClaudiaComito Sep 8, 2026
2fadd7a
take op type assessment out of main function
ClaudiaComito Sep 8, 2026
dabb1a8
simplify cleanup of indexed dimensions in _resolve_indexing_state
ClaudiaComito Sep 8, 2026
cc29acd
take adv ind keys sanitation out of main function
ClaudiaComito Sep 8, 2026
2055392
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Sep 8, 2026
825e124
fix merge - remove LocalIndex
ClaudiaComito Sep 11, 2026
5b57966
consolidate slice and adv_local in getitem_local
ClaudiaComito Sep 11, 2026
9c27b94
consolidate slice and adv_local in setitem_local
ClaudiaComito Sep 11, 2026
1bbf020
edit docstrings
ClaudiaComito Sep 11, 2026
058af37
remove unused variable lose_dims
ClaudiaComito Sep 11, 2026
2031368
remove unreachable fallback else branch in __broadcast_value
ClaudiaComito Sep 11, 2026
ded5824
agnostic balanced property in scalar_early_out
ClaudiaComito Sep 11, 2026
b1a5b38
bypass array(is_split) call
ClaudiaComito Sep 11, 2026
2df1ebd
fix scalar value for descending setitem and nd buffer slicing
ClaudiaComito Sep 11, 2026
9addfff
add tests for scalar assignment on descending slice
ClaudiaComito Sep 11, 2026
e689820
remove unnecessary transpose back step
ClaudiaComito Sep 11, 2026
76868ae
remove backwards_transpose_axes
ClaudiaComito Sep 11, 2026
8ff577a
support single-mask tuple key and expand tests
ClaudiaComito Sep 11, 2026
26eb02c
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Sep 11, 2026
d2d5a67
bypass whole shebang for purely local indexing
ClaudiaComito Sep 11, 2026
8989370
skip multiple ellipses excep test in local mode
ClaudiaComito Sep 14, 2026
091ae0a
small fixes to non-distr indexing
ClaudiaComito Sep 14, 2026
2687a88
adapt indexing tests
ClaudiaComito Sep 14, 2026
18f19a3
skip split tests in local mode
ClaudiaComito Sep 14, 2026
f5dd6c7
fix device mismatch
ClaudiaComito Sep 14, 2026
4b3609b
timing
ClaudiaComito Sep 14, 2026
90785db
replace .larray.device with .device.torch_device property
ClaudiaComito Sep 14, 2026
8d54997
replace sorting with in-place comparison
ClaudiaComito Sep 14, 2026
596a229
optimize descending slice indexing (w. Gemini3.7ext)
ClaudiaComito Sep 14, 2026
e5b0809
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Sep 14, 2026
1cc0b38
bypass comm_matrix in prepare_unordered_comm
ClaudiaComito Sep 14, 2026
7d5da08
remove redundant sorting in _resolve_dupl_ind (w. Gemini3.7ext)
ClaudiaComito Sep 14, 2026
2a2185a
fix mistake in astype
ClaudiaComito Sep 14, 2026
bfbf8f3
consolidate coll communication in sanitize_int_indices
ClaudiaComito Sep 14, 2026
f95282c
replace cond masking with searchsorted in sanitize_advanced_keys
ClaudiaComito Sep 14, 2026
1504fcd
replace torch.zeros with empty where possible
ClaudiaComito Sep 14, 2026
27a41ad
debugging
ClaudiaComito Sep 15, 2026
f2f02b8
cache counts_displs and remove duplicate calls
ClaudiaComito Sep 15, 2026
138f8a7
CUDA: resolve duplicate indices for non-distr setitem as well
ClaudiaComito Sep 15, 2026
9f02cff
torch_proxy on meta device
ClaudiaComito Sep 15, 2026
71b538b
bypass recursive global getitem in resolve_indexing_state
ClaudiaComito Sep 15, 2026
f8e2081
optimize process_scalar_key via bisect (w. Gemini3.7ext)
ClaudiaComito Sep 15, 2026
5f78fd7
normalize negative indices in resolve_duplicate
ClaudiaComito Sep 15, 2026
d56e9f0
decouple value from indices payload in setitem_unordered
ClaudiaComito Sep 15, 2026
3242a3f
bypass factories.array() on scalar value in setitem
ClaudiaComito Sep 15, 2026
86c03a0
remove dummy tensor allocation from __set
ClaudiaComito Sep 15, 2026
0cee691
replace conditional indexing with searchsorted for ordered keys
ClaudiaComito Sep 15, 2026
b094745
support non-tensor rhs in _resolve_duplicate_indices
ClaudiaComito Sep 15, 2026
8c87bb9
delegate shape mismatch checks to PyTorch in setitem_mask
ClaudiaComito Sep 15, 2026
9562f99
bypass tensor creation for scalars in setitem_mask
ClaudiaComito Sep 15, 2026
5939250
update summary table
ClaudiaComito Sep 16, 2026
cab3ec5
update tables, remove detailed breakdown
ClaudiaComito Sep 16, 2026
e5eee2a
fix example
ClaudiaComito Sep 16, 2026
c0331b3
add Indexing docs
ClaudiaComito Sep 16, 2026
04f8c6a
Merge branch 'main' into 914_adv-indexing-outshape-outsplit
ClaudiaComito Sep 17, 2026
48d3a35
__setitem_mask(): expand tests and remove dead code
ClaudiaComito Sep 17, 2026
0b32413
__setitem_scalar(): remove dead code
ClaudiaComito Sep 17, 2026
4413496
expand test coverage _unwrap_local_key
ClaudiaComito Sep 17, 2026
4e1c59c
remove dead code from _resolve_duplicate_indices
ClaudiaComito Sep 17, 2026
9eb8263
preserve axis for singleton scalar indexers in _normalize_key
ClaudiaComito Sep 17, 2026
85eed47
expand adv indexing tests
ClaudiaComito Sep 17, 2026
69c8a1b
expand tests _scalar_early_out
ClaudiaComito Sep 17, 2026
54f2523
expand tests _expand_dimensions_and_ellipsis
ClaudiaComito Sep 17, 2026
227129d
expand tests _process_slice_indexer
ClaudiaComito Sep 17, 2026
49b605c
remove dead code _resolve_1d_boolean_first_dim
ClaudiaComito Sep 17, 2026
1443597
return IndexError on non-int, non-bool indices
ClaudiaComito Sep 17, 2026
1b3c680
expand tests indices sanitation
ClaudiaComito Sep 17, 2026
64b3884
support mask-like adv indexing on non-consecutive dims
ClaudiaComito Sep 17, 2026
6debddc
expand advanced indexing tests
ClaudiaComito Sep 17, 2026
b9faceb
expand tests _sanitize_advanced_keys
ClaudiaComito Sep 17, 2026
b74c730
debugging
ClaudiaComito Sep 17, 2026
23af2d0
debugging
ClaudiaComito Sep 17, 2026
d417870
remove dead code from _broadcast_value
ClaudiaComito Sep 18, 2026
3db671f
expand tests for _broadcast_value
ClaudiaComito Sep 18, 2026
368d1a1
expand tests __setitem_advanced_distributed
ClaudiaComito Sep 18, 2026
aaf9f2f
reinstate ind sanitation tests
ClaudiaComito Sep 18, 2026
e2f8e49
refactor: delegate key resplit to getitem/setitem
ClaudiaComito Sep 18, 2026
143c87f
expand advanced item assignment tests
ClaudiaComito Sep 18, 2026
1c75b8a
remove indexing How-To for now
ClaudiaComito Sep 18, 2026
2c11830
replace np.newaxis with ht.newaxis
ClaudiaComito Sep 18, 2026
686ccd5
unstage INDEXING.md for now
ClaudiaComito Sep 18, 2026
0e57992
expand advanced indexing tests
ClaudiaComito Sep 18, 2026
48085dd
expand advanced indexing tests
ClaudiaComito Sep 18, 2026
b5723f5
correct key distr and output reshape for multi-dimensional indexing
ClaudiaComito Sep 18, 2026
520b975
expand tests
ClaudiaComito Sep 18, 2026
7d712c6
remove dead code
ClaudiaComito Sep 18, 2026
3ea75b8
remove dead code
ClaudiaComito Sep 18, 2026
0b7299a
test plain newaxis
ClaudiaComito Sep 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 231 additions & 0 deletions doc/source/INDEXING.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation looks great!

Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@

# Indexing on DNDarrays

Heat v1.9 introduces fully distributed indexing for DNDarrays. While the indexing behaviour is designed to be highly compatible with the NumPy API, the memory-distributed nature of DNDarrays introduces unique considerations regarding performance and communication overhead. In the following sections, we will cover the basics plus some of these Heat-specific indexing features.

*Note: This guide is heavily inspired by the official [NumPy indexing documentation](https://numpy.org/doc/stable/user/basics.indexing.html).*

## Distributed indexing

We work under the assumption that Heat users process data in very large, memory-distributed arrays. In the following, we will refer to `array`, `key`, and `value` as the DNDarray, the index/combination of indices, and (if present) the value to be assigned to the index, respectively. Examples:

- item getting: `array[key]`
- item setting: `array[key] = value`

We assume that not only `array`, but also `key` and `value` may be very large and distributed across MPI processes if the use case requires.

The following table shows the distribution semantics of the DNDarray indexing operations.

| Array is distributed | Operation | Key is distributed | Value is distributed | Result is distributed | Notes |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **No** | `array[key]` | **No** | -- | **No** | Standard local indexing directly on underlying torch tensor. |
| **No** | `array[key]` | **Yes** | -- | **Yes** | For a 1D distributed key, the output inherits `split` and balanced status from the key. |
| **Yes** | `array[key]` | **No** | -- | **Yes** / **No** | Scalar `key` on split axis collapses that dimension, output is replicated on each process (`split=None`). For all other key types distribution is maintained. |
| **Yes** | `array[key]` | **Yes** | -- | **Yes** | **Local path:** Aligned boolean mask flattens locally with 0 communication.<br>**Communication path:** Unordered distributed integer indices trigger `__getitem_unordered` with `Alltoallv` exchange. |
| **No** | `array[key] = val` | **No** | **No** | **No** (In-place) | In-place assignment directly on underlying tensor. |
| **Yes** | `array[key] = val` | **No** | **No** | **Yes** (In-place) | **Scalars:** Assigned directly with 0 communication (PyTorch broadcasts locally).<br>**Local arrays:** Converted to a distributed array matching the target split axis and aligned via `redistribute_`. |
| **Yes** | `array[key] = val` | **No** | **Yes** | **Yes** (In-place) | **Split axis match required:** If `value.split != target.split`, raises a `RuntimeError`. |
| **Yes** | `array[key] = val` | **Yes** | **No, scalar** | **Yes** (In-place) | Python scalars and 0-D tensors assign directly to all local masked/indexed positions. |
| **Yes** | `array[key] = val` | **Yes** | **No, array** | **ERROR** / **Yes** | **Supported** only for boolean mask key, otherwise **ValueError** is raised. |
| **Yes** | `array[key] = val` | **Yes** | **Yes** | **Yes** (In-place) | **Aligned boolean mask key:** Local assignment with 0 communication.<br>**Unordered integer indices:** `key` is redistributed to match `value`, followed by a dual `Alltoallv` shuffle (indices and data payload). |

*Note: Extracting a single element along the split axis will collapse that dimension, resulting in `split=None`.*

---

## Basic slicing and indexing

Basic slicing extends Python's basic concept of slicing to N dimensions. It occurs when `key` is a `slice` object (constructed by `start:stop:step` notation inside brackets), an integer, or a tuple of slice objects and integers.

### Single element indexing
When indexing a single element or a specific slice that reduces the dimensionality of the array, the `split` axis is dynamically updated. If the array is indexed with an integer along the dimension it is split on, that dimension is collapsed and the resulting slice is no longer distributed along that axis.

```python
import heat as ht

# 1D array distributed across processes
x = ht.arange(10, split=0)
# indexing collapses the 0th dimension; the result is no longer distributed
result = x[2]
# result.split is None
```

If the array is multi-dimensional and split on an axis that is not the one being collapsed, the split axis shifts to account for the removed dimension.

```python
# 2D array distributed along axis 1 (columns)
x = ht.arange(10).reshape(2, 5)
x_split1 = ht.array(x, split=1)

# selecting a specific row collapses axis 0
result = x_split1[0]
# result.split is 0, because the old axis 1 is now the new axis 0
```

### Slicing and striding
Standard slicing `start:stop:step` preserves the dimensions of the array. The array remains distributed along the original split axis. Negative steps are supported and will reverse the elements locally while executing collective communication to reverse the chunks globally.

```python
x = ht.arange(20, split=0)
# slice with a step
result = x[1:11:3]
# result.split remains 0
```

### Dimensional indexing

You can manipulate the dimensionality of a DNDarray directly inside the brackets using ht.newaxis (or None) and ... (Ellipsis).

- `None` or `np.newaxis` inserts a new axis of size 1 into the array's shape. If the array is distributed, inserting an axis before the split axis will cause the split axis index to shift by +1.
Comment thread
ClaudiaComito marked this conversation as resolved.
Outdated

- `...` expands to the number of `:` objects needed to make a selection tuple of the same length as the array dimensions.

```python
x = ht.array([[[1], [2], [3]], [[4], [5], [6]]], split=1)

# adds a new dimension at axis 1
x_newaxis = x[:, None, :2, :]
# original split was 1; new split is 2
```

## Advanced indexing

Advanced indexing is triggered when the selection object key is a non-tuple sequence object, a DNDarray (of integer or boolean data type), a torch.Tensor, or a tuple with at least one sequence object or multi-dimensional array.

Advanced indexing always returns a copy of the data (contrast with basic slicing that returns a view).

### Integer array indexing

You can use DNDarray objects containing integers to select arbitrary items. The resulting array will take on the distribution map of the indexing key.


```python
# array split along axis 0
x = ht.arange(60, split=0).reshape(5, 3, 4)

# using multiple non-distributed indices
k1 = ht.array([0, 4, 1, 0])
k2 = ht.array([0, 2, 1, 0])
k3 = ht.array([1, 2, 3, 1])

# standard advanced indexing
result = x[k1, k2, k3]
```

### Boolean array indexing

Boolean arrays used as indices are treated as a mask. The result is a 1-D array containing the elements that correspond to True in the boolean array.

```python
arr = ht.arange(60, split=0).reshape(3, 4, 5)
mask = arr > 30

# returns a 1D array of all elements > 30, split along axis 0
result = arr[mask]
```

Row-selection optimization: Heat implements a highly optimized fast-path for the common data science pattern of row-filtering. If you index a 2D array split along axis 0 with a 1D boolean mask that is also split along axis 0, Heat skips the heavy distributed indexing machinery. It applies the mask locally and resolves the global shape via a fast metadata exchange. The output remains a 2D array split along axis 0.


```python
arr_2d = ht.arange(20, split=0).reshape((10, 2))
mask_1d = ht.array([True, False, True, False, True, False, True, False, True, False], split=0)

# the result remains a 2D array (shape: 5, 2) and retains split=0
result = arr_2d[mask_1d]
```

### In-place assignment (setitem)

Advanced indexing can be used to assign values. If the assignment value is itself a distributed DNDarray, Heat will automatically execute a distributed routing protocol (via Alltoallv) to align the spatial memory distribution of the values with the target indices before executing the local assignments.

```python
x = ht.arange(10 * 20 * 30, split=1).reshape(10, 20, 30)

# boolean mask assignment
mask = x > 100
x[mask] = 99.0

# advanced integer assignment with an aligned distributed value
# (assigning 10 elements along axis 1 on a 1D slice across all other dimensions)
indices = ht.array([2, 5, 8, 11], dtype=ht.int64, split=0)
value = ht.ones((10, 4, 30), split=1)

x[:, indices, :] = value
```

## Combining advanced and basic indexing

When you mix advanced indexing (like integer arrays or lists) with basic slicing (like `:`), the shape of the resulting `DNDarray` depends on whether the advanced indices are positioned next to each other.

Heat follows NumPy's standard transposition rules for mixed indexing, while automatically managing the distributed memory alignment internally. The array's nominal `split` axis will track the new dimensional layout.

### Advanced indexing on consecutive dimensions
If the advanced indices are adjacent to each other (not separated by a slice), the resulting broadcasted shape of the advanced indices is inserted directly into the output shape at the position of the first advanced index.

If the original array's `split` axis is untouched by the advanced indexing, it will simply shift to account for the collapsed dimensions.

```python
import heat as ht

# arr shape: (10, 20, 30, 40), distributed along axis 3
arr = ht.zeros((10, 20, 30, 40), split=3)
a1 = ht.array([1, 2])
a2 = ht.array([3, 4])

# Advanced indices are consecutive on axes 1 and 2
result = arr[:, a1, a2, :]

# The advanced indices on axes 1 and 2 broadcast to a single shape (2,)
# Result shape: (10, 2, 40)

# The original split axis 3 is now the last dimension in the new shape.
# result.split is 2
```

### Advanced indexing on non-consecutive dimensions

If the advanced indices are separated by a basic slice, the resulting layout becomes ambiguous. To resolve this, the advanced-indexing dimensions are grouped together and transposed to the very front of the resulting array's shape.

Any remaining basic slices follow behind them. The split axis is tracked through this transposition and assigned its new relative index.

```python
import heat as ht

# arr shape: (10, 20, 30, 40), distributed along axis 3
arr = ht.zeros((10, 20, 30, 40), split=3)
a1 = ht.array([1, 2])
a2 = ht.array([3, 4])

# Advanced indices (axes 0 and 2) are separated by a slice (axis 1)
result = arr[a1, :, a2, :]

# The advanced indices broadcast to shape (2,) and are moved to the front.
# The untouched basic slices (from axes 1 and 3) are appended to the back.
# Result shape: (2, 20, 40)

# The original split axis 3 is still the last dimension in the new array.
# result.split is 2
```

## Communication overhead

The indexing operations evaluate the state of the indexing key to determine the most efficient network routing strategy. The communication overhead ranges from completely zero (purely local execution) to heavy all-to-all exchanges for non-sequential advanced indexing.

Here are the different possible configurations, categorized and ordered from the lowest communication overhead to the highest within each category.

### Summary of Communication Overhead

| Category | Configuration (Operation & State) | Communication Overhead (MPI Calls) |
| :--- | :--- | :--- |
| **Single Element Indexing** | `array[key]` (key is an integer on a *non-split* axis) | **None** |
| | `array[key] = local_value` (key is an int on the *split* axis) | **None** (Only the root rank executes the local set) |
| | `array[key]` (key is an int on the *split* axis) | **1 `Bcast`** (Root extracts value and broadcasts to all ranks) |
| **Slicing & Striding** | `array[slice]` or `array[slice] = local_value` | **None** |
| | `array[::-1]` (Descending slice along split axis) | **None** (Executes local slice followed by a global `flip` operation) |
| | `array[::-1] = distributed_value` (Descending slice write) | **Multiple `Send`/`Recv`** (Executes `redistribute_` using point-to-point transfers if array slice and value are misaligned) |
| **Dimensional Indexing** | `array[..., None]` or `array[:, np.newaxis]` | **None** |
| **Advanced Indexing** | `array[mask]` (1D or full bool mask, split=0) | **1 `Allreduce`** (Applies mask locally, reduces element counts to compute `gshape`) |
| | `array[non_seq_key] = local_value` | **1 `Allreduce`** (Batched validation for bounds and negative coordinates) |
| | `array[non_seq_key]` (Unstructured read) | **1 `Alltoall` + 2 `Alltoallv`** (Exchanges counts, requests indices, returns data) |
| **Slicing & Striding**| `array[::-1]` (Descending slice along split axis) | **Point-to-point / Redistribution** (Local slice followed by distributed `flip`) |
14 changes: 14 additions & 0 deletions doc/source/_static/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,17 @@ code,
.frontpage-news .timeline-item:nth-child(n+5) {
display: none;
}

/* ============================================================
CUSTOM OVERRIDES: Force hyperlinks to be visible in italics
============================================================ */
.rst-content a,
.md-typeset a {
color: #2980B9 !important; /* Matches standard RTD blue */
text-decoration: none;
}

.rst-content a:hover,
.md-typeset a:hover {
text-decoration: underline !important;
}
16 changes: 16 additions & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,22 @@ How-to guides

**Linear algebra:** Matrix-matrix multiplications, Singular Value Decomposition across multi-GPU.

.. grid-item-card::
:class-card: sd-card
:link: /indexing
:link-type: doc

@mtar mtar Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The card doesn't link to any page.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mtar thanks. I'm tempted to leave the documentation page out of this PR, and finish it properly in the next weeks. What do you think?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indexing is explicitly mentioned in a notebook. The output behaviour hasn't changed there and a note mentioned that PR.

Yes, the longer in depth article can be added later.


.. image:: _static/images/tutorial_split_dndarray.svg

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the page the same image is used four times now. We will have to replace some of them.

:alt: Distributed Indexing
:align: center
:height: 140px

.. div:: mt-3 **Distributed indexing & item assignment**

.. div:: text-muted small mt-1

**Distributed indexing:** Slicing, boolean masking, unstructured indexing, and assignment across MPI ranks.

.. grid-item-card::
:class-card: sd-card
:link: /tutorials/notebooks/Clustering_and_PCA
Expand Down
6 changes: 3 additions & 3 deletions heat/classification/kneighborsclassifier.py
Comment thread
brownbaerchen marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ def predict(self, x: DNDarray) -> DNDarray:
"""
distances = self.effective_metric_(x, self.x)
_, indices = ht.topk(distances, self.n_neighbors, largest=False)
predictions = self.y[indices.flatten()]

predictions = self.y[indices]
predictions.balance_()
predictions = ht.reshape(predictions, (indices.gshape + (self.y.gshape[1],)))
predictions = ht.reshape(predictions, indices.gshape + (self.y.gshape[1],))
predictions = ht.sum(predictions, axis=1)

self.classes_ = ht.argmax(predictions, axis=1)

return self.classes_
Loading
Loading