Skip to content

Commit

Permalink
Merge pull request #45 from DatenMetzgerX/api-rework
Browse files Browse the repository at this point in the history
API Cleanup
  • Loading branch information
Micha Reiser committed Sep 19, 2016
2 parents 17e17eb + 63804ed commit b5d0089
Show file tree
Hide file tree
Showing 57 changed files with 1,013 additions and 501 deletions.
2 changes: 1 addition & 1 deletion deploy-gh-pages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ cp -r ./docs $OUT_DIR/artifacts/docs
cd $OUT_DIR
git config user.name "Travis CI"
git config user.email "$COMMIT_AUTHOR_EMAIL"
git add -N --all
git add -N *

# If there are no changes to the compiled out (e.g. this is a README update) then just bail.
if [ -z `git diff --exit-code` ]; then
Expand Down
23 changes: 7 additions & 16 deletions example/browser-example.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import parallel from "../src/browser/index";
import {createMandelOptions, computeMandelbrotLine} from "./mandelbrot";
import {parallelMandelbrot, syncMandelbrot, createMandelOptions} from "./mandelbrot";
import {syncMonteCarlo, parallelMonteCarlo, IProjectResult} from "./monte-carlo";
import {syncKnightTours, parallelKnightTours} from "./knights-tour";

Expand Down Expand Up @@ -43,31 +42,23 @@ document.querySelector("#mandelbrot-run-async").addEventListener("click", functi
const maxValuesPerTask = parseInt((document.querySelector("#mandelbrot-values-per-task") as HTMLInputElement).value, 10);

console.time("mandelbrot-async");
parallel
.range(0, mandelbrotOptions.imageHeight, 1, { maxValuesPerTask })
.environment(mandelbrotOptions)
.map(computeMandelbrotLine)
.result()
parallelMandelbrot(mandelbrotOptions, { maxValuesPerTask })
.subscribe((lines, index, blockSize) => {
for (let i = 0; i < lines.length; ++i) {
mandelbrotContext!.putImageData(new ImageData(lines[i], mandelbrotOptions.imageWidth, 1), 0, index * blockSize + i);
mandelbrotContext!.putImageData(new ImageData(lines[i], mandelbrotCanvas.width, 1), 0, index * blockSize + i);
}
})
.then(() => console.timeEnd("mandelbrot-async"), reason => console.error(reason));
});

document.querySelector("#mandelbrot-run-sync").addEventListener("click", function () {
const canvas = document.querySelector("#mandelbrot-canvas") as HTMLCanvasElement;
const context = canvas.getContext("2d");

context!.putImageData(context!.createImageData(canvas.width, canvas.height), 0, 0);
mandelbrotContext!.putImageData(mandelbrotContext!.createImageData(mandelbrotCanvas.width, mandelbrotCanvas.height), 0, 0);

setTimeout(() => {
console.time("mandelbrot-sync");
for (let y = 0; y < mandelbrotOptions.imageHeight; ++y) {
const line = computeMandelbrotLine(y, mandelbrotOptions);
context!.putImageData(new ImageData(line, mandelbrotOptions.imageWidth, 1), 0, y);
}
syncMandelbrot(mandelbrotOptions, function (line, y) {
mandelbrotContext!.putImageData(new ImageData(line, mandelbrotCanvas.width, 1), 0, y);
});
console.timeEnd("mandelbrot-sync");
}, 0);

Expand Down
43 changes: 7 additions & 36 deletions example/knights-tour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@ export interface ICoordinate {
readonly y: number;
}

type IPath = ICoordinate[];

export interface IKnightTourEnvironment {
boardSize: number;
board: number[];
}

function createEnvironment({ boardSize }: { boardSize: number }): IKnightTourEnvironment {
function createEnvironment(boardSize: number): IKnightTourEnvironment {
const board: number[] = new Array(boardSize * boardSize);
board.fill(0);
return {
Expand Down Expand Up @@ -72,22 +70,22 @@ export function knightTours(startPath: ICoordinate[], { board, boardSize }: IKni
}

export function syncKnightTours(start: ICoordinate, boardSize: number): number {
const environment = createEnvironment({ boardSize });
const environment = createEnvironment(boardSize);
return knightTours([start], environment);
}

export function parallelKnightTours(start: ICoordinate, boardSize: number, options?: IParallelOptions): PromiseLike<number> {

function successors(coordinate: ICoordinate) {
const moves = [
{ x: -2, y: -1 }, { x: -2, y: 1}, { x: -1, y: -2 }, { x: -1, y: 2 },
{ x: 1, y: -2 }, { x: 1, y: 2}, { x: 2, y: -1 }, { x: 2, y: 1 }
{x: -2, y: -1}, {x: -2, y: 1}, {x: -1, y: -2}, {x: -1, y: 2},
{x: 1, y: -2}, {x: 1, y: 2}, {x: 2, y: -1}, {x: 2, y: 1}
];
const result: ICoordinate[] = [];

for (const move of moves) {
const successor = { x: coordinate.x + move.x, y: coordinate.y + move.y };
const accessible = successor.x >= 0 && successor.y >= 0 && successor.x < boardSize && successor.y < boardSize &&
const successor = {x: coordinate.x + move.x, y: coordinate.y + move.y};
const accessible = successor.x >= 0 && successor.y >= 0 && successor.x < boardSize && successor.y < boardSize &&
(successor.x !== start.x || successor.y !== start.y) && (successor.x !== coordinate.x && successor.y !== coordinate.y);
if (accessible) {
result.push(successor);
Expand All @@ -111,8 +109,7 @@ export function parallelKnightTours(start: ICoordinate, boardSize: number, optio
let startTime = performance.now();
return parallel
.from(computeStartFields(), options)
.environment({ boardSize })
.initializer(createEnvironment)
.inEnvironment(createEnvironment, boardSize)
.map(knightTours)
.reduce(0, (memo, count) => memo + count)
.subscribe(subResults => {
Expand All @@ -123,29 +120,3 @@ export function parallelKnightTours(start: ICoordinate, boardSize: number, optio
console.log(`${total / (performance.now() - startTime) * 1000} results per second`);
});
}

export function formatPath(path: IPath) {
return path.map(coordiante => `(${coordiante.x}, ${coordiante.y})`).join("->");
}

export function validatePath(path: IPath) {
const boardSize = Math.sqrt(path.length);
const foundCoordinates: boolean[] = new Array<boolean>(path.length);
foundCoordinates.fill(false);

for (let i = 0; i < path.length; ++i) {
const coordinate = path[i];
const position = coordinate.x * boardSize + coordinate.y;

if (foundCoordinates[position] === true) {
throw new Error(`The coordinate ${coordinate.x}, ${coordinate.y} ocuurres twice in the same path`);
}
foundCoordinates[position] = true;
}

for (let i = 0; i < foundCoordinates.length; ++i) {
if (!foundCoordinates[i]) {
throw new Error(`The coordinate ${Math.floor(i / boardSize)}, ${i % boardSize} is not part of the path`);
}
}
}
18 changes: 18 additions & 0 deletions example/mandelbrot.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import parallel from "../src/browser/index";
import {IParallelOptions} from "../src/common/parallel/parallel-options";

interface IComplexNumber {
i: number;
real: number;
Expand Down Expand Up @@ -71,3 +74,18 @@ export function computeMandelbrotLine(y: number, { min, max, scalingFactor, iter
}
return line;
}

export function parallelMandelbrot(mandelbrotOptions: IMandelbrotOptions, options?: IParallelOptions) {
return parallel
.range(0, mandelbrotOptions.imageHeight, 1, options)
.inEnvironment(mandelbrotOptions)
.map(computeMandelbrotLine)
.run();
}

export function syncMandelbrot(mandelbrotOptions: IMandelbrotOptions, callback: (line: Uint8ClampedArray, y: number) => void) {
for (let y = 0; y < mandelbrotOptions.imageHeight; ++y) {
const line = computeMandelbrotLine(y, mandelbrotOptions);
callback(line, y);
}
}
5 changes: 2 additions & 3 deletions example/monte-carlo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,7 @@ export function parallelMonteCarlo(userOptions?: IMonteCarloSimulationOptions) {
const options = initializeOptions(userOptions);
return parallel
.from(options.projects)
.environment(options)
.initializer(createMonteCarloEnvironment)
.inEnvironment(createMonteCarloEnvironment, options)
.map(calculateProject)
.result();
.run();
}
31 changes: 8 additions & 23 deletions example/performance-measurement.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,11 @@
import {computeMandelbrotLine, createMandelOptions, IMandelbrotOptions} from "./mandelbrot";
import parallel from "../src/browser/index";
import {
IMonteCarloSimulationOptions, syncMonteCarlo, parallelMonteCarlo,
IProject
} from "./monte-carlo";
import { createMandelOptions, IMandelbrotOptions, parallelMandelbrot, syncMandelbrot } from "./mandelbrot";
import { IMonteCarloSimulationOptions, syncMonteCarlo, parallelMonteCarlo, IProject } from "./monte-carlo";
import {syncKnightTours, parallelKnightTours} from "./knights-tour";
const runButton = document.querySelector("#run") as HTMLInputElement;
const outputTable = document.querySelector("#output-table") as HTMLTableElement;

const iterations = 10;

function measureParallelMandelbrot(options: IMandelbrotOptions, maxValuesPerTask?: number) {
const start = performance.now();
return parallel
.range(0, options.imageHeight, 1, { maxValuesPerTask })
.environment(options)
.map(computeMandelbrotLine)
.result()
.then(() => {
const end = performance.now();
return end - start;
});
}

interface IPerformanceMeasurement {
title: string;
func: () => PromiseLike<number>;
Expand All @@ -34,7 +17,11 @@ function createParallelMandelbrotMeasurements(mandelbrotOptions: IMandelbrotOpti
result.push({
title: `Mandelbrot ${mandelbrotOptions.imageWidth}x${mandelbrotOptions.imageHeight}, ${mandelbrotOptions.iterations} parallel (${maxValuesPerTask})`,
func() {
return measureParallelMandelbrot(mandelbrotOptions, maxValuesPerTask);
const start = performance.now();
return parallelMandelbrot(mandelbrotOptions, { maxValuesPerTask }).then(() => {
const end = performance.now();
return end - start;
});
}
});
}
Expand Down Expand Up @@ -134,9 +121,7 @@ function createExamples(): IPerformanceMeasurement[] {
func(): PromiseLike<number> {
const start = performance.now();

for (let y = 0; y < mandelbrotOptions.imageHeight; ++y) {
computeMandelbrotLine(y, mandelbrotOptions);
}
syncMandelbrot(mandelbrotOptions, () => undefined);

const end = performance.now();
return Promise.resolve(end - start);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "parallel.es",
"version": "1.0.0",
"description": "Simple parallelization for ES",
"description": "Simple parallelization for EcmaScript",
"main": "index.js",
"browser": "./dist/browser-es5-commonjs.parallel-es.js",
"scripts": {
Expand Down
18 changes: 9 additions & 9 deletions src/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
*/ /** */

import {parallelFactory} from "../common/parallel/parallel-impl";
import {FunctionRegistry} from "../common/serialization/function-registry";
import {FunctionRegistry} from "../common/function/function-registry";
import {DefaultThreadPool} from "../common/thread-pool/default-thread-pool";
import {BrowserWorkerThreadFactory} from "./worker/browser-worker-thread-factory";
import {DefaultParallelScheduler} from "../common/parallel/default-parallel-scheduler";
import {IParallel} from "../common/parallel";

export {ITaskDefinition} from "../common/task/task-definition";
export {ITask} from "../common/task/task";
export {IFunctionDefinition} from "../common/worker/function-defintion";
export {ISerializedFunctionCall, isSerializedFunctionCall} from "../common/serialization/serialized-function-call";
export {IFunctionDefinition} from "../common/function/function-defintion";
export {FunctionCall} from "../common/function/function-call";
export {ISerializedFunctionCall, isSerializedFunctionCall} from "../common/function/serialized-function-call";
export {FunctionCallSerializer} from "../common/function/function-call-serializer";
export {IThreadPool} from "../common/thread-pool/thread-pool";
export {IParallel} from "../common/parallel/parallel";
export {IParallelOptions} from "../common/parallel/parallel-options";
export {IParallelStream} from "../common/parallel/parallel-stream";
export {IParallelChain} from "../common/parallel/parallel-chain";
export {IParallelTaskEnvironment, IEmptyParallelEnvironment} from "../common/parallel/parallel-environment";
export * from "../common/parallel";

const functionLookupTable = new FunctionRegistry();
const maxConcurrencyLevel = (window.navigator as any)["hardwareConcurrency"] || 4;
Expand All @@ -27,5 +27,5 @@ const threadPool = new DefaultThreadPool(new BrowserWorkerThreadFactory(function
/**
* The global parallel instance.
*/
const parallel = parallelFactory({ threadPool, maxConcurrencyLevel });
const parallel: IParallel = parallelFactory({ maxConcurrencyLevel, scheduler: new DefaultParallelScheduler(), threadPool });
export default parallel;
4 changes: 2 additions & 2 deletions src/browser/worker-slave/browser-worker-slave-states.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {FunctionCallDeserializer} from "../../common/serialization/function-call-deserializer";
import {FunctionCallDeserializer} from "../../common/function/function-call-deserializer";
import {ITaskDefinition} from "../../common/task/task-definition";
import {IFunctionDefinition} from "../../common/worker/function-defintion";
import {IFunctionDefinition} from "../../common/function/function-defintion";
import {
functionExecutionError, isFunctionResponse, isInitializeMessage, isScheduleTask, requestFunctionMessage,
workerResultMessage } from "../../common/worker/worker-messages";
Expand Down
2 changes: 1 addition & 1 deletion src/browser/worker-slave/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ParallelWorkerFunctions} from "../../common/parallel/parallel-worker-functions";
import {staticFunctionRegistry} from "../../common/serialization/static-function-registry";
import {staticFunctionRegistry} from "../../common/function/static-function-registry";
import {BrowserWorkerSlave} from "./browser-worker-slave";

staticFunctionRegistry.registerStaticFunctions(ParallelWorkerFunctions);
Expand Down
6 changes: 3 additions & 3 deletions src/browser/worker-slave/slave-function-cache.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {IFunctionLookupTable} from "../../common/serialization/function-lookup-table";
import {staticFunctionRegistry} from "../../common/serialization/static-function-registry";
import {IFunctionDefinition} from "../../common/worker/function-defintion";
import {IFunctionLookupTable} from "../../common/function/function-lookup-table";
import {staticFunctionRegistry} from "../../common/function/static-function-registry";
import {IFunctionDefinition} from "../../common/function/function-defintion";

/**
* Cache used by each {@link BrowserWorkerSlave} to cache the received functions.
Expand Down
2 changes: 1 addition & 1 deletion src/browser/worker/browser-worker-thread-factory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {IWorkerThreadFactory} from "../../common/worker/worker-thread-factory";
import {IWorkerThread} from "../../common/worker/worker-thread";
import {BrowserWorkerThread} from "./browser-worker-thread";
import {FunctionRegistry} from "../../common/serialization/function-registry";
import {FunctionRegistry} from "../../common/function/function-registry";

declare function require(module: string): any;
/* tslint:disable:no-var-requires */
Expand Down
2 changes: 1 addition & 1 deletion src/browser/worker/browser-worker-thread-state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {isFunctionRequest, IFunctionRequest, functionResponseMessage, isWorkerResult, isFunctionExecutionError} from "../../common/worker/worker-messages";
import {FunctionRegistry} from "../../common/serialization/function-registry";
import {FunctionRegistry} from "../../common/function/function-registry";

/**
* State of the browser worker thread
Expand Down
2 changes: 1 addition & 1 deletion src/browser/worker/browser-worker-thread.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {FunctionRegistry} from "../../common/serialization/function-registry";
import {FunctionRegistry} from "../../common/function/function-registry";
import {ITaskDefinition} from "../../common/task/task-definition";
import {initializeWorkerMessage, IWorkerMessage, stopMessage, scheduleTaskMessage} from "../../common/worker/worker-messages";
import {IWorkerThread} from "../../common/worker/worker-thread";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* @module parallel
*/
/** */

import {ISerializedFunctionCall} from "./serialized-function-call";
import {FunctionRegistry} from "./function-registry";

Expand Down

0 comments on commit b5d0089

Please sign in to comment.