Skip to content

Commit cc9a45a

Browse files
committed
feat : add user input engineWorkersNb
1 parent 8af6194 commit cc9a45a

8 files changed

Lines changed: 68 additions & 14 deletions

File tree

src/constants.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,42 @@ export const STRONGEST_ENGINE: EngineName = EngineName.Stockfish17;
1818

1919
export const ENGINE_LABELS: Record<
2020
EngineName,
21-
{ small: string; full: string }
21+
{ small: string; full: string; sizeMb: number }
2222
> = {
2323
[EngineName.Stockfish17]: {
2424
full: "Stockfish 17 (75MB)",
2525
small: "Stockfish 17",
26+
sizeMb: 75,
2627
},
2728
[EngineName.Stockfish17Lite]: {
2829
full: "Stockfish 17 Lite (6MB)",
2930
small: "Stockfish 17 Lite",
31+
sizeMb: 6,
3032
},
3133
[EngineName.Stockfish16_1]: {
3234
full: "Stockfish 16.1 (64MB)",
3335
small: "Stockfish 16.1",
36+
sizeMb: 64,
3437
},
3538
[EngineName.Stockfish16_1Lite]: {
3639
full: "Stockfish 16.1 Lite (6MB)",
3740
small: "Stockfish 16.1 Lite",
41+
sizeMb: 6,
3842
},
3943
[EngineName.Stockfish16NNUE]: {
4044
full: "Stockfish 16 (40MB)",
4145
small: "Stockfish 16",
46+
sizeMb: 40,
4247
},
4348
[EngineName.Stockfish16]: {
4449
full: "Stockfish 16 Lite (HCE)",
4550
small: "Stockfish 16 Lite",
51+
sizeMb: 2,
4652
},
4753
[EngineName.Stockfish11]: {
4854
full: "Stockfish 11 (HCE)",
4955
small: "Stockfish 11",
56+
sizeMb: 2,
5057
},
5158
};
5259

src/lib/engine/shared.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@ export const isWasmSupported = () =>
1212

1313
export const isMultiThreadSupported = () => {
1414
try {
15-
return SharedArrayBuffer !== undefined;
15+
return SharedArrayBuffer !== undefined && !isIosDevice();
1616
} catch {
1717
return false;
1818
}
1919
};
2020

21+
export const isIosDevice = () => /iPhone|iPad|iPod/i.test(navigator.userAgent);
22+
23+
export const isMobileDevice = () =>
24+
isIosDevice() || /Android|Opera Mini/i.test(navigator.userAgent);
25+
2126
export const isEngineSupported = (name: EngineName): boolean => {
2227
switch (name) {
2328
case EngineName.Stockfish17:

src/lib/engine/uciEngine.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ export class UciEngine {
4949
await engine.addNewWorker();
5050
engine.isReady = true;
5151

52-
console.log(`${engineName} initialized`);
5352
return engine;
5453
}
5554

@@ -138,11 +137,11 @@ export class UciEngine {
138137
for (const worker of this.workers) {
139138
this.terminateWorker(worker);
140139
}
141-
142-
console.log(`${this.name} shutdown`);
140+
this.workers = [];
143141
}
144142

145143
private terminateWorker(worker: EngineWorker) {
144+
console.log(`Terminating worker from ${this.enginePath}`);
146145
worker.uci("quit");
147146
worker.terminate?.();
148147
worker.isReady = false;

src/lib/engine/worker.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { EngineWorker } from "@/types/engine";
2+
import { isIosDevice, isMobileDevice } from "./shared";
23

34
export const getEngineWorker = (enginePath: string): EngineWorker => {
45
console.log(`Creating worker from ${enginePath}`);
@@ -47,13 +48,19 @@ export const getRecommendedWorkersNb = (): number => {
4748
const maxWorkersNbFromThreads = Math.max(
4849
1,
4950
navigator.hardwareConcurrency - 4,
50-
Math.ceil((navigator.hardwareConcurrency * 2) / 3)
51+
Math.floor((navigator.hardwareConcurrency * 2) / 3)
5152
);
5253

5354
const maxWorkersNbFromMemory =
5455
"deviceMemory" in navigator && typeof navigator.deviceMemory === "number"
5556
? navigator.deviceMemory
5657
: 4;
5758

58-
return Math.min(maxWorkersNbFromThreads, maxWorkersNbFromMemory, 10);
59+
const maxWorkersNbFromDevice = isIosDevice() ? 2 : isMobileDevice() ? 4 : 10;
60+
61+
return Math.min(
62+
maxWorkersNbFromThreads,
63+
maxWorkersNbFromMemory,
64+
maxWorkersNbFromDevice
65+
);
5966
};

src/sections/analysis/panelHeader/analyzeButton.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
engineDepthAtom,
44
engineMultiPvAtom,
55
engineNameAtom,
6+
engineWorkersNbAtom,
67
evaluationProgressAtom,
78
gameAtom,
89
gameEvalAtom,
@@ -19,12 +20,12 @@ import { useEffect, useCallback } from "react";
1920
import { usePlayersData } from "@/hooks/usePlayersData";
2021
import { Typography } from "@mui/material";
2122
import { useCurrentPosition } from "../hooks/useCurrentPosition";
22-
import { getRecommendedWorkersNb } from "@/lib/engine/worker";
2323

2424
export default function AnalyzeButton() {
2525
const engineName = useAtomValue(engineNameAtom);
2626
const engine = useEngine(engineName);
2727
useCurrentPosition(engine);
28+
const engineWorkersNb = useAtomValue(engineWorkersNbAtom);
2829
const [evaluationProgress, setEvaluationProgress] = useAtom(
2930
evaluationProgressAtom
3031
);
@@ -58,7 +59,7 @@ export default function AnalyzeButton() {
5859
white: white?.rating,
5960
black: black?.rating,
6061
},
61-
workersNb: getRecommendedWorkersNb(),
62+
workersNb: engineWorkersNb,
6263
});
6364

6465
setEval(newGameEval);
@@ -86,6 +87,7 @@ export default function AnalyzeButton() {
8687
}, [
8788
engine,
8889
engineName,
90+
engineWorkersNb,
8991
game,
9092
engineDepth,
9193
engineMultiPv,

src/sections/analysis/states.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { DEFAULT_ENGINE } from "@/constants";
2+
import { getRecommendedWorkersNb } from "@/lib/engine/worker";
23
import { EngineName } from "@/types/enums";
34
import { CurrentPosition, GameEval, SavedEvals } from "@/types/eval";
45
import { Chess } from "chess.js";
56
import { atom } from "jotai";
7+
import { atomWithStorage } from "jotai/utils";
68

79
export const gameEvalAtom = atom<GameEval | undefined>(undefined);
810
export const gameAtom = atom(new Chess());
@@ -16,6 +18,10 @@ export const showPlayerMoveIconAtom = atom(true);
1618
export const engineNameAtom = atom<EngineName>(DEFAULT_ENGINE);
1719
export const engineDepthAtom = atom(14);
1820
export const engineMultiPvAtom = atom(3);
21+
export const engineWorkersNbAtom = atomWithStorage(
22+
"engineWorkersNb",
23+
getRecommendedWorkersNb()
24+
);
1925
export const evaluationProgressAtom = atom(0);
2026

2127
export const savedEvalsAtom = atom<SavedEvals>({});

src/sections/engineSettings/engineSettingsDialog.tsx

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
engineNameAtom,
2121
engineDepthAtom,
2222
engineMultiPvAtom,
23+
engineWorkersNbAtom,
2324
} from "../analysis/states";
2425
import ArrowOptions from "./arrowOptions";
2526
import { useAtomLocalStorage } from "@/hooks/useAtomLocalStorage";
@@ -35,6 +36,7 @@ import {
3536
PIECE_SETS,
3637
STRONGEST_ENGINE,
3738
} from "@/constants";
39+
import { getRecommendedWorkersNb } from "@/lib/engine/worker";
3840

3941
interface Props {
4042
open: boolean;
@@ -56,6 +58,7 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
5658
);
5759
const [boardHue, setBoardHue] = useAtom(boardHueAtom);
5860
const [pieceSet, setPieceSet] = useAtom(pieceSetAtom);
61+
const [engineWorkersNb, setEngineWorkersNb] = useAtom(engineWorkersNbAtom);
5962

6063
const theme = useTheme();
6164
const isDarkMode = theme.palette.mode === "dark";
@@ -72,12 +75,15 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
7275

7376
return (
7477
<Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
75-
<DialogTitle variant="h5">Settings</DialogTitle>
78+
<DialogTitle variant="h5" sx={{ paddingBottom: 1 }}>
79+
Settings
80+
</DialogTitle>
7681
<DialogContent sx={{ paddingBottom: 0 }}>
7782
<Grid
7883
container
7984
justifyContent="center"
8085
alignItems="center"
86+
paddingTop={1}
8187
spacing={3}
8288
size={12}
8389
>
@@ -86,12 +92,14 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
8692
justifyContent="center"
8793
size={{ xs: 12, sm: 7, md: 8 }}
8894
>
89-
<Typography>
95+
<Typography variant="body2">
9096
{ENGINE_LABELS[DEFAULT_ENGINE].small} is the default engine if
9197
your device support its requirements. It offers the best balance
9298
between speed and strength.{" "}
9399
{ENGINE_LABELS[STRONGEST_ENGINE].small} is the strongest engine
94-
available, note that it requires a one time download of 75MB.
100+
available, note that it requires a one time download of{" "}
101+
{ENGINE_LABELS[STRONGEST_ENGINE].sizeMb}MB and is much more
102+
compute intensive.
95103
</Typography>
96104
</Grid>
97105

@@ -162,6 +170,7 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
162170
<Grid
163171
container
164172
justifyContent="center"
173+
alignItems="center"
165174
size={{ xs: 12, sm: 4, md: 3 }}
166175
>
167176
<FormControl variant="outlined">
@@ -194,6 +203,26 @@ export default function EngineSettingsDialog({ open, onClose }: Props) {
194203
</Select>
195204
</FormControl>
196205
</Grid>
206+
207+
<Grid container justifyContent="center" size={{ xs: 12, sm: 7 }}>
208+
<Slider
209+
label="Number of threads"
210+
value={engineWorkersNb}
211+
setValue={setEngineWorkersNb}
212+
min={1}
213+
max={10}
214+
marksFilter={1}
215+
/>
216+
</Grid>
217+
218+
<Grid container justifyContent="center" size={{ xs: 12, sm: 5 }}>
219+
<Typography variant="body2">
220+
More threads means quicker analysis but only if your device can
221+
handle them, otherwise it may have the opposite effect. The
222+
estimated best value for your device is{" "}
223+
{getRecommendedWorkersNb()}.
224+
</Typography>
225+
</Grid>
197226
</Grid>
198227
</DialogContent>
199228
<DialogActions sx={{ m: 1 }}>

src/types/engine.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ export interface EngineWorker {
22
isReady: boolean;
33
uci(command: string): void;
44
listen: (data: string) => void;
5-
terminate?: () => void;
6-
setNnueBuffer?: (data: Uint8Array, index?: number) => void;
5+
terminate: () => void;
76
}
87

98
export interface WorkerJob {

0 commit comments

Comments
 (0)