Intel Arc in the app (0.3.20): vendor intel from the OpenCL vendor string and the Windows name, the INTEL badge and its token, the no-cap row naming IGCL, the measure-only tune words, the view test and the ui-mock scenario (the six app files of intel-arc 18453bb1, applied as its own diff; the test's prove sentence in this tree's wording)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
5bd64245d0
commit
b95a8e3ca9
6 changed files with 97 additions and 5 deletions
|
|
@ -111,8 +111,11 @@ fn card(index: usize, name: &str, vendor: &str, worker: &str, detail: &str, devi
|
|||
/// CL_DEVICE_NAME: PC 1's Ryzen iGPU is "gfx1036", 5 October 2026).
|
||||
pub fn looks_integrated(name: &str) -> bool {
|
||||
let n = name.to_ascii_lowercase();
|
||||
if n.contains("arc") && n.contains("intel") {
|
||||
return arc_is_integrated(&n);
|
||||
}
|
||||
let integrated = ["radeon(tm) graphics", "radeon graphics", "vega 8", "vega 7", "vega 6", "vega 3", "vega 11", "iris", "uhd graphics", "hd graphics", "intel(r) graphics", "intel graphics", "apu", "780m", "760m", "680m", "610m", "890m", "880m"];
|
||||
if integrated.iter().any(|k| n.contains(k)) && !n.contains("arc ") {
|
||||
if integrated.iter().any(|k| n.contains(k)) {
|
||||
return true;
|
||||
}
|
||||
// AMD APU graphics by gfx code (approximate list from AMD's ROCm and Mesa target tables): Raven/Picasso gfx902 and
|
||||
|
|
@ -123,6 +126,22 @@ pub fn looks_integrated(name: &str) -> bool {
|
|||
apu.iter().any(|k| code == *k || code.starts_with(&format!("{k}:")) || code.starts_with(&format!("{k} ")))
|
||||
}
|
||||
|
||||
/// An Intel name carrying "Arc" (lower-cased): the cards ("Arc(TM) A770", "Arc(TM) B580", "Arc(TM) Pro A60") are
|
||||
/// discrete; the Arc-branded processor graphics are integrated: the bare "Intel(R) Arc(TM) Graphics" of Meteor Lake
|
||||
/// and Arrow Lake, the "Arc(TM) 130V / 140V" of Lunar Lake and the "Arc(TM) 1xxT" of Panther Lake (approximate names
|
||||
/// from Intel's product pages, 7 October 2026; the B580 is the first Intel card in hand, docs/plans/intel-arc.md).
|
||||
fn arc_is_integrated(lower: &str) -> bool {
|
||||
let after = lower.split("arc").nth(1).unwrap_or("").trim_start_matches("(tm)").trim_start_matches("(r)").trim();
|
||||
let word = after.split(|c: char| !c.is_ascii_alphanumeric()).next().unwrap_or("");
|
||||
// "graphics" or nothing after "Arc": the processor graphics; "130v", "140t": digits first, the processor graphics
|
||||
if word.is_empty() || word == "graphics" || word.starts_with(|c: char| c.is_ascii_digit()) {
|
||||
return true;
|
||||
}
|
||||
// "pro", "a770", "b580": a card. Anything else unknown is read as a card (on by default; a wrong call costs an
|
||||
// iGPU 8 identities at 1 to 2 MH/s, a card called integrated would sit off with no reason the owner can see)
|
||||
false
|
||||
}
|
||||
|
||||
/// One row of Windows' adapter list (Win32_VideoController), the part this app reads.
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
pub struct Adapter {
|
||||
|
|
@ -186,6 +205,10 @@ pub fn vendor_of(name: &str) -> &'static str {
|
|||
"amd"
|
||||
} else if n.contains("apple") {
|
||||
"apple"
|
||||
} else if n.contains("intel") {
|
||||
// Arc cards and Intel processor graphics alike (the kind tells them apart); the first Intel card is the B580
|
||||
// on PC 1, 7 October 2026 (docs/plans/intel-arc.md)
|
||||
"intel"
|
||||
} else {
|
||||
"other"
|
||||
}
|
||||
|
|
@ -440,6 +463,9 @@ impl ClDevice {
|
|||
"nvidia"
|
||||
} else if self.vendor.contains("Advanced Micro") || self.vendor.contains("AMD") || self.name.contains("Radeon") || self.name.contains("AMD") || self.name.to_ascii_lowercase().starts_with("gfx") {
|
||||
"amd"
|
||||
} else if self.vendor.contains("Intel") || self.name.contains("Intel") {
|
||||
// "Intel(R) Corporation" on the "Intel(R) OpenCL Graphics" platform (the Arc driver's runtime)
|
||||
"intel"
|
||||
} else {
|
||||
"other"
|
||||
}
|
||||
|
|
@ -809,6 +835,8 @@ mod tests {
|
|||
// the Mac: detect() labels Apple silicon "apple" itself; the name rules do not call it integrated
|
||||
assert!(!looks_integrated("Apple M5 Max"));
|
||||
assert_eq!(vendor_of("Apple M5 Max"), "apple");
|
||||
assert_eq!(vendor_of("Intel(R) Arc(TM) B580 Graphics"), "intel");
|
||||
assert_eq!(vendor_of("Intel(R) UHD Graphics 770"), "intel");
|
||||
assert_eq!(vendor_of("gfx1036"), "amd");
|
||||
assert_eq!(vendor_of("AMD Radeon RX 9070 XT"), "amd");
|
||||
assert_eq!(vendor_of("NVIDIA GeForce RTX 5090"), "nvidia");
|
||||
|
|
@ -951,6 +979,39 @@ mod tests {
|
|||
assert!(diff.removed.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// The first Intel card (the B580 on PC 1, 7 October 2026, docs/plans/intel-arc.md): the Arc driver's OpenCL
|
||||
/// platform lists it as "Intel(R) Arc(TM) B580 Graphics" under vendor "Intel(R) Corporation" (the line shape is
|
||||
/// the worker's; the device name and vendor string are Intel's documented forms, approximate until the PC 1 job
|
||||
/// prints them). It becomes a discrete 12 GB card, vendor intel, worker OpenCL, on with 8 identities; the
|
||||
/// Arc-branded processor graphics stay integrated; the NVIDIA cards beside it are untouched.
|
||||
#[test]
|
||||
fn an_intel_arc_card_on_the_intel_platform_is_a_discrete_intel_card() {
|
||||
let list = String::from(PC1_LIST)
|
||||
+ " [4] Intel(R) Arc(TM) B580 Graphics | Intel(R) OpenCL Graphics (OpenCL 3.0 )\n GPU, vendor Intel(R) Corporation, driver 32.0.101.9034, OpenCL C 3.0, 160 compute units, 2850 MHz, pci 05:00.0\n global 12208 MiB, max alloc 4095 MiB, local 64 KiB, max work-group 1024, sub-group extension: cl_intel_subgroups\n";
|
||||
let (devs, _) = parse_opencl_list(&list);
|
||||
let arc = devs.iter().find(|d| d.name.contains("B580")).expect("the Arc line parses");
|
||||
assert_eq!(arc.vendor_word(), "intel");
|
||||
assert_eq!(arc.mem_mb, 12208);
|
||||
assert_eq!(arc.bus, "05:00.0");
|
||||
let d = assemble(pc1_inputs(&list));
|
||||
let c = d.cards.iter().find(|c| c.vendor == "intel").expect("an intel card");
|
||||
assert_eq!((c.name.as_str(), c.kind.as_str(), c.worker.as_str(), c.device.as_str(), c.enabled, c.identities), ("Intel(R) Arc(TM) B580 Graphics", "discrete", "OpenCL", "4", true, 8));
|
||||
assert_eq!(c.key, "intel:Intel(R) Arc(TM) B580 Graphics");
|
||||
assert_eq!(c.vram_mb, 12208);
|
||||
assert!(!c.sweep_supported, "no cap through OpenCL");
|
||||
assert!(c.sweep_note.contains("Intel Arc"), "{}", c.sweep_note);
|
||||
assert!(d.listed(c), "the OpenCL list answered, so a vanished Arc can be called removed");
|
||||
// the Arc names: cards discrete, processor graphics integrated
|
||||
for card in ["Intel(R) Arc(TM) B580 Graphics", "Intel(R) Arc(TM) A770 Graphics", "Intel(R) Arc(TM) A380 Graphics", "Intel(R) Arc(TM) Pro A60 Graphics", "Intel(R) Arc(TM) B570 Graphics"] {
|
||||
assert_eq!(classify_kind(card, None), "discrete", "{card}");
|
||||
}
|
||||
for igpu in ["Intel(R) Arc(TM) Graphics", "Intel(R) Arc(TM) 140V GPU (16GB)", "Intel(R) Arc(TM) 130V GPU", "Intel(R) Arc(TM) 140T GPU"] {
|
||||
assert_eq!(classify_kind(igpu, None), "integrated", "{igpu}");
|
||||
}
|
||||
assert_eq!(classify_kind("Intel(R) UHD Graphics 770", None), "integrated");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keys_number_identical_cards() {
|
||||
let mut cards = vec![card(0, "NVIDIA GeForce RTX 5090", "nvidia", "CUDA", "", "0"), card(1, "NVIDIA GeForce RTX 5090", "nvidia", "CUDA", "", "1"), card(2, "gfx1201", "amd", "OpenCL", "", "2")];
|
||||
|
|
|
|||
|
|
@ -439,6 +439,9 @@ pub fn unsupported_reason(vendor: &str, power_default_w: f64, device: &str) -> O
|
|||
// Ember Tune (src/ember.rs, 5 October 2026): AMD is tuned through igneum-gpu-telemetry, Apple measures only;
|
||||
// the tune itself says which at its start (the card row's note)
|
||||
"apple" | "amd" => None,
|
||||
// the first Intel card, the B580 on PC 1 (7 October 2026, docs/plans/intel-arc.md section 2.3): OpenCL
|
||||
// exposes neither a cap nor a reading; Intel's path is IGCL (ControlLib.dll), the telemetry helper's next piece
|
||||
"intel" => Some("not available: Intel Arc exposes no power cap or reading through OpenCL (the driver's IGCL counters come next)"),
|
||||
_ => Some("not available: no power reading or cap for this card"),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
:root{
|
||||
/* colour, dark */
|
||||
--obsidian:#0C0C0E;--graphite:#16161A;--row:#111114;--line:#2A2A30;--line-2:#3A3A42;--ember:#F2541B;--ember-hi:#FF6A2B;--molten:#FFB35C;--bone:#F4F1EC;--ash:#9A9A9E;--ink-2:#C9C7C2;--ember-ink:#0C0C0E;
|
||||
--ember-12:rgba(242,84,27,.12);--ember-40:rgba(242,84,27,.4);--molten-10:rgba(255,179,92,.1);--molten-40:rgba(255,179,92,.4);--nvidia:#8BE37A;--rail-bg:#111114;--hover:rgba(255,255,255,.04);--top-bg:rgba(12,12,14,.86);--shadow:rgba(0,0,0,.6);--scrim:rgba(12,12,14,.72);--ok:#FFB35C;
|
||||
--ember-12:rgba(242,84,27,.12);--ember-40:rgba(242,84,27,.4);--molten-10:rgba(255,179,92,.1);--molten-40:rgba(255,179,92,.4);--nvidia:#8BE37A;--intel:#7CC4FF;--rail-bg:#111114;--hover:rgba(255,255,255,.04);--top-bg:rgba(12,12,14,.86);--shadow:rgba(0,0,0,.6);--scrim:rgba(12,12,14,.72);--ok:#FFB35C;
|
||||
/* type scale */
|
||||
--t-xs:11px;--t-sm:12px;--t-base:13px;--t-md:14px;--t-lg:15px;--t-xl:17px;--t-num:24px;--t-hero:34px;--t-h2:28px;--t-h1:44px;
|
||||
/* spacing scale */
|
||||
|
|
@ -29,10 +29,10 @@
|
|||
--included:#3B7DD8;--excluded:#B0362B}
|
||||
@media (prefers-color-scheme:light){:root:not([data-theme="dark"]){
|
||||
--obsidian:#F4F1EC;--graphite:#FFFFFF;--row:#FAF8F5;--line:#E2DED8;--line-2:#CFCAC2;--ember:#E04A14;--ember-hi:#F2541B;--molten:#B8731F;--bone:#16161A;--ash:#6B6B70;--ink-2:#3C3C42;--ember-ink:#FFFFFF;
|
||||
--ember-12:rgba(224,74,20,.1);--ember-40:rgba(224,74,20,.4);--molten-10:rgba(184,115,31,.1);--molten-40:rgba(184,115,31,.4);--nvidia:#3C9B2C;--rail-bg:#EFEBE4;--hover:rgba(0,0,0,.04);--top-bg:rgba(244,241,236,.88);--shadow:rgba(0,0,0,.18);--scrim:rgba(244,241,236,.72);--ok:#B8731F;--included:#2A62B8;--excluded:#B0362B}}
|
||||
--ember-12:rgba(224,74,20,.1);--ember-40:rgba(224,74,20,.4);--molten-10:rgba(184,115,31,.1);--molten-40:rgba(184,115,31,.4);--nvidia:#3C9B2C;--intel:#1C6FD6;--rail-bg:#EFEBE4;--hover:rgba(0,0,0,.04);--top-bg:rgba(244,241,236,.88);--shadow:rgba(0,0,0,.18);--scrim:rgba(244,241,236,.72);--ok:#B8731F;--included:#2A62B8;--excluded:#B0362B}}
|
||||
:root[data-theme="light"]{
|
||||
--obsidian:#F4F1EC;--graphite:#FFFFFF;--row:#FAF8F5;--line:#E2DED8;--line-2:#CFCAC2;--ember:#E04A14;--ember-hi:#F2541B;--molten:#B8731F;--bone:#16161A;--ash:#6B6B70;--ink-2:#3C3C42;--ember-ink:#FFFFFF;
|
||||
--ember-12:rgba(224,74,20,.1);--ember-40:rgba(224,74,20,.4);--molten-10:rgba(184,115,31,.1);--molten-40:rgba(184,115,31,.4);--nvidia:#3C9B2C;--rail-bg:#EFEBE4;--hover:rgba(0,0,0,.04);--top-bg:rgba(244,241,236,.88);--shadow:rgba(0,0,0,.18);--scrim:rgba(244,241,236,.72);--ok:#B8731F;--included:#2A62B8;--excluded:#B0362B}
|
||||
--ember-12:rgba(224,74,20,.1);--ember-40:rgba(224,74,20,.4);--molten-10:rgba(184,115,31,.1);--molten-40:rgba(184,115,31,.4);--nvidia:#3C9B2C;--intel:#1C6FD6;--rail-bg:#EFEBE4;--hover:rgba(0,0,0,.04);--top-bg:rgba(244,241,236,.88);--shadow:rgba(0,0,0,.18);--scrim:rgba(244,241,236,.72);--ok:#B8731F;--included:#2A62B8;--excluded:#B0362B}
|
||||
*{box-sizing:border-box}
|
||||
html,body{height:100%}
|
||||
body{margin:0;background:var(--obsidian);color:var(--bone);font-family:var(--sans);font-size:var(--t-md);line-height:1.5;-webkit-font-smoothing:antialiased;overflow:hidden;user-select:none;-webkit-user-select:none;font-variant-numeric:tabular-nums}
|
||||
|
|
@ -199,6 +199,7 @@ body[data-phase="welcome"] #screen-welcome,body[data-phase="cards"] #screen-card
|
|||
.badge.apple{color:var(--bone)}
|
||||
.badge.nvidia{color:var(--nvidia)}
|
||||
.badge.amd{color:var(--ember)}
|
||||
.badge.intel{color:var(--intel)}
|
||||
.gpu-row .info{flex:1;min-width:180px;display:flex;flex-direction:column;gap:var(--s-1)}
|
||||
.gpu-row .name{font-family:var(--head);font-weight:700;font-size:var(--t-xl);line-height:1.2;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
||||
.kind{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;border-radius:999px;padding:2px 8px;border:1px solid var(--line-2);color:var(--ash);font-weight:500;white-space:nowrap}
|
||||
|
|
|
|||
|
|
@ -354,6 +354,7 @@ var View = (function () {
|
|||
if (cd.power_w > 0 || cd.temp_gpu > 0) return '';
|
||||
if (cd.vendor === 'apple') return 'No power or temperature reading on Apple silicon';
|
||||
if (cd.kind === 'integrated') return 'No power or temperature reading on an integrated GPU';
|
||||
if (cd.vendor === 'intel') return 'No power or temperature reading on Intel Arc yet: the driver exposes them through IGCL, not OpenCL';
|
||||
return '';
|
||||
}
|
||||
// the row's cells: rate, watts with MH/W, £ a day, temperature; a cell with no number is left out, never n/a
|
||||
|
|
@ -1071,6 +1072,7 @@ var TuneLine = (function () {
|
|||
// the model: {kind: running|tuned|measured|stopped|idle|off, text, note}
|
||||
function model(cd, now) {
|
||||
cd = cd || {};
|
||||
if (cd.vendor === 'intel') return { kind: 'off', text: 'tuning: measure only on Intel Arc once a power reading exists', note: 'no cap through OpenCL; IGCL next' };
|
||||
if (cd.vendor !== 'nvidia' && cd.vendor !== 'amd' && cd.vendor !== 'apple') return { kind: 'off', text: cd.sweep_note || 'tuning: no power or clock control for this card' };
|
||||
if (cd.sweep_state === 'running') return { kind: 'running', text: cd.sweep_note || 'tuning: running' };
|
||||
var when = cd.sweep_at && now ? ', ' + rel(now - cd.sweep_at) + ' ago' : '';
|
||||
|
|
@ -1914,7 +1916,7 @@ if (typeof document !== 'undefined') (function () {
|
|||
// ---------- render ----------
|
||||
function badgeHtml(cd) {
|
||||
if (cd.vendor === 'apple') return '<svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor" aria-hidden="true"><path d="M16.4 12.6c0-2.5 2-3.6 2.1-3.7-1.2-1.7-3-1.9-3.6-2-1.5-.2-3 .9-3.8.9-.8 0-2-.9-3.3-.8-1.7 0-3.2 1-4.1 2.5-1.8 3-.5 7.6 1.3 10.1.9 1.2 1.9 2.6 3.2 2.5 1.3 0 1.8-.8 3.3-.8 1.6 0 2 .8 3.3.8 1.4 0 2.3-1.2 3.1-2.5 1-1.4 1.4-2.8 1.4-2.9 0 0-2.7-1-2.9-4.1zM13.9 5.3c.7-.8 1.2-2 1-3.2-1 0-2.2.7-2.9 1.5-.6.7-1.2 1.9-1 3 1.1.1 2.2-.5 2.9-1.3z"/></svg>';
|
||||
return cd.vendor === 'nvidia' ? 'NV' : cd.vendor === 'amd' ? 'AMD' : 'GPU';
|
||||
return cd.vendor === 'nvidia' ? 'NV' : cd.vendor === 'amd' ? 'AMD' : cd.vendor === 'intel' ? 'INTEL' : 'GPU';
|
||||
}
|
||||
function vramText(cd) { if (!cd.vram_mb) return ''; var gb = cd.vram_mb / 1024; return (gb >= 10 ? Math.round(gb) : gb.toFixed(gb < 4 ? 1 : 0)) + ' GB' + (cd.kind === 'apple' ? ' unified' : ''); }
|
||||
// ---------- the first-run GPU rows: one per card, with a switch ----------
|
||||
|
|
@ -2057,6 +2059,7 @@ if (typeof document !== 'undefined') (function () {
|
|||
'<p class="help">Lower is cooler and quieter. Most cards hash nearly as fast at 70%. ' + (cd.pinned ? 'Set by hand, so Ember leaves it. <button class="btn tiny ghost" data-pin="0">Back to Default</button>' : 'Default: Ember may move it.') + '</p></div>';
|
||||
h += cd.power_applied ? '<div class="line ok">Cap in force: <b>' + want + ' W</b>' + (cd.sweep_pct === pct && cd.sweep_pct ? ' <span class="pin">Ember’s choice</span>' : '') + '</div>' : '<div class="line hot">Cap not set yet. Windows needs the administrator prompt. <button class="btn tiny" data-power-retry="1">Retry</button></div>';
|
||||
} else if (cd.vendor === 'apple') h += '<p class="help">Apple silicon manages its own power. There is no cap to set.</p>';
|
||||
else if (cd.vendor === 'intel') h += '<p class="help">Intel Arc exposes no power cap through OpenCL; the card runs at the driver’s default limit (Intel Graphics Software can set one). No watts reading yet, so the MH/W cell stays empty until the IGCL reader lands.</p>';
|
||||
var tl = [];
|
||||
if (cd.temp_mem > 0) tl.push('memory <b>' + Math.round(cd.temp_mem) + ' °C</b>');
|
||||
if (cd.gclk_mhz > 0) tl.push('core clock <b>' + Math.round(cd.gclk_mhz) + ' MHz</b>' + (cd.clock_cap_mhz > 0 ? ' (cap ' + cd.clock_cap_mhz + ')' : ''));
|
||||
|
|
|
|||
|
|
@ -51,6 +51,23 @@ test('a GPU row: temperatures turn amber then red; unknown numbers are empty', (
|
|||
assert.equal(apple.meta, '128 GB unified');
|
||||
});
|
||||
|
||||
test('an Intel Arc card is a discrete Intel row: INTEL badge, no power reading sentence, measure-only tune words (intel-arc, 7 October 2026)', () => {
|
||||
const arc = card({ key: 'intel:Intel(R) Arc(TM) B580 Graphics', name: 'Intel(R) Arc(TM) B580 Graphics', vendor: 'intel', kind: 'discrete', worker: 'OpenCL', vram_mb: 12208, enabled: true, state: 'mining', hash_now: 15.2, power_w: 0, temp_gpu: 0, sweep_supported: false, sweep_state: 'unsupported', sweep_note: 'not available: Intel Arc exposes no power cap or reading through OpenCL (the driver\'s IGCL counters come next)' });
|
||||
const r = V.cardRow(arc);
|
||||
assert.equal(r.vendor, 'intel');
|
||||
assert.equal(r.kindWord, 'Discrete');
|
||||
assert.equal(r.integrated, false);
|
||||
assert.equal(r.on, true);
|
||||
assert.ok(r.meta.startsWith('12 GB'), r.meta);
|
||||
assert.equal(r.power, '', 'no watts cell without a reading');
|
||||
assert.equal(V.noReading(arc), 'No power or temperature reading on Intel Arc yet: the driver exposes them through IGCL, not OpenCL');
|
||||
assert.equal(V.tunable(arc), false, 'no cap, no clock control: not tunable');
|
||||
assert.equal(V.proveTier(arc), 'Intel(R) Arc(TM) B580 Graphics: cannot prove yet (proving needs an NVIDIA card).');
|
||||
const tm = mod.exports.TuneLine.model(arc, 1000);
|
||||
assert.equal(tm.kind, 'off');
|
||||
assert.equal(tm.text, 'tuning: measure only on Intel Arc once a power reading exists');
|
||||
});
|
||||
|
||||
test('an integrated GPU is shown as integrated and off, with its reason', () => {
|
||||
const r = V.cardRow(card({ key: 'intel:1:UHD', name: 'Intel UHD Graphics 770', vendor: 'other', kind: 'integrated', enabled: false, state: 'off', hash_now: 0, reason: 'integrated GPU: slow and shares the machine memory', power_w: 0, temp_gpu: 0 }));
|
||||
assert.equal(r.integrated, true);
|
||||
|
|
|
|||
|
|
@ -199,6 +199,13 @@ function stateNow() {
|
|||
s.heat = { on: true, phase: resting ? 'resting' : 'heating', set_c: 20, room_c: resting ? 20.1 : 19.6, room_source: 'typed', room_error_c: 0, room_age_s: 2400, duty: 0.6, duty_hour: 0.58, heat_w: resting ? 0 : 448, full_w: 448, heat_avg_w: 269, until_s: resting ? 230 : 312, note: resting ? 'Holding 20.0 °C: room 20.1 °C from your reading 40 min ago. resting, heats again in 4 min. Heat 60% of the time.' : 'Holding 20.0 °C: room 19.6 °C from your reading 40 min ago. heating, 5 min to go. Heat 60% of the time.', period_s: 600, offset_c: 7.5, offset_learned: true };
|
||||
s.events = [{ kind: 'info', t: t - 312, text: 'heat mode: heating again' }, { kind: 'info', t: t - 2400, text: 'heat mode on: holding 20.0 °C (schedule 06:00 20, 22:00 16); the cards heat for a share of every 10 minutes and rest for the rest' }].concat(s.events).slice(0, 40);
|
||||
}
|
||||
if (scenario === 'intel') {
|
||||
// PC 1 after the B580 swap (7 October 2026, docs/plans/intel-arc.md): the 5090 and the first Intel card; the Arc's
|
||||
// numbers are the plan's expectation, not a measurement, until the PC 1 job's row lands
|
||||
s.mining.cards = [{ ...recState.mining.cards[0], key: 'nvidia:NVIDIA GeForce RTX 5090', name: 'NVIDIA GeForce RTX 5090', kind: 'discrete', vendor: 'nvidia', worker: 'CUDA', detail: '21760 cores', vram_mb: 32768, device: '0', identities: 8, ids: ['8fafda27', '1b2c3d4e', '5f6a7b8c'], power_default_w: 575, power_pct: 80, power_applied: true, power_limit_w: 460, power_w: 227, temp_gpu: 61, temp_mem: 70, hash_now: 127.7, hash_avg: 127.1, eff_mhw: 0.563, sweep_supported: true, sweep_state: 'idle', sweep_note: '', tune_line: 'Tuned: 127.7 MH/s at 227 W (0.563 MH/W)', tune_source: 'full', tune_control: true, tune_clock_mhz: 1854, sweep_pct: 100, sweep_watts: 227, sweep_at: t - 7200 },
|
||||
{ ...recState.mining.cards[0], key: 'intel:Intel(R) Arc(TM) B580 Graphics', name: 'Intel(R) Arc(TM) B580 Graphics', code: 'Intel(R) Arc(TM) B580 Graphics', platform: 'Intel(R) OpenCL Graphics (OpenCL 3.0 ), driver 32.0.101.9034', kind: 'discrete', vendor: 'intel', worker: 'OpenCL', detail: '160 compute units', vram_mb: 12208, device: '1', bus: '05:00.0', identities: 8, ids: ['c0ffee01', 'c0ffee02'], enabled: true, state: 'mining', hash_now: 15.2, hash_avg: 15.0, accepted: 3, rejected: 0, power_default_w: 0, power_pct: 0, power_applied: false, power_w: 0, temp_gpu: 0, temp_mem: 0, eff_mhw: 0, sweep_supported: false, sweep_state: 'unsupported', sweep_note: 'not available: Intel Arc exposes no power cap or reading through OpenCL (the driver\'s IGCL counters come next)', tune_line: '', tune_source: '', tune_control: false, driver: '32.0.101.9034' }];
|
||||
s.mining.hash_total = 142.9; s.display_name = 'pc-1';
|
||||
}
|
||||
if (scenario === 'nvidia') {
|
||||
s.mining.cards = [{ ...recState.mining.cards[0], key: 'nvidia:0:NVIDIA GeForce RTX 5090', name: 'NVIDIA GeForce RTX 5090', kind: 'discrete', vendor: 'nvidia', worker: 'CUDA', detail: '21760 cores', vram_mb: 32768, device: '0', identities: 8, ids: ['8fafda27', '1b2c3d4e', '5f6a7b8c'], power_default_w: 575, power_pct: 80, power_applied: true, power_limit_w: 460, power_w: 441, temp_gpu: 71, temp_mem: 92, telemetry_at: t, hash_now: 412.5, hash_avg: 405.2 },
|
||||
{ ...recState.mining.cards[0], key: 'nvidia:1:NVIDIA GeForce RTX 4070', name: 'NVIDIA GeForce RTX 4070', kind: 'discrete', vendor: 'nvidia', worker: 'CUDA', detail: '5888 cores', vram_mb: 12288, device: '1', identities: 2, ids: ['9a8b7c6d'], power_default_w: 200, power_pct: 80, power_applied: false, power_note: 'nvidia-smi: wanted 160 W, card reports 200 W', power_limit_w: 200, power_w: 188, temp_gpu: 64, temp_mem: 0, telemetry_at: t, hash_now: 98.1, hash_avg: 97.4, state: 'restarting', restart_in_s: 4 },
|
||||
|
|
|
|||
Loading…
Reference in a new issue