Merge branch 'master' into class
* master: team dmap update stockfish.wasm (v0.6.1, growable memory)pull/5923/head
commit
51c02a4122
|
@ -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))
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue