mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-09-24 15:49:09 +00:00
a56b868d10
* fix(system-manager): parse CANN 24.x Ascend npu-smi info tables ModelArts / CANN 24.1 tables include Hugepages-Usage and Bus-Id chip rows that the old regex rejected, so the GPU tab showed zero Ascend devices even when npu-smi was present. Parse summary+chip pairs like nputop, always collect the info dump, and fall back to info -m for NPU IDs. Closes #2811 Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com> * feat(system-manager): harden Ascend parsing from nputop fixtures and polish GPU UI Borrow real npu-smi samples from youyve/nputop (Apache-2.0) so CI covers 910B2C, 310B4, Atlas A3 multi-chip, and 310P3 process tables without hardware. Aggregate multi-chip NPUs, parse info-dump processes, and surface npu-smi driver versions. GPU tab now keeps a short util/HBM sparkline history and ResourceBar uses smooth width transitions with load-aware tones, closer to an nvtop feel inside the existing system-manager chrome. Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: 陈大猫 <binaricat@users.noreply.github.com>
51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
import React, { memo } from 'react';
|
|
import { cn } from '../../lib/utils';
|
|
|
|
interface ResourceBarProps {
|
|
label: string;
|
|
value: number | null | undefined;
|
|
className?: string;
|
|
/** Slightly taller track for GPU cards. */
|
|
size?: 'sm' | 'md';
|
|
}
|
|
|
|
function barTone(clamped: number): string {
|
|
if (clamped > 85) return 'bg-destructive/80';
|
|
if (clamped > 60) return 'bg-amber-500/80';
|
|
return 'bg-primary/75';
|
|
}
|
|
|
|
export const ResourceBar = memo(function ResourceBar({
|
|
label,
|
|
value,
|
|
className,
|
|
size = 'sm',
|
|
}: ResourceBarProps) {
|
|
const finite = typeof value === 'number' && Number.isFinite(value);
|
|
const clamped = finite ? Math.max(0, Math.min(100, value)) : 0;
|
|
return (
|
|
<div className={cn('flex items-center gap-2 min-w-0', className)}>
|
|
{label ? (
|
|
<span className="text-[10px] text-muted-foreground w-7 shrink-0">{label}</span>
|
|
) : null}
|
|
<div
|
|
className={cn(
|
|
'flex-1 rounded-full bg-muted/50 overflow-hidden min-w-[48px]',
|
|
size === 'md' ? 'h-1.5' : 'h-1',
|
|
)}
|
|
>
|
|
<div
|
|
className={cn(
|
|
'h-full rounded-full transition-[width,background-color] duration-500 ease-out motion-reduce:transition-none',
|
|
finite ? barTone(clamped) : 'opacity-0',
|
|
)}
|
|
style={{ width: `${clamped}%` }}
|
|
/>
|
|
</div>
|
|
<span className="text-[10px] tabular-nums text-muted-foreground w-10 text-right shrink-0">
|
|
{finite ? `${value.toFixed(1)}%` : '--'}
|
|
</span>
|
|
</div>
|
|
);
|
|
});
|