Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
bea38e8
Initial commit
andrewdalpino Sep 19, 2026
5908b98
Save game
andrewdalpino Sep 19, 2026
d4ccdc6
Merge branch '4.0' into zephir-buffer
andrewdalpino Sep 20, 2026
930cce7
Merge branch '4.0' into zephir-buffer
andrewdalpino Sep 20, 2026
98b3fe2
A little nicer
andrewdalpino Sep 21, 2026
b10bebc
Save game
andrewdalpino Sep 21, 2026
e75e736
Expand TensorBuffer API
andrewdalpino Sep 21, 2026
994264d
Save game
andrewdalpino Sep 21, 2026
78aeb95
Save game
andrewdalpino Sep 22, 2026
64e547c
Remove a ton of AI slop
andrewdalpino Sep 22, 2026
618952d
Clean up more AI slop
andrewdalpino Sep 22, 2026
c29eb11
Remove even more AI slop
andrewdalpino Sep 22, 2026
dce2728
Fix more AI slop
andrewdalpino Sep 22, 2026
040fca9
Save game
andrewdalpino Sep 22, 2026
9933179
Fix tests
andrewdalpino Sep 22, 2026
c068683
Fix benchmarks
andrewdalpino Sep 22, 2026
ca06425
Merge branch '4.0' into zephir-buffer
andrewdalpino Sep 22, 2026
5e4212f
Optimize unary operations
andrewdalpino Sep 22, 2026
77fc773
Fix typo
andrewdalpino Sep 22, 2026
b828d49
More optimizations
andrewdalpino Sep 22, 2026
66ac38a
A little nicer
andrewdalpino Sep 22, 2026
928d4de
Convert reductions and decompositions to buffer
andrewdalpino Sep 22, 2026
612c145
A little bit nicer
andrewdalpino Sep 22, 2026
b8d3406
Fix typo
andrewdalpino Sep 22, 2026
a5be5f1
Save game
andrewdalpino Sep 22, 2026
df70f3c
A little nicer
andrewdalpino Sep 22, 2026
879c1ce
PHP array serial representation
andrewdalpino Sep 23, 2026
c912bb7
A little nicer
andrewdalpino Sep 23, 2026
234d9c4
Save game
andrewdalpino Sep 23, 2026
20b0149
Fix mod tests
andrewdalpino Sep 23, 2026
a0ca87c
A little nicer
andrewdalpino Sep 23, 2026
792b33e
Convert to floats
andrewdalpino Sep 23, 2026
74caee5
Add test
andrewdalpino Sep 23, 2026
455f425
Add headers
andrewdalpino Sep 23, 2026
f142b64
Plug memory leak
andrewdalpino Sep 23, 2026
ea49f19
Will write later
andrewdalpino Sep 23, 2026
f41f7ec
Fix map bug
andrewdalpino Sep 23, 2026
fe32112
Fix clobber
andrewdalpino Sep 24, 2026
bfa015e
Fix bugs
andrewdalpino Sep 24, 2026
7ddfa11
Save game
andrewdalpino Sep 24, 2026
0aa4ded
Unlock multithreading
andrewdalpino Sep 24, 2026
20602ce
A little nicer
andrewdalpino Sep 24, 2026
03c8ee9
Optimize matrix reducers
andrewdalpino Sep 24, 2026
afdd763
Consolidate reducers
andrewdalpino Sep 24, 2026
67eb12a
Remove bootstrap
andrewdalpino Sep 24, 2026
0ec0bef
Optimize dot
andrewdalpino Sep 24, 2026
e4f84b9
Optimize
andrewdalpino Sep 24, 2026
01655da
More vectorization
andrewdalpino Sep 24, 2026
3061438
Optimize median and quantiles
andrewdalpino Sep 24, 2026
d3dd415
Optimize transpose
andrewdalpino Sep 24, 2026
0ed2449
More optimizations
andrewdalpino Sep 24, 2026
8b1b1c3
Fix typo
andrewdalpino Sep 24, 2026
1b499f6
Save game
andrewdalpino Sep 24, 2026
b705ac5
Optimize sum and product
andrewdalpino Sep 24, 2026
522dfef
Merge pull request #1 from RubixML/zephir-buffer
andrewdalpino Sep 24, 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
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ jobs:
- name: Install Dependencies
run: composer install

- name: Static Analysis
run: composer analyze

- name: Unit Tests
run: composer test

Expand Down
17 changes: 7 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ Guidance for AI coding agents contributing to **Tensor** — a scientific-comput

## Environment

- PHP **8.1+** (CI matrix is 8.1 → 8.5). `composer.json` declares `>=1.0`.
- Dev tooling is installed as Composer dev dependencies (PHPStan, php-cs-fixer, phpunit, phpbench, Zephir).
- PHP **8.1+** (CI matrix is 8.1 → 8.5). `composer.json` declares `>=8.1`.
- Dev tooling is installed as Composer dev dependencies (php-cs-fixer, phpunit, phpbench, Zephir).
- Compiling the extension additionally needs a C compiler, GFortran, `phpize`, OpenBLAS dev headers, LAPACKE, and re2c (see README for per-OS install commands).

## Commands
Expand All @@ -29,20 +29,18 @@ All are Composer scripts (see `composer.json`):
| --- | --- |
| Install deps | `composer install` |
| Validate manifest | `composer validate` |
| Static analysis | `composer analyze` (PHPStan level 8 over `tests`, `benchmarks`) |
| Run tests | `composer test` (PHPUnit, test suite `Base`; requires the extension to be loaded) |
| Check style | `composer check` (php-cs-fixer, dry-run; sets `PHP_CS_FIXER_IGNORE_ENV=1`) |
| Fix style | `composer fix` |
| Full build | `composer build` = validate → install → analyze → test → check |
| Benchmarks | `composer benchmark` (requires the extension to be loaded) |
| Compile extension | `composer compile` = zephir generate → `php build-ext` → zephir compile |
| Compile extension | `composer compile` = zephir generate → zephir compile |
| Clean generated extension | `composer clean` (zephir fullclean) |

**Recommended loop before submitting a change:**

```sh
composer install
composer analyze
composer test
composer fix
```
Expand All @@ -52,12 +50,11 @@ composer fix
## Conventions to follow

- **Coding style** is governed by `.php-cs-fixer.dist.php` (extends `@PSR2`). Highlights: single quotes, short array syntax, compact nullable type hints, pre-increment, ordered class elements, trimmed/multi-line phpdoc, `echo` over `print`. Rather than memorize the rule set, run `composer fix`.
- **Static analysis is required.** New code must pass PHPStan level 8 (`composer analyze`). Keep types accurate; the codebase uses docblock generics like `list<float>` and `int<0,max>`.
- **Testing guidance** (from `CONTRIBUTING.md`):
- New functionality ships with a matching unit test in `tests/`.
- Bug fixes ship with a passing test that would have reproduced the bug beforehand.
- Tests target public methods and cover edge cases / invalid input.
- **Documentation & changelog:** update docs if behavior changes, and add a `CHANGELOG.md` entry for user-facing changes.
- **Documentation:** update docs if behavior changes.
- **PHPDoc:** classes use `@category` / `@package` / `@author` blocks; methods carry param and return annotations. Use `@var list<float>` for element arrays.
- **Exceptions** are typed under `Tensor\Exceptions` (e.g. `InvalidArgumentException`, `DimensionalityMismatch`, `RuntimeException`). Use the existing ones rather than `Exception`.
- **Math is float-only.** Values stored/computed as `float`; don't introduce integer-only branches. When adding a new operation, mirror it across the `Tensor` sub-interfaces (`Arithmetic`, `Comparable`, `Algebraic`, `Trigonometric`, `Statistical`, `Special`).
Expand All @@ -70,16 +67,16 @@ Every public method a new `tensor/` class adds typically routes into the C backi
1. Update the Zephir class in `tensor/`.
2. Add/adjust the matching `optimizers/Tensor<Op>Optimizer.php` if it is a callable that the extension should route into C.
3. Ensure the underlying C implementation exists under `ext/include/*.c` and is linked (already wired in `config.json` `extra-sources`).
4. Bump the version in both `config.json` and `package.xml` if this is a released change, and record it in `CHANGELOG.md`.
4. Bump the version in both `config.json` if this is a released change, and record it in `CHANGELOG.md`.

Do **not** hand-edit the generated C in `ext/` (files like `*.dep`, `*.lo`, `*.o`, `Makefile*`, `config.h`). They are produced by `composer compile`. Hand-written logic belongs in `ext/include/*.c`.

## Working verification paths

To run the tests against the locally compiled extension, load the built shared object. For example:
An installed TEnsor extension will override any new changes. To run the tests against the locally compiled extension, load the built shared object. For example:

```sh
php -n -d extension=$PWD/ext/modules/tensor.so vendor/bin/phpunit ...
php -n -d extension=$PWD/ext/modules/tensor_ext.so extension=iconv -d extension=mbstring -d extension=tokenizer -d extension=dom -d extension=xml -d extension=ctype -d extension=xmlwriter vendor/bin/phpunit ...
```

If a system-installed `tensor` extension is already enabled, you can rely on it instead of building locally.
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Change Log

- 3.1.1
- Just triggering the first Packagist release
- 4.0.0
- Speed up `Vector::fromArray()` and `Matrix::fromArray()` by eliminating intermediate array copies

- 3.1.0
- Implemented the singular value decomposition (SVD) in the extension
Expand Down
40 changes: 40 additions & 0 deletions benchmarks/Arithmetic/ColumnVectorMatrixDivideBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Tensor\Benchmarks\Arithmetic;

use Tensor\Matrix;
use Tensor\ColumnVector;

/**
* @Groups({"Arithmetic"})
* @BeforeMethods({"setUp"})
*/
class ColumnVectorMatrixDivideBench
{
/**
* @var \Tensor\Vector
*/
protected $a;

/**
* @var Matrix
*/
protected $b;

public function setUp() : void
{
$this->a = ColumnVector::uniform(1000);

$this->b = Matrix::uniform(1000, 1000);
}

/**
* @Subject
* @Iterations(5)
* @OutputTimeUnit("seconds", precision=3)
*/
public function divide() : void
{
$this->a->divide($this->b);
}
}
40 changes: 40 additions & 0 deletions benchmarks/Arithmetic/MatrixColumnVectorDivideBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Tensor\Benchmarks\Arithmetic;

use Tensor\Matrix;
use Tensor\ColumnVector;

/**
* @Groups({"Arithmetic"})
* @BeforeMethods({"setUp"})
*/
class MatrixColumnVectorDivideBench
{
/**
* @var Matrix
*/
protected $a;

/**
* @var ColumnVector
*/
protected $b;

public function setUp() : void
{
$this->a = Matrix::uniform(1000, 1000);

$this->b = ColumnVector::uniform(1000);
}

/**
* @Subject
* @Iterations(5)
* @OutputTimeUnit("seconds", precision=3)
*/
public function divide() : void
{
$this->a->divide($this->b);
}
}
40 changes: 40 additions & 0 deletions benchmarks/Arithmetic/MatrixColumnVectorSubtractBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Tensor\Benchmarks\Arithmetic;

use Tensor\Matrix;
use Tensor\ColumnVector;

/**
* @Groups({"Arithmetic"})
* @BeforeMethods({"setUp"})
*/
class MatrixColumnVectorSubtractBench
{
/**
* @var Matrix
*/
protected $a;

/**
* @var ColumnVector
*/
protected $b;

public function setUp() : void
{
$this->a = Matrix::uniform(1000, 1000);

$this->b = ColumnVector::uniform(1000);
}

/**
* @Subject
* @Iterations(5)
* @OutputTimeUnit("seconds", precision=3)
*/
public function subtract() : void
{
$this->a->subtract($this->b);
}
}
40 changes: 40 additions & 0 deletions benchmarks/Arithmetic/MatrixVectorAddBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Tensor\Benchmarks\Arithmetic;

use Tensor\Matrix;
use Tensor\Vector;

/**
* @Groups({"Arithmetic"})
* @BeforeMethods({"setUp"})
*/
class MatrixVectorAddBench
{
/**
* @var Matrix
*/
protected $a;

/**
* @var Vector
*/
protected $b;

public function setUp() : void
{
$this->a = Matrix::uniform(1000, 1000);

$this->b = Vector::uniform(1000);
}

/**
* @Subject
* @Iterations(5)
* @OutputTimeUnit("seconds", precision=3)
*/
public function add() : void
{
$this->a->add($this->b);
}
}
40 changes: 40 additions & 0 deletions benchmarks/Arithmetic/MatrixVectorDivideBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Tensor\Benchmarks\Arithmetic;

use Tensor\Matrix;
use Tensor\Vector;

/**
* @Groups({"Arithmetic"})
* @BeforeMethods({"setUp"})
*/
class MatrixVectorDivideBench
{
/**
* @var Matrix
*/
protected $a;

/**
* @var Vector
*/
protected $b;

public function setUp() : void
{
$this->a = Matrix::uniform(1000, 1000);

$this->b = Vector::uniform(1000);
}

/**
* @Subject
* @Iterations(5)
* @OutputTimeUnit("seconds", precision=3)
*/
public function divide() : void
{
$this->a->divide($this->b);
}
}
40 changes: 40 additions & 0 deletions benchmarks/Arithmetic/VectorMatrixMultiplyBench.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Tensor\Benchmarks\Arithmetic;

use Tensor\Matrix;
use Tensor\Vector;

/**
* @Groups({"Arithmetic"})
* @BeforeMethods({"setUp"})
*/
class VectorMatrixMultiplyBench
{
/**
* @var Vector
*/
protected $a;

/**
* @var Matrix
*/
protected $b;

public function setUp() : void
{
$this->a = Vector::uniform(1000);

$this->b = Matrix::uniform(1000, 1000);
}

/**
* @Subject
* @Iterations(5)
* @OutputTimeUnit("seconds", precision=3)
*/
public function multiply() : void
{
$this->a->multiplyMatrix($this->b);
}
}
Loading
Loading