dask-array 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dask_array/__init__.py +228 -0
- dask_array/_backends.py +76 -0
- dask_array/_backends_array.py +99 -0
- dask_array/_blockwise.py +1410 -0
- dask_array/_broadcast.py +272 -0
- dask_array/_chunk.py +445 -0
- dask_array/_chunk_types.py +54 -0
- dask_array/_collection.py +1644 -0
- dask_array/_concatenate.py +331 -0
- dask_array/_core_utils.py +1365 -0
- dask_array/_dispatch.py +141 -0
- dask_array/_einsum.py +277 -0
- dask_array/_expr.py +544 -0
- dask_array/_expr_flow.py +586 -0
- dask_array/_gufunc.py +805 -0
- dask_array/_histogram.py +617 -0
- dask_array/_map_blocks.py +652 -0
- dask_array/_new_collection.py +10 -0
- dask_array/_numpy_compat.py +135 -0
- dask_array/_overlap.py +1159 -0
- dask_array/_rechunk.py +1050 -0
- dask_array/_reshape.py +710 -0
- dask_array/_routines.py +102 -0
- dask_array/_shuffle.py +448 -0
- dask_array/_stack.py +264 -0
- dask_array/_svg.py +291 -0
- dask_array/_templates.py +29 -0
- dask_array/_test_utils.py +257 -0
- dask_array/_ufunc.py +385 -0
- dask_array/_utils.py +349 -0
- dask_array/_visualize.py +223 -0
- dask_array/_xarray.py +337 -0
- dask_array/core/__init__.py +34 -0
- dask_array/core/_blockwise_funcs.py +312 -0
- dask_array/core/_conversion.py +422 -0
- dask_array/core/_from_graph.py +97 -0
- dask_array/creation/__init__.py +71 -0
- dask_array/creation/_arange.py +121 -0
- dask_array/creation/_diag.py +116 -0
- dask_array/creation/_diagonal.py +241 -0
- dask_array/creation/_eye.py +103 -0
- dask_array/creation/_linspace.py +102 -0
- dask_array/creation/_mesh.py +134 -0
- dask_array/creation/_ones_zeros.py +454 -0
- dask_array/creation/_pad.py +270 -0
- dask_array/creation/_repeat.py +55 -0
- dask_array/creation/_tile.py +36 -0
- dask_array/creation/_tri.py +28 -0
- dask_array/creation/_utils.py +296 -0
- dask_array/fft.py +320 -0
- dask_array/io/__init__.py +39 -0
- dask_array/io/_base.py +10 -0
- dask_array/io/_from_array.py +257 -0
- dask_array/io/_from_delayed.py +95 -0
- dask_array/io/_from_graph.py +54 -0
- dask_array/io/_from_npy_stack.py +67 -0
- dask_array/io/_store.py +336 -0
- dask_array/io/_tiledb.py +159 -0
- dask_array/io/_to_npy_stack.py +65 -0
- dask_array/io/_zarr.py +449 -0
- dask_array/linalg/__init__.py +39 -0
- dask_array/linalg/_cholesky.py +234 -0
- dask_array/linalg/_lu.py +300 -0
- dask_array/linalg/_norm.py +94 -0
- dask_array/linalg/_qr.py +601 -0
- dask_array/linalg/_solve.py +349 -0
- dask_array/linalg/_svd.py +394 -0
- dask_array/linalg/_tensordot.py +334 -0
- dask_array/linalg/_utils.py +74 -0
- dask_array/manipulation/__init__.py +45 -0
- dask_array/manipulation/_expand.py +321 -0
- dask_array/manipulation/_flip.py +92 -0
- dask_array/manipulation/_roll.py +78 -0
- dask_array/manipulation/_transpose.py +309 -0
- dask_array/random/__init__.py +125 -0
- dask_array/random/_choice.py +181 -0
- dask_array/random/_expr.py +256 -0
- dask_array/random/_generator.py +441 -0
- dask_array/random/_random_state.py +259 -0
- dask_array/random/_utils.py +84 -0
- dask_array/reductions/__init__.py +84 -0
- dask_array/reductions/_arg_reduction.py +130 -0
- dask_array/reductions/_common.py +1082 -0
- dask_array/reductions/_cumulative.py +522 -0
- dask_array/reductions/_percentile.py +261 -0
- dask_array/reductions/_reduction.py +725 -0
- dask_array/reductions/_trace.py +56 -0
- dask_array/routines/__init__.py +133 -0
- dask_array/routines/_apply.py +84 -0
- dask_array/routines/_bincount.py +112 -0
- dask_array/routines/_broadcast.py +111 -0
- dask_array/routines/_coarsen.py +115 -0
- dask_array/routines/_diff.py +79 -0
- dask_array/routines/_gradient.py +158 -0
- dask_array/routines/_indexing.py +65 -0
- dask_array/routines/_insert_delete.py +132 -0
- dask_array/routines/_misc.py +122 -0
- dask_array/routines/_nonzero.py +72 -0
- dask_array/routines/_search.py +123 -0
- dask_array/routines/_select.py +113 -0
- dask_array/routines/_statistics.py +171 -0
- dask_array/routines/_topk.py +82 -0
- dask_array/routines/_triangular.py +74 -0
- dask_array/routines/_unique.py +232 -0
- dask_array/routines/_where.py +62 -0
- dask_array/slicing/__init__.py +67 -0
- dask_array/slicing/_basic.py +550 -0
- dask_array/slicing/_blocks.py +138 -0
- dask_array/slicing/_bool_index.py +145 -0
- dask_array/slicing/_setitem.py +329 -0
- dask_array/slicing/_squeeze.py +101 -0
- dask_array/slicing/_utils.py +1133 -0
- dask_array/slicing/_vindex.py +282 -0
- dask_array/stacking/__init__.py +15 -0
- dask_array/stacking/_block.py +83 -0
- dask_array/stacking/_simple.py +58 -0
- dask_array/templates/array.html.j2 +48 -0
- dask_array/tests/__init__.py +0 -0
- dask_array/tests/conftest.py +22 -0
- dask_array/tests/test_api.py +40 -0
- dask_array/tests/test_binary_op_chunks.py +107 -0
- dask_array/tests/test_coarse_slice_through_blockwise.py +362 -0
- dask_array/tests/test_collection.py +799 -0
- dask_array/tests/test_creation.py +1102 -0
- dask_array/tests/test_expr_flow.py +143 -0
- dask_array/tests/test_linalg.py +1130 -0
- dask_array/tests/test_map_blocks_multi_output.py +104 -0
- dask_array/tests/test_rechunk_pushdown.py +214 -0
- dask_array/tests/test_reductions.py +1091 -0
- dask_array/tests/test_routines.py +2853 -0
- dask_array/tests/test_shuffle_chunks.py +67 -0
- dask_array/tests/test_slice_pushdown.py +968 -0
- dask_array/tests/test_slice_through_blockwise.py +678 -0
- dask_array/tests/test_slice_through_overlap.py +366 -0
- dask_array/tests/test_slice_through_reshape.py +272 -0
- dask_array/tests/test_slicing.py +839 -0
- dask_array/tests/test_transpose_slice_pushdown.py +208 -0
- dask_array/tests/test_visualize.py +94 -0
- dask_array/tests/test_xarray.py +193 -0
- dask_array-0.1.0.dist-info/METADATA +48 -0
- dask_array-0.1.0.dist-info/RECORD +144 -0
- dask_array-0.1.0.dist-info/WHEEL +4 -0
- dask_array-0.1.0.dist-info/entry_points.txt +2 -0
- dask_array-0.1.0.dist-info/licenses/LICENSE +29 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""Tests for expression flow visualization."""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
import dask_array as da
|
|
7
|
+
from dask_array._expr_flow import (
|
|
8
|
+
FlowDiagram,
|
|
9
|
+
FlowEdge,
|
|
10
|
+
FlowNode,
|
|
11
|
+
build_flow_graph,
|
|
12
|
+
count_operations,
|
|
13
|
+
expr_flow,
|
|
14
|
+
render_flow_svg,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_linear_chain_single_node():
|
|
19
|
+
"""Linear chain with same shape creates single node."""
|
|
20
|
+
x = da.from_array(np.random.random((100, 100)), chunks=(50, 50))
|
|
21
|
+
y = x + 1
|
|
22
|
+
z = y * 2
|
|
23
|
+
result = z - 0.5
|
|
24
|
+
|
|
25
|
+
nodes, edges = build_flow_graph(result._expr)
|
|
26
|
+
assert len(nodes) == 1
|
|
27
|
+
assert len(edges) == 0
|
|
28
|
+
assert nodes[0].shape == (100, 100)
|
|
29
|
+
assert len(nodes[0].operations) == 4 # Load, Add, Mul, Sub
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_reduction_creates_nodes():
|
|
33
|
+
"""Reduction creates nodes with edges."""
|
|
34
|
+
x = da.from_array(np.random.random((100, 100)), chunks=(50, 50))
|
|
35
|
+
y = x + 1
|
|
36
|
+
result = y.sum()
|
|
37
|
+
|
|
38
|
+
nodes, edges = build_flow_graph(result._expr)
|
|
39
|
+
# Should have at least source and final result (may include intermediates)
|
|
40
|
+
assert len(nodes) >= 2
|
|
41
|
+
assert len(edges) >= 1
|
|
42
|
+
shapes = {n.shape for n in nodes}
|
|
43
|
+
assert (100, 100) in shapes # Source
|
|
44
|
+
assert () in shapes # Final scalar result
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_axis_reduction():
|
|
48
|
+
"""Axis reduction shows shape change."""
|
|
49
|
+
x = da.from_array(np.random.random((100, 100)), chunks=(50, 50))
|
|
50
|
+
result = x.sum(axis=0)
|
|
51
|
+
|
|
52
|
+
nodes, edges = build_flow_graph(result._expr)
|
|
53
|
+
# Should have at least source and final result
|
|
54
|
+
assert len(nodes) >= 2
|
|
55
|
+
shapes = {n.shape for n in nodes}
|
|
56
|
+
assert (100, 100) in shapes # Source
|
|
57
|
+
assert (100,) in shapes # Final reduced result
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_multi_input_separate_nodes():
|
|
61
|
+
"""Multi-input creates separate source nodes."""
|
|
62
|
+
a = da.from_array(np.random.random((100, 100)), chunks=(50, 50))
|
|
63
|
+
b = da.from_array(np.random.random((100, 100)), chunks=(50, 50))
|
|
64
|
+
result = a + b
|
|
65
|
+
|
|
66
|
+
nodes, edges = build_flow_graph(result._expr)
|
|
67
|
+
assert len(nodes) == 3 # Two inputs + one output
|
|
68
|
+
assert len(edges) == 2 # Two edges to output
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_layout_assignment():
|
|
72
|
+
"""Layout assigns correct columns."""
|
|
73
|
+
x = da.from_array(np.random.random((100, 100)), chunks=(50, 50))
|
|
74
|
+
result = x.sum()
|
|
75
|
+
|
|
76
|
+
nodes, edges = build_flow_graph(result._expr)
|
|
77
|
+
# Source should be at column 0, result at highest column
|
|
78
|
+
cols = {n.shape: n.col for n in nodes}
|
|
79
|
+
assert cols[(100, 100)] == 0 # Source at start
|
|
80
|
+
# Final result at end (may be column 1 or higher if intermediates shown)
|
|
81
|
+
assert cols[()] >= 1
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_count_operations():
|
|
85
|
+
"""count_operations returns correct count."""
|
|
86
|
+
x = da.from_array(np.random.random((100, 100)), chunks=(50, 50))
|
|
87
|
+
y = x + 1
|
|
88
|
+
result = y.sum()
|
|
89
|
+
|
|
90
|
+
count = count_operations(result._expr)
|
|
91
|
+
assert count >= 2 # At least load and sum
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_expr_flow_accepts_array():
|
|
95
|
+
"""expr_flow works with Array objects."""
|
|
96
|
+
x = da.ones((10, 10), chunks=5)
|
|
97
|
+
flow = expr_flow(x)
|
|
98
|
+
assert isinstance(flow, FlowDiagram)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_expr_flow_accepts_expr():
|
|
102
|
+
"""expr_flow works with ArrayExpr objects."""
|
|
103
|
+
x = da.ones((10, 10), chunks=5)
|
|
104
|
+
flow = expr_flow(x._expr)
|
|
105
|
+
assert isinstance(flow, FlowDiagram)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_flow_diagram_repr():
|
|
109
|
+
"""FlowDiagram has text repr."""
|
|
110
|
+
x = da.ones((10, 10), chunks=5)
|
|
111
|
+
flow = expr_flow(x)
|
|
112
|
+
text = repr(flow)
|
|
113
|
+
assert "Expression:" in text
|
|
114
|
+
assert "operations" in text
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_flow_diagram_html():
|
|
118
|
+
"""FlowDiagram generates HTML."""
|
|
119
|
+
x = da.ones((10, 10), chunks=5)
|
|
120
|
+
flow = expr_flow(x)
|
|
121
|
+
html = flow._repr_html_()
|
|
122
|
+
assert "<div" in html
|
|
123
|
+
assert "svg" in html or "text-align" in html
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def test_render_flow_svg():
|
|
127
|
+
"""render_flow_svg produces HTML."""
|
|
128
|
+
x = da.ones((10, 10), chunks=5)
|
|
129
|
+
html = render_flow_svg(x._expr)
|
|
130
|
+
assert "<div" in html
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_key_shapes_present():
|
|
134
|
+
"""Key shapes (source and result) are present in flow graph."""
|
|
135
|
+
x = da.from_array(np.random.random((100, 100)), chunks=(50, 50))
|
|
136
|
+
result = x.sum()
|
|
137
|
+
|
|
138
|
+
nodes, edges = build_flow_graph(result._expr)
|
|
139
|
+
# Main shapes should always be present
|
|
140
|
+
shapes = {n.shape for n in nodes}
|
|
141
|
+
assert (100, 100) in shapes # Source data
|
|
142
|
+
assert () in shapes # Final scalar result
|
|
143
|
+
# May include intermediates - that's OK with conservative filtering
|