Skip to content

Commit

Permalink
[need squash] wip
Browse files Browse the repository at this point in the history
  • Loading branch information
axmmisaka committed Aug 20, 2023
1 parent 7413e83 commit bce6352
Show file tree
Hide file tree
Showing 6 changed files with 352 additions and 0 deletions.
64 changes: 64 additions & 0 deletions src/benchmark/sucoverrelax/actor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* eslint-disable @typescript-eslint/prefer-readonly */
// The SOR (Re)actor
import { Reactor, State } from "../../core/internal";

export class SORActor extends Reactor {
constructor(
parent: Reactor,
pos: number,
_value: number,
colour: number,
nx: number,
ny: number,
omega: number,
sorSource: Reactor,
peer: boolean
) {
super(parent, "SORActor");

const x = Math.floor(pos / ny);
const y = pos % ny;

const omegaOverFour = 0.25 * omega;
const oneMinusOmega = 1.0 - omega;

const neighbours = (() => {
const calPos = (x: number, y: number): number => (x * ny + y);

if (x > 0 && x < nx - 1 && y > 0 && y < ny - 1) {
return [calPos(x, y + 1),
calPos(x + 1, y),
calPos(x, y - 1),
calPos(x - 1, y)];
}
if ((x === 0 || x === (nx - 1)) && (y === 0 || y === (ny - 1))) {
return [
(x === 0) ? calPos(x + 1, y) : calPos(x - 1, y),
(y === 0) ? calPos(x, y + 1) : calPos(x, y - 1)
];
}
if ((x === 0 || x === (nx - 1)) || (y === 0 || y === (ny - 1))) {
if (x === 0 || x === nx - 1) {
return [
(x === 0) ? calPos(x + 1, y) : calPos(x - 1, y),
calPos(x, y + 1),
calPos(x, y - 1)
];
}
return [
(y === 0) ? calPos(x, y + 1) : calPos(x, y - 1),
calPos(x+1, y),
calPos(x-1, y)
];
}
return [];
})();
}

private iter = new State(0);
private maxIter = new State(0);
private msgRcv = new State(0);
private sorActors = new State<Reactor[]>([]);

protected
}
18 changes: 18 additions & 0 deletions src/benchmark/sucoverrelax/peer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Reactor, State } from "../../core/internal";
import { SORRunner } from "./runner";
import { SorBorder } from "./sorutils";

export class SORPeer extends Reactor {
sorActors: State<Reactor[]>;
constructor(
parent: Reactor,
s: number,
partStart: number,
matrixPart: number[][],
border: SorBorder,
sorSource: SORRunner
) {
super(parent, "SORPeer");
this.sorActors = new State([]);
}
}
82 changes: 82 additions & 0 deletions src/benchmark/sucoverrelax/runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { InMultiPort, InPort, OutMultiPort, OutPort, Parameter, Reactor, State, } from "../../core/internal";
import { SORActor } from "./actor";
import { SORPeer } from "./peer";
import { Message, SorBorder, omega } from "./sorutils";

export class SORRunner extends Reactor {
protected sorActors: State<Reactor[]>;
protected sorPeer: State<Reactor | undefined>;

protected portToSORActors: OutPort<Message>;
protected portToSORPeer: OutPort<Message>;
// Unsure if this would work, let's just try......
protected portFromSORActor: InPort<Message>;
protected portFromSORPeer: InPort<Message>;

constructor(parent: Reactor, size: number, _randoms: number[][]) {
super(parent, "SORRunner");
// These are in SorRunner;
const s = size;
// In the scala implementation a simple /2 was used.
// In JS we might need to enforce some sort of guarantee as it was used to calculate position
const part = Math.floor(s / 2);
/** These are from Savina. They should be rather irrelevant, actually. */
this.sorActors = new State([]);
this.sorPeer = new State(undefined);

/** These are the actual messaging passing mechanism that are synonomous to that of Savina. */
// This creates a bunch of ports.
this.portToSORActors = new OutPort(this);
this.portToSORPeer = new OutPort(this);

// SorRunner::boot()
this.addMutation(
[this.startup],
[this.sorActors, this.sorPeer],
function (this, sorActors, sorPeer) {
const myBorder: Reactor[] = [];
const randoms = _randoms;

// In scala, (i <- 0 until s) is loop excluding s.
const sorActorsValue = sorActors.get();
for (let i = 0; i < s; ++i) {
let c = i % 2;
for (let j = 0; j < part; ++j) {
const pos = i * (part + 1) + j;
c = 1 - c;
// We modify them in bulk, then update the state.
// Unlike in Scala we do not need to initialise the array here, JS supports sparse array.
// I have absolutely no idea why these parametres are called as such......
sorActorsValue[pos] = this.getReactor()._uncheckedAddSibling(
SORActor,
pos, randoms[i][j], c, s, part + 1, omega, this.getReactor(), false
);
// TODO: Make connections
if (j === (part - 1)) {
myBorder[i] = sorActorsValue[pos];
}

}
}
sorActors.set(sorActorsValue);

const partialMatrix: number[][] = [];
for (let i = 0; i < s; ++i) {
for (let j = 0; j < s - part; ++j) {
partialMatrix[i][j] = randoms[i][j + part];
}
}

const sorPeerValue = this.getReactor()._uncheckedAddSibling(
SORPeer,
s, part, partialMatrix, new SorBorder(myBorder),
// A dirty hack. Maybe this will be removed as ports get added.
this.getReactor() as SORRunner
);
sorPeer.set(sorPeerValue);
// TODO: Add connections.

}
);
}
}
82 changes: 82 additions & 0 deletions src/benchmark/sucoverrelax/sorutils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Reactor } from "../../core/reactor";

// Savina implementation of PRNG
export class SavinaPRNG {
private value: number;

constructor(value?: number) {
this.value = value ?? 1145141919;
}

public nextNumber(): number {
this.value = ((this.value * 1309) + 13849) & 65535;
return this.value;
}

public nextFloat(): number {
return 1.0 / (this.nextNumber() + 1);
}
}

// This is not a recommended way to use JS, but whatever......

export const refVal = [
0.000003189420084871275,
0.001846644602759566,
0.0032099996270638005,
0.0050869220175413146,
0.008496328291240363,
0.016479973604143234,
0.026575660248076397,
// This is different from the Savina one because JS doesn't have high precision
1.026575660248076,
2.026575660248076,
3.026575660248076
];

export const jacobi = 100;

export const omega = 1.25;

export function randomMatrix(m: number, n: number): number[][] {
const mat = [];
const prng = new SavinaPRNG(114514);
for (let i = 0; i < m; ++i) {
const row = [];
for (let j = 0; j < n; ++j) {
row.push(prng.nextFloat() * 1e-6);
}
mat.push(row);
}
return mat;
}

export function jgfValidate(gTotal: number, size: number): void {
const dev = Math.abs(gTotal - refVal[size]);
if (dev > 1.0e-12) {
console.log("Validation failed");
console.log(`GTotal=${gTotal}; ${refVal[size]}; ${dev}; ${size}`);
} else {
console.log("Validation OK!");
}
}

export enum MessageTypes {
sorBorderMessage,
sorStartMessage,
sorValueMessage,
sorBootMessage,
sorResuleMessage
}

export class SorBorder {
borderActors: Reactor[];
constructor(borderActors: Reactor[]) {
this.borderActors = borderActors;
}
}

export interface Message {
messageType: MessageTypes;
}

20 changes: 20 additions & 0 deletions src/benchmark/sucoverrelax/sucoverrelax.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
type WritablePort,
Parameter,
InPort,
OutPort,
State,
Action,
Reactor,
App,
TimeValue,
Origin,
Log
} from "../../core/internal";







86 changes: 86 additions & 0 deletions src/benchmark/sucoverrelax/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { App, InPort, OutPort, Reactor } from "../../core/internal";

class Master extends Reactor {
outp: OutPort<number>;

constructor(parent: Reactor, receivers: Receiver[]) {
super(parent, "");
this.outp = new OutPort(this);

this.addMutation(
[this.startup],
[this.outp],
function(this, outp) {
let i = 0;
for (const r of receivers) {
console.log(`Master: triggering ${i}`)
this.connect(outp, r.inp);
this.getReactor().writable(outp).set(i++);
this.disconnect(outp, r.inp);
}
}
);
}
}

class Receiver extends Reactor {
inp: InPort<number>;
outp: OutPort<number>;

constructor(parent: Reactor, receiver2: Receiver2) {
super(parent, "");
this.inp = new InPort(this);
this.outp = new OutPort(this);

this.addMutation(
[this.inp],
[this.inp, this.outp],
function(this, inp, outp) {
const message = inp.get();
if (message == null) {
throw Error("Receiver: Message is null.");
}
console.log(`Receiver: message ${message}. Sending.`);
this.connect(outp, receiver2.inp);
this.getReactor().writable(outp).set(message);
this.disconnect(outp, receiver2.inp);
}
);
}
}

class Receiver2 extends Reactor {
inp: InPort<number>;

constructor(parent: Reactor) {
super(parent, "");
this.inp = new InPort(this);

this.addReaction(
[this.inp],
[this.inp],
function (this, inp) {
console.log(`Receiver2: received ${inp.get()}`)
}
);
}
}

class Apppp extends App {
master: Master;
recvs: Receiver[];
recv2: Receiver2;

constructor() {
super(undefined, undefined, false, ()=>(undefined), ()=>(undefined), "");
this.recv2 = new Receiver2(this);
this.recvs = [];
for (let i = 0; i < 10; ++i) {
this.recvs.push(new Receiver(this, this.recv2));
}
this.master = new Master(this, this.recvs);
}
}

const app = new Apppp();
app._start();

0 comments on commit bce6352

Please sign in to comment.