107 lines
3 KiB
PHP
107 lines
3 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\Gpu;
|
|
use Illuminate\Console\Command;
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
|
|
#[AsCommand(name: 'festbench:gpus', description: 'Manage the canonical GPU catalog')]
|
|
class Gpus extends Command
|
|
{
|
|
protected $signature = 'festbench:gpus
|
|
{action : list|add|deactivate}
|
|
{--name= : GPU name (add/deactivate)}
|
|
{--vendor= : amd|nvidia|intel|other (add)}';
|
|
|
|
public function handle(): int
|
|
{
|
|
return match ($this->argument('action')) {
|
|
'list' => $this->listGpus(),
|
|
'add' => $this->addGpu(),
|
|
'deactivate' => $this->deactivateGpu(),
|
|
default => (function () {
|
|
$this->error('Unknown action. Use list, add or deactivate.');
|
|
|
|
return self::FAILURE;
|
|
})(),
|
|
};
|
|
}
|
|
|
|
private function listGpus(): int
|
|
{
|
|
$this->table(
|
|
['id', 'name', 'vendor', 'active'],
|
|
Gpu::orderBy('vendor')->orderBy('name')->get(['id', 'name', 'vendor', 'active'])
|
|
->map(fn ($g) => [$g->id, $g->name, $g->vendor, $g->active ? 'yes' : 'no'])->all()
|
|
);
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function addGpu(): int
|
|
{
|
|
$name = $this->option('name');
|
|
|
|
if ($name === null) {
|
|
$this->error('--name is required.');
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$vendor = $this->option('vendor') ?? $this->guessVendor($name);
|
|
|
|
if (! in_array($vendor, ['amd', 'nvidia', 'intel', 'other'], true)) {
|
|
$this->error('--vendor must be amd, nvidia, intel or other.');
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$gpu = Gpu::updateOrCreate(
|
|
['name' => trim($name)],
|
|
['vendor' => $vendor, 'active' => true]
|
|
);
|
|
|
|
$this->info($gpu->wasRecentlyCreated
|
|
? "GPU {$gpu->name} ({$gpu->vendor}) added."
|
|
: "GPU {$gpu->name} ({$gpu->vendor}) updated.");
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function deactivateGpu(): int
|
|
{
|
|
$name = $this->option('name');
|
|
|
|
if ($name === null) {
|
|
$this->error('--name is required.');
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$gpu = Gpu::match($name);
|
|
|
|
if ($gpu === null) {
|
|
$this->error("GPU {$name} not found.");
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$gpu->update(['active' => false]);
|
|
$this->info("GPU {$gpu->name} deactivated (historical runs keep their links).");
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function guessVendor(string $name): string
|
|
{
|
|
$lower = strtolower($name);
|
|
|
|
return match (true) {
|
|
str_contains($lower, 'radeon') || str_contains($lower, 'amd') || str_contains($lower, 'instinct') => 'amd',
|
|
str_contains($lower, 'nvidia') || str_contains($lower, 'geforce') || str_contains($lower, 'rtx') || str_contains($lower, 'gtx') => 'nvidia',
|
|
str_contains($lower, 'intel') || str_contains($lower, 'arc') => 'intel',
|
|
default => 'other',
|
|
};
|
|
}
|
|
}
|