Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 35 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: test

on:
push:
branches: [master]
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# 18.x is the floor declared in package.json engines.node
node-version: ['18.x', '20.x', '22.x', '24.x']
name: node ${{ matrix.node-version }}
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm

- run: npm ci

- run: npm test

# NOTE: example.js is deliberately not run here. Its final step needs gpu.js,
# whose `gl` dependency is a native module requiring system GL headers on the
# runner, which makes the job fail for reasons unrelated to this package.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
coverage/
*.log
.DS_Store
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

26 changes: 19 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Matrix Log

[![test](https://github.com/gpujs/matrix-log.js/actions/workflows/test.yml/badge.svg)](https://github.com/gpujs/matrix-log.js/actions/workflows/test.yml)

A matrix log dependency utility. Useful for converting and testing algorithm behavior of CPU code to GPU code.

## Why?
Expand All @@ -17,9 +19,16 @@ Don't understand?
2. Think of the Leonardo 2's cannons talking with each other to build up their values and how this violates the laws of physics.
3. Have eureka moment.

## Installation
```bash
npm install matrix-log.js
```

## API
```js
import * as MatrixLog from 'matrix-log';
const MatrixLog = require('matrix-log.js');
// or, from an ES module:
// import MatrixLog from 'matrix-log.js';


// create a matrix log that will have dependencies called
Expand Down Expand Up @@ -152,7 +161,7 @@ If you prefer to learn by code rather than have step by step instructions take a
for (let y = 0; y < 4; y++) {
let filterY = y < 2 ? 0 : 1;
for (let x = 0; x < 4; x++) {
let filterX = x < filter.length ? 0 : 1;
let filterX = x < 2 ? 0 : 1;
filters[filterY][filterX] += weights[y][x];
}
}
Expand Down Expand Up @@ -181,14 +190,17 @@ If you prefer to learn by code rather than have step by step instructions take a
for (let y = 0; y < 4; y++) {
let filterY = y < 2 ? 0 : 1;
for (let x = 0; x < 4; x++) {
let filterX = x < filter.length ? 0 : 1;
let filterX = x < 2 ? 0 : 1;
filters[filterY][filterX] += weights[y][x];
matrixLog
.at({ x, y })
.at({
x: filterX,
y: filterY
})
.add({
name: 'weights',
x: filterX,
y: filterY,
x,
y,
width: weights[0].length,
height: weights.length
});
Expand Down Expand Up @@ -293,7 +305,7 @@ If you prefer to learn by code rather than have step by step instructions take a
5. If we use a GPU environment, such as GPU.js, we could then then convert the kernel so that our algorithm actually works for setting the value of `filters` like this:

```js
import GPU from 'gpu.js';
import { GPU } from 'gpu.js';
const gpu = new GPU();

const filterKernel = gpu.createKernel(function(filters, weights) {
Expand Down
38 changes: 38 additions & 0 deletions __tests__/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,44 @@ describe('MatrixLog', () => {
expect(location.highY).toBe(childY);
expect(location.points[childZ][childY].indexOf(childX)).toBe(0);
});
it('can add below a child that is wider than it is tall', () => {
// regression: highY was previously compared against highX, so a child
// whose width exceeded its height never grew its lower bound and threw
const matrixLog = new MatrixLog('test-matrix', 1, 1);
matrixLog.at({ x: 0, y: 0 })
.add({
name:'child-matrix',
x: 0,
y: 3,
width: 6,
height: 2
});
const location = matrixLog.locations[0][0][0]['child-matrix'];
expect(location.lowY).toBe(0);
expect(location.highY).toBe(3);
expect(location.lowX).toBe(0);
expect(location.highX).toBe(5);
expect(location.points[0][3].indexOf(0)).toBe(0);
});
it('can add repeatedly above a child without losing points', () => {
// regression: only the call that extended a bound created its row, so a
// second point on an already extended row threw
const matrixLog = new MatrixLog('test-matrix', 1, 1);
const child = {
name:'child-matrix',
width: 2,
height: 6
};
matrixLog.at({ x: 0, y: 0 })
.add(Object.assign({}, child, { x: 0, y: -3 }))
.add(Object.assign({}, child, { x: 1, y: -2 }))
.add(Object.assign({}, child, { x: 0, y: -2 }));
const location = matrixLog.locations[0][0][0]['child-matrix'];
expect(location.lowY).toBe(-3);
expect(location.highY).toBe(5);
expect(location.points[0][-3]).toEqual([0]);
expect(location.points[0][-2]).toEqual([1, 0]);
});
});
describe('.toString()', () => {
it('repeats for every point logged', () => {
Expand Down
5 changes: 3 additions & 2 deletions example.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const targetValue = step1CPU();
assert.deepStrictEqual(step2CPUWithMatrixLog(), targetValue);
assert.deepStrictEqual(step3GPUStyleLoops(), targetValue);
assert.deepStrictEqual(step4GPUStyleKernel(), targetValue);
assert.deepStrictEqual(step5GPUKernel(), targetValue);
// a gpu.js kernel returns Float32Array rows, so normalise them before comparing
assert.deepStrictEqual(step5GPUKernel().map(row => Array.from(row)), targetValue);

function step1CPU() {
const filters = [
Expand Down Expand Up @@ -134,7 +135,7 @@ function step5GPUKernel() {
[0,0],
[0,0]
];
const GPU = require('gpu.js');
const { GPU } = require('gpu.js');
const gpu = new GPU();

const filterKernel = gpu.createKernel(function (filters, weights) {
Expand Down
9 changes: 6 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,8 @@ class MatrixLog {
// handle negative and positive
if (y < location.lowY) {
location.lowY = y;
points[z][y] = [];
} else if (y > location.highX) {
} else if (y > location.highY) {
location.highY = y;
points[z][y] = [];
}

if (x < location.lowX) {
Expand All @@ -107,6 +105,11 @@ class MatrixLog {
location.highX = x;
}

// rows outside the child's declared height are created on demand
if (!points[z][y]) {
points[z][y] = [];
}

points[z][y].push(x);
return this;
}
Expand Down
Loading
Loading