From 2d1135cbd3bd19f6eaaf3186486d0cb237f3f047 Mon Sep 17 00:00:00 2001 From: Thomas Ubensee <34603111+tomuben@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:27:00 -0300 Subject: [PATCH] #1036: Added pytorch and numba integration test compatible with CPU only VM --- .../flavor_base/testconfig | 2 +- .../tests/test/python3-cuda-flavor/numba.py | 47 ++++++++++++ .../tests/test/python3-cuda-flavor/pytorch.py | 72 +++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 test_container/tests/test/python3-cuda-flavor/numba.py create mode 100644 test_container/tests/test/python3-cuda-flavor/pytorch.py diff --git a/flavors/test-Exasol-8-cuda-ml/flavor_base/testconfig b/flavors/test-Exasol-8-cuda-ml/flavor_base/testconfig index d1bdb8113..106402b1c 100644 --- a/flavors/test-Exasol-8-cuda-ml/flavor_base/testconfig +++ b/flavors/test-Exasol-8-cuda-ml/flavor_base/testconfig @@ -1,2 +1,2 @@ generic_language_tests=python3 -test_folders=python3/all pandas/all pandas/pandas2 +test_folders=python3/all pandas/all pandas/pandas2 python3-cuda-flavor diff --git a/test_container/tests/test/python3-cuda-flavor/numba.py b/test_container/tests/test/python3-cuda-flavor/numba.py new file mode 100644 index 000000000..13aad0a43 --- /dev/null +++ b/test_container/tests/test/python3-cuda-flavor/numba.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 + +from exasol_python_test_framework import udf + + +class NumbaTest(udf.TestCase): + def setUp(self): + self.query('create schema numbabasic', ignore_errors=True) + + def test_import_keras(self): + self.query(udf.fixindent(''' + CREATE OR REPLACE PYTHON3 SCALAR SCRIPT + test_numba(epochs INTEGER) + RETURNS VARCHAR(10000) AS + + import math + from numba import vectorize, cuda + import numpy as np + import os + + @vectorize(['float32(float32, float32, float32)', + 'float64(float64, float64, float64)',], + #target='cuda' + ) + def cu_discriminant(a, b, c): + return math.sqrt(b ** 2 - 4 * a * c) + + def run(ctx): + N = ctx.epochs + dtype = np.float32 + + # prepare the input + A = np.array(np.random.sample(N), dtype=dtype) + B = np.array(np.random.sample(N) + 10, dtype=dtype) + C = np.array(np.random.sample(N), dtype=dtype) + + D = cu_discriminant(A, B, C) + + return str(D) + / + ''')) + + row = self.query("SELECT numbabasic.test_numba(10000);")[0] + + +if __name__ == '__main__': + udf.main() diff --git a/test_container/tests/test/python3-cuda-flavor/pytorch.py b/test_container/tests/test/python3-cuda-flavor/pytorch.py new file mode 100644 index 000000000..d9865bca4 --- /dev/null +++ b/test_container/tests/test/python3-cuda-flavor/pytorch.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +import shutil +import tarfile +import tempfile +import time +import urllib.request +from pathlib import Path + +import requests +from exasol_python_test_framework import udf +from exasol_python_test_framework.exatest.utils import obj_from_json_file +from requests.auth import HTTPBasicAuth + + +class PytorchTest(udf.TestCase): + def setUp(self): + self.query('create schema pytorchbasic', ignore_errors=True) + + def test_pytorch(self): + self.query(udf.fixindent(''' + CREATE OR REPLACE PYTHON3 SCALAR SCRIPT + test_pytorch(epochs INTEGER) + RETURNS VARCHAR(10000) AS + + import torch + import torch.nn as nn + import torch.optim as optim + import numpy as np + + def run(ctx): + # Generate random data + np.random.seed(42) + x = np.random.rand(100, 1).astype(np.float32) # Random x values + y = 10 * x # Corresponding y values + + # Convert numpy arrays to torch tensors + x_train = torch.from_numpy(x) + y_train = torch.from_numpy(y) + + # Define a simple linear regression model + class LinearModel(nn.Module): + def __init__(self): + super(LinearModel, self).__init__() + self.linear = nn.Linear(1, 1) # Input and output both have size 1 + + def forward(self, x): + return self.linear(x) + + # Initialize the model, loss function, and optimizer + model = LinearModel() + criterion = nn.MSELoss() + optimizer = optim.SGD(model.parameters(), lr=0.01) + + # Training loop + epochs = ctx.epochs + for epoch in range(epochs): + model + # Check accuracy + model.eval() + with torch.no_grad(): + y_pred = model(x_train) + mse = criterion(y_pred, y_train) + return f'Mean Squared Error: {mse.item():.4f}' + / + ''')) + + row = self.query(f"SELECT pytorchbasic.test_pytorch(1000);")[0] + self.assertIn('Mean Squared Error', row[0]) + + +if __name__ == '__main__': + udf.main()