Merge branch 'master' into class

* master:
  team dmap
  update stockfish.wasm (v0.6.1, growable memory)
pull/5923/head
Thibault Duplessis 2020-01-15 19:32:52 -06:00
commit 51c02a4122
8 changed files with 55 additions and 51 deletions

View File

@ -171,7 +171,7 @@ final class TeamApi(
_ ?? {
memberRepo.remove(team.id, userId) >>
teamRepo.incMembers(team.id, -1) >>-
(cached invalidateTeamIds userId)
cached.invalidateTeamIds(userId)
}
}
@ -208,10 +208,10 @@ final class TeamApi(
cached.syncTeamIds(userId) contains teamId
def belongsTo(teamId: Team.ID, userId: User.ID): Fu[Boolean] =
cached.teamIds(userId) map (_ contains teamId)
cached.teamIds(userId) dmap (_ contains teamId)
def owns(teamId: Team.ID, userId: User.ID): Fu[Boolean] =
teamRepo ownerOf teamId map (_ has userId)
teamRepo ownerOf teamId dmap (_ has userId)
def filterExistingIds(ids: Set[String]): Fu[Set[Team.ID]] =
teamRepo.coll.distinctEasy[Team.ID, Set]("_id", $doc("_id" $in ids))

View File

@ -1,3 +1,5 @@
<meta charset="utf-8">
<pre>
<script>
function is64Bit() {
const x64 = ['x86_64', 'x86-64', 'Win64','x64', 'amd64', 'AMD64'];
@ -18,17 +20,17 @@ function wasmInfo() {
info.mvp = WebAssembly.validate(source);
if (!info.mvp) return info;
if (info.SharedArrayBuffer !== 'function') return info;
var mem = new WebAssembly.Memory({shared: true, initial: 8, maximum: 16});
info.sharedMem = mem.buffer instanceof SharedArrayBuffer;
try {
window.postMessage(new WebAssembly.Module(source), '*');
window.postMessage(mem, '*');
info.structuredCloning = 'ok';
} catch (e) {
info.structuredCloning = e.toString();
}
if (info.SharedArrayBuffer !== 'function') return info;
var mem = new WebAssembly.Memory({shared: true, initial: 8, maximum: 16});
info.sharedMem = mem.buffer instanceof SharedArrayBuffer;
try {
mem.grow(8);
info.growableMem = 'ok';
@ -89,7 +91,7 @@ function serviceWorkerInfo() {
}
var info = {
diagnosticsVersion: 4,
diagnosticsVersion: 5,
navigator: {
userAgent: navigator.userAgent,
platform: navigator.platform,
@ -109,3 +111,4 @@ var info = {
document.write(JSON.stringify(info));
</script>
</pre>

View File

@ -178,6 +178,10 @@ interface LightUser {
declare var SharedArrayBuffer: any | undefined;
declare var Atomics: any | undefined;
interface Navigator {
deviceMemory: number;
}
declare type VariantKey = 'standard' | 'chess960' | 'antichess' | 'fromPosition' | 'kingOfTheHill' | 'threeCheck' | 'atomic' | 'horde' | 'racingKings' | 'crazyhouse';
declare type Speed = 'bullet' | 'blitz' | 'classical' | 'correspondence' | 'unlimited';

View File

@ -232,7 +232,7 @@ export function view(ctrl: AnalyseCtrl): VNode {
attrs: {
type: 'range',
min: 4,
max: 10,
max: Math.floor(Math.log2(ceval.maxHashSize)),
step: 1
},
hook: rangeConfig(

View File

@ -20,40 +20,25 @@ function officialStockfish(variant: VariantKey): boolean {
return variant === 'standard' || variant === 'chess960';
}
function is64Bit(): boolean {
const x64 = ['x86_64', 'x86-64', 'Win64','x64', 'amd64', 'AMD64'];
for (const substr of x64) if (navigator.userAgent.includes(substr)) return true;
return navigator.platform === 'Linux x86_64' || navigator.platform === 'MacIntel';
}
function wasmThreadsSupported() {
// In theory 32 bit should be supported just the same, but some 32 bit
// browser builds seem to crash when running WASMX. So for now detect and
// require a 64 bit platform.
if (!is64Bit()) return false;
// WebAssembly 1.0
const source = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00);
if (typeof WebAssembly !== 'object' || !WebAssembly.validate(source)) return false;
function sharedWasmMemory(initial: number, maximum: number): WebAssembly.Memory | undefined {
// Atomics
if (typeof Atomics !== 'object') return;
// SharedArrayBuffer
if (typeof SharedArrayBuffer !== 'function') return false;
// Atomics
if (typeof Atomics !== 'object') return false;
if (typeof SharedArrayBuffer !== 'function') return;
// Shared memory
const mem = new WebAssembly.Memory({shared: true, initial: 8, maximum: 8} as WebAssembly.MemoryDescriptor);
if (!(mem.buffer instanceof SharedArrayBuffer)) return false;
const mem = new WebAssembly.Memory({shared: true, initial, maximum} as WebAssembly.MemoryDescriptor);
if (!(mem.buffer instanceof SharedArrayBuffer)) return;
// Structured cloning
try {
window.postMessage(mem, '*');
} catch (e) {
return false;
return;
}
return true;
return mem;
}
function median(values: number[]): number {
@ -67,17 +52,32 @@ export default function(opts: CevalOpts): CevalCtrl {
return opts.storageKeyPrefix ? `${opts.storageKeyPrefix}.${k}` : k;
};
// select wasmx > wasm > asmjs
// select wasmx with growable shared mem > wasmx > wasm > asmjs
let technology: CevalTechnology = 'asmjs';
let growableSharedMem = false;
if (typeof WebAssembly === 'object' && WebAssembly.validate(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00))) {
technology = 'wasm';
if (officialStockfish(opts.variant.key) && wasmThreadsSupported()) technology = 'wasmx';
technology = 'wasm'; // WebAssembly 1.0
if (officialStockfish(opts.variant.key)) {
const sharedMem = sharedWasmMemory(8, 16);
if (sharedMem) {
technology = 'wasmx';
try {
sharedMem.grow(8);
growableSharedMem = true;
} catch (e) { }
}
}
}
const maxThreads = Math.min(Math.max((navigator.hardwareConcurrency || 1) - 1, 1), growableSharedMem ? 16 : 2);
const threads = storedProp(storageKey('ceval.threads'), Math.min(Math.ceil((navigator.hardwareConcurrency || 1) / 4), maxThreads));
const maxHashSize = Math.min((navigator.deviceMemory || 0.25) * 1024 / 8, growableSharedMem ? 1024 : 16);
const hashSize = storedProp(storageKey('ceval.hash-size'), 16);
const minDepth = 6;
const maxDepth = storedProp<number>(storageKey('ceval.max-depth'), 18);
const multiPv = storedProp(storageKey('ceval.multipv'), opts.multiPvDefault || 1);
const hashSize = storedProp(storageKey('ceval.hash-size'), 128);
const infinite = storedProp('ceval.infinite', false);
let curEval: Tree.ClientEval | null = null;
const enableStorage = li.storage.makeBoolean(storageKey('client-eval-enabled'));
@ -88,11 +88,6 @@ export default function(opts: CevalOpts): CevalCtrl {
const hovering = prop<Hovering | null>(null);
const isDeeper = prop(false);
const maxThreads = Math.min(
Math.max((navigator.hardwareConcurrency || 1) - 1, 1),
technology == 'wasmx' ? 4 : 512); // wasm limitations: https://github.com/niklasf/stockfish.wasm/issues/4
const threads = storedProp(storageKey('ceval.threads'), Math.min(Math.ceil((navigator.hardwareConcurrency || 1) / 2), maxThreads));
const pool = new Pool({
technology,
asmjs: 'vendor/stockfish.js/stockfish.js',
@ -101,8 +96,8 @@ export default function(opts: CevalOpts): CevalCtrl {
}, {
minDepth,
variant: opts.variant.key,
threads: technology == 'wasmx' && threads,
hashSize: false && hashSize,
threads: technology == 'wasmx' && (() => Math.min(parseInt(threads()), maxThreads)),
hashSize: technology == 'wasmx' && (() => Math.min(parseInt(hashSize()), maxHashSize)),
});
// adjusts maxDepth based on nodes per second
@ -237,9 +232,10 @@ export default function(opts: CevalOpts): CevalCtrl {
possible: opts.possible,
enabled,
multiPv,
threads: (technology == 'wasmx') ? threads : undefined,
hashSize: undefined,
threads: technology == 'wasmx' ? threads : undefined,
hashSize: technology == 'wasmx' ? hashSize : undefined,
maxThreads,
maxHashSize,
infinite,
hovering,
setHovering(fen: Fen, uci?: Uci) {

View File

@ -73,6 +73,7 @@ export interface CevalCtrl {
threads: StoredProp<number> | undefined;
hashSize: StoredProp<number> | undefined;
maxThreads: number;
maxHashSize: number;
infinite: StoredBooleanProp;
hovering: Prop<Hovering | null>;
toggle(): void;

View File

@ -24,7 +24,7 @@
"dependencies": {
"stockfish-mv.wasm": "^0.2.0",
"stockfish.js": "^10.0.2",
"stockfish.wasm": "^0.5.12",
"stockfish.wasm": "^0.6.1",
"tablesort": "^5.1"
}
}

View File

@ -4322,10 +4322,10 @@ stockfish.js@^10.0.2:
resolved "https://registry.yarnpkg.com/stockfish.js/-/stockfish.js-10.0.2.tgz#c8206aa3b0290171ace52b463a74112ea1f83989"
integrity sha512-treB3AYcdvRJ9SDPOyL0R2NcEAtQgG432nStfRzR4wzVELGQ6iVoeBHwvirHTfocNOTims7XNkK3SADaocsJmQ==
stockfish.wasm@^0.5.12:
version "0.5.12"
resolved "https://registry.yarnpkg.com/stockfish.wasm/-/stockfish.wasm-0.5.12.tgz#b499c7df995ab0ef01ed6d7c30cb014711e39f74"
integrity sha512-/WZ6tR0shvoNJKQgsZMvc2aWl5sL2PKGtEvw0uzpwDphs+n00ourMDgGxqUo/VEhczPiTAVzEdq3fQz5rJk7Mg==
stockfish.wasm@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/stockfish.wasm/-/stockfish.wasm-0.6.1.tgz#6cba8121a2631bcda6355f6a2dad022934abb430"
integrity sha512-n8tTe0IEAHxcPHLNR0B14oMtZ+X4Sgy4C+U5/J7ITkOT8mvR65HlHcqBT5+qPCKQJzTfreby9d/rLKA8eiEsfQ==
stream-browserify@^2.0.0:
version "2.0.2"