Skip to content

Commit 2c1fcef

Browse files
Use custom OpenBlasFactory without lapacke and consequently libgfortran dependency at runtime
1 parent 03616db commit 2c1fcef

4 files changed

Lines changed: 84 additions & 9 deletions

File tree

src/Commands/InstallCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ protected function askToStar(InputInterface $input, OutputInterface $output): vo
4848
}
4949

5050
$helper = $this->getHelper('question');
51-
$question = new ConfirmationQuestion('? All done! Would you like to show some love by starring the Transformers repo on GitHub? ', true);
51+
$question = new ConfirmationQuestion('? Would you like to show some love by starring the Transformers repo on GitHub? ', true);
5252

5353
if ($helper->ask($input, $output, $question)) {
5454
if (PHP_OS_FAMILY === 'Darwin') {

src/Tensor/OpenBLASFactory.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
6+
namespace Codewithkyrian\Transformers\Tensor;
7+
8+
use FFI;
9+
use FFI\Exception as FFIException;
10+
use Rindow\Math\Matrix\Drivers\MatlibPHP\PhpLapack;
11+
use Rindow\OpenBLAS\FFI\Blas;
12+
use RuntimeException;
13+
14+
/**
15+
*/
16+
class OpenBLASFactory
17+
{
18+
private static ?FFI $ffi = null;
19+
20+
21+
/**
22+
* @param array<string> $libFiles
23+
* @param array<string> $lapackeLibs
24+
*/
25+
public function __construct(
26+
string $headerFile,
27+
array $libFiles,
28+
)
29+
{
30+
if (self::$ffi !== null) {
31+
return;
32+
}
33+
if (!extension_loaded('ffi')) {
34+
return;
35+
}
36+
37+
$code = file_get_contents($headerFile);
38+
39+
foreach ($libFiles as $filename) {
40+
try {
41+
$ffi = FFI::cdef($code, $filename);
42+
} catch (FFIException $e) {
43+
continue;
44+
}
45+
46+
self::$ffi = $ffi;
47+
break;
48+
}
49+
}
50+
51+
public function isAvailable(): bool
52+
{
53+
return self::$ffi !== null;
54+
}
55+
56+
public function Blas(): Blas
57+
{
58+
if (self::$ffi == null) {
59+
throw new RuntimeException('openblas library not loaded.');
60+
}
61+
return new Blas(self::$ffi);
62+
}
63+
64+
public function Lapack(): PhpLapack
65+
{
66+
return new PhpLapack();
67+
}
68+
}

src/Tensor/TensorService.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use Codewithkyrian\TransformersLibrariesDownloader\Libraries;
99
use Rindow\Math\Matrix\Drivers\AbstractMatlibService;
1010
use Rindow\Matlib\FFI\MatlibFactory;
11-
use Rindow\OpenBLAS\FFI\OpenBLASFactory;
1211

1312
class TensorService extends AbstractMatlibService
1413
{
@@ -20,14 +19,12 @@ protected function injectDefaultFactories(): void
2019
$openblasFactory = new OpenBLASFactory(
2120
headerFile: Libraries::OpenBlas_OpenMP->headerFile(Transformers::$libsDir),
2221
libFiles: [Libraries::OpenBlas_OpenMP->libFile(Transformers::$libsDir)],
23-
lapackeLibs: [Libraries::Lapacke_OpenMP->libFile(Transformers::$libsDir)],
2422
);
2523

2624
$mathFactory = new MatlibFactory(
2725
libFiles: [Libraries::RindowMatlib_OpenMP->libFile(Transformers::$libsDir)]
2826
);
2927

30-
3128
// Check if OpenMP-compatible factories are available
3229
if ($openblasFactory->isAvailable() && $mathFactory->isAvailable()) {
3330
$this->openblasFactory = $openblasFactory;
@@ -41,7 +38,6 @@ protected function injectDefaultFactories(): void
4138
$openblasFactory = new OpenBLASFactory(
4239
headerFile: Libraries::OpenBlas_Serial->headerFile(Transformers::$libsDir),
4340
libFiles: [Libraries::OpenBlas_Serial->libFile(Transformers::$libsDir)],
44-
lapackeLibs: [Libraries::Lapacke_Serial->libFile(Transformers::$libsDir)],
4541
);
4642

4743
$mathFactory = new MatlibFactory(

src/Utils/LibsChecker.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class LibsChecker
1212
{
1313
public static function check(): void
1414
{
15-
echo "Checking TransformersPHP libraries...\n";
15+
echo self::colorize("Checking TransformersPHP libraries.... ") . "\n";
1616

1717
foreach (Libraries::cases() as $library) {
1818
if (!$library->exists(Transformers::$libsDir)) {
@@ -22,7 +22,7 @@ public static function check(): void
2222
}
2323
}
2424

25-
echo "All TransformersPHP libraries are installed\n";
25+
echo self::colorize("All TransformersPHP libraries are installed") . "\n";
2626
}
2727

2828
private static function downloadLibrary(string $name): void
@@ -33,11 +33,11 @@ private static function downloadLibrary(string $name): void
3333
$downloadUrl = Libraries::joinPaths($baseUrl, "$name.$ext");
3434
$downloadPath = tempnam(sys_get_temp_dir(), 'transformers-php') . ".$ext";
3535

36-
echo " - Downloading $name\n";
36+
echo " - Downloading " . self::colorize($name) . "\n";
3737

3838
Downloader::download($downloadUrl, $downloadPath);
3939

40-
echo " - Installing $name : Extracting archive\n";
40+
echo " - Installing " . self::colorize($name) . " : Extracting archive\n";
4141

4242
$archive = new \PharData($downloadPath);
4343

@@ -47,4 +47,15 @@ private static function downloadLibrary(string $name): void
4747

4848
$archive->extractTo(Transformers::$libsDir);
4949
}
50+
51+
private static function colorize(string $text, string $color = 'green'): string
52+
{
53+
$prefix = match ($color) {
54+
'red' => "\033[31m",
55+
'green' => "\033[32m",
56+
'yellow' => "\033[33m",
57+
};
58+
59+
return "$prefix$text\033[39m";
60+
}
5061
}

0 commit comments

Comments
 (0)