galley-jl-python 0.1.1__tar.gz → 0.1.2__tar.gz

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.
Files changed (21) hide show
  1. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/PKG-INFO +1 -1
  2. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/pyproject.toml +1 -1
  3. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/juliapkg.json +1 -1
  4. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/tensor.py +30 -4
  5. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/LICENSE +0 -0
  6. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/README.md +0 -0
  7. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/__init__.py +0 -0
  8. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/_array_api_info.py +0 -0
  9. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/_sysimage.py +0 -0
  10. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/compiled.py +0 -0
  11. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/dtypes.py +0 -0
  12. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/einstein.py +0 -0
  13. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/errors.py +0 -0
  14. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/finch_fused.py +0 -0
  15. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/io.py +0 -0
  16. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/julia.py +0 -0
  17. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/juliapkg_dev.json +0 -0
  18. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/levels.py +0 -0
  19. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/linalg/__init__.py +0 -0
  20. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/linalg/_linalg.py +0 -0
  21. {galley_jl_python-0.1.1 → galley_jl_python-0.1.2}/src/galley_jl_python/typing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: galley-jl-python
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Sparse Tensor Programming in Python powered by Finch.jl
5
5
  License-File: LICENSE
6
6
  Author: Willow Ahrens
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "galley-jl-python"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  description = "Sparse Tensor Programming in Python powered by Finch.jl"
5
5
  readme = "README.md"
6
6
  authors = [{name = "Willow Ahrens", email = "willow.marie.ahrens@gmail.com"}]
@@ -91,7 +91,7 @@
91
91
  },
92
92
  "Galley": {
93
93
  "uuid": "0b99cc74-af0a-4786-be99-594ac14242a4",
94
- "version": "=0.2.1"
94
+ "version": "=0.2.2"
95
95
  },
96
96
  "Gamma": {
97
97
  "uuid": "a0844989-3bd2-4988-8bea-c9407ab0941b",
@@ -68,6 +68,18 @@ def _weak_scalar(element_type, value):
68
68
  return jc.convert(jl.galley_weak_scalar_type(element_type, value_type), value)
69
69
 
70
70
 
71
+ def _scalar_tensor(value) -> Tensor:
72
+ """A Julia scalar as a 0-d tensor whose fill is the scalar itself."""
73
+ return Tensor(jl.swizzle(_scalar_to_0d(jl.typeof(value), value, value)))
74
+
75
+
76
+ # `where` picks with `ifelse` after promoting both branches to one type, as
77
+ # the Array API requires. Julia's `ifelse` returns whichever branch it picks
78
+ # unchanged, so on its own it would give a Union{Float64, Int64} result for a
79
+ # float branch and an integer one.
80
+ _where_op = jl.seval("(c, a, b) -> ifelse(c, promote(a, b)...)")
81
+
82
+
71
83
  def _element_fill(dtype, fill_value):
72
84
  """fill_value as an Element level's fill for values of dtype.
73
85
 
@@ -311,8 +323,9 @@ class Tensor(_Display, SparseArray):
311
323
  def _elemwise_op(
312
324
  self, op: str, other: Tensor | None = None, *, reflected: bool = False
313
325
  ) -> Tensor:
326
+ fn = jl.seval(op)
314
327
  if other is None:
315
- result = jl.broadcast(jl.seval(op), self._obj)
328
+ result = jl.broadcast(fn, self._obj)
316
329
  else:
317
330
  if np.isscalar(other):
318
331
  other = _weak_scalar(jl.eltype(self._obj), other)
@@ -321,7 +334,7 @@ class Tensor(_Display, SparseArray):
321
334
  # inverse swizzle, so `broadcast` appends new dims to the front
322
335
  this = jl.permutedims(self._obj, tuple(range(self.ndim, 0, -1)))
323
336
  args = (other, this) if reflected else (this, other)
324
- result = jl.broadcast(jl.seval(op), *args)
337
+ result = jl.broadcast(fn, *args)
325
338
  # swizzle back to the original order
326
339
  result = jl.permutedims(result, tuple(range(jl.ndims(result), 0, -1)))
327
340
 
@@ -987,7 +1000,20 @@ def astype(x: Tensor, dtype: DType, /, *, copy: bool = True) -> Tensor:
987
1000
  return Tensor(jl.swizzle(result, *x.get_order(zero_indexing=False)))
988
1001
 
989
1002
 
990
- def where(condition: Tensor, x1: Tensor, x2: Tensor, /) -> Tensor:
1003
+ def where(
1004
+ condition: Tensor,
1005
+ x1: Tensor | complex,
1006
+ x2: Tensor | complex,
1007
+ /,
1008
+ ) -> Tensor:
1009
+ # A Python scalar takes the other branch's type when it is of the same
1010
+ # kind, as the Array API's weak scalars do.
1011
+ if np.isscalar(x1) and np.isscalar(x2):
1012
+ raise TypeError("where needs at least one of x1 and x2 to be an array.")
1013
+ if np.isscalar(x1):
1014
+ x1 = _scalar_tensor(_weak_scalar(jl.eltype(x2._obj), x1))
1015
+ if np.isscalar(x2):
1016
+ x2 = _scalar_tensor(_weak_scalar(jl.eltype(x1._obj), x2))
991
1017
  axis_cond, axis_x1, axis_x2 = (
992
1018
  range(condition.ndim, 0, -1),
993
1019
  range(x1.ndim, 0, -1),
@@ -995,7 +1021,7 @@ def where(condition: Tensor, x1: Tensor, x2: Tensor, /) -> Tensor:
995
1021
  )
996
1022
  # inverse swizzle, so `broadcast` appends new dims to the front
997
1023
  result = jl.broadcast(
998
- jl.ifelse,
1024
+ _where_op,
999
1025
  jl.permutedims(condition._obj, tuple(axis_cond)),
1000
1026
  jl.permutedims(x1._obj, tuple(axis_x1)),
1001
1027
  jl.permutedims(x2._obj, tuple(axis_x2)),