LCOV - code coverage report
Current view: top level - tests/linalg - t_vector_vector_i8.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 241 241 100.0 %
Date: 2024-05-13 05:06:06 Functions: 60 60 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /**
       2             :  * Unit tests for the Linear Algebra module's Vector operations
       3             :  */
       4             : #include <chrono>
       5             : #include <cstdint>
       6             : #include <cstdlib>
       7             : #include <gtest/gtest.h>
       8             : #include <iostream>
       9             : #include <openGPMP/linalg/vector.hpp>
      10             : #include <random>
      11             : #include <stdexcept>
      12             : #include <vector>
      13             : 
      14             : const double TOLERANCE = 1e-3;
      15             : 
      16             : #define TEST_COUT std::cerr << "\033[32m[          ] [ INFO ] \033[0m"
      17             : #define INFO_COUT                                                              \
      18             :     std::cerr << "\033[32m[          ] [ INFO ] \033[0m\033[1;34m\033[1m"
      19             : /*****************************************************************************/
      20             : /** VECTOR<INT8> TESTS */
      21             : 
      22           4 : TEST(VectorVectorTestI8, Addition) {
      23           1 :     INFO_COUT << "Vector (as Vectors) INT8" << std::endl;
      24             : 
      25             :     // Create input vectors
      26           1 :     std::vector<int8_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
      27           1 :     std::vector<int8_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
      28           1 :     std::vector<int8_t> result(vec1.size());
      29             : 
      30             :     // Perform vector addition
      31           1 :     gpmp::linalg::vector_add(vec1, vec2, result);
      32             : 
      33             :     // Check the result
      34           1 :     EXPECT_EQ(result.size(), vec1.size());
      35           9 :     for (size_t i = 0; i < result.size(); ++i) {
      36           8 :         EXPECT_EQ(result[i], vec1[i] + vec2[i]);
      37             :     }
      38           1 : }
      39             : 
      40           4 : TEST(VectorVectorTestI8, AdditionComparison) {
      41             :     // Create input vectors
      42           1 :     std::vector<int8_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
      43           1 :     std::vector<int8_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
      44           1 :     std::vector<int8_t> result_intrin(vec1.size());
      45           1 :     std::vector<int8_t> result_std(vec1.size());
      46             : 
      47             :     // Perform vector addition using INTRINSIC and standard methods
      48           1 :     gpmp::linalg::vector_add(vec1, vec2, result_intrin);
      49           1 :     gpmp::linalg::std_vector_add(vec1, vec2, result_std);
      50             : 
      51             :     // Check if the results match
      52           1 :     ASSERT_EQ(result_intrin.size(), result_std.size());
      53           9 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
      54           8 :         EXPECT_EQ(result_intrin[i], result_std[i]);
      55             :     }
      56           1 : }
      57             : 
      58           4 : TEST(VectorVectorTestI8, AdditionComparisonRandom) {
      59           1 :     const size_t size = 3333;
      60             : 
      61           1 :     std::random_device rd;
      62           1 :     std::mt19937 rng(rd());
      63           1 :     std::uniform_int_distribution<int8_t> dist(-127, 127);
      64             : 
      65             :     // Generate random vectors
      66           1 :     std::vector<int8_t> vec1;
      67           1 :     std::vector<int8_t> vec2;
      68        3334 :     for (size_t i = 0; i < size; ++i) {
      69        3333 :         vec1.push_back(dist(rng));
      70        3333 :         vec2.push_back(dist(rng));
      71             :     }
      72             : 
      73             :     // Perform vector addition using INTRINSIC and standard methods
      74           1 :     std::vector<int8_t> result_intrin(size);
      75           1 :     std::vector<int8_t> result_std(size);
      76           1 :     gpmp::linalg::vector_add(vec1, vec2, result_intrin);
      77           1 :     gpmp::linalg::std_vector_add(vec1, vec2, result_std);
      78             : 
      79             :     // Check if the results match
      80           1 :     ASSERT_EQ(result_intrin.size(), result_std.size());
      81        3334 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
      82        3333 :         EXPECT_EQ(result_intrin[i], result_std[i]);
      83             :     }
      84           1 : }
      85           4 : TEST(VectorVectorTestI8, AdditionPerformanceComparison) {
      86           1 :     const size_t size = 3333 * 3333;
      87             : 
      88           1 :     TEST_COUT << "Vector size      : " << size << std::endl;
      89             :     // Create random number generator
      90           1 :     std::random_device rd;
      91           1 :     std::mt19937 rng(rd());
      92           1 :     std::uniform_int_distribution<int8_t> dist(-127, 127);
      93             : 
      94             :     // Generate random vectors
      95           1 :     std::vector<int8_t> vec1;
      96           1 :     std::vector<int8_t> vec2;
      97    11108890 :     for (size_t i = 0; i < size; ++i) {
      98    11108889 :         vec1.push_back(dist(rng));
      99    11108889 :         vec2.push_back(dist(rng));
     100             :     }
     101             : 
     102             :     // Measure execution time for INTRINSIC vector addition
     103           1 :     std::vector<int8_t> result_intrin(size);
     104             : 
     105           1 :     auto start_intrin = std::chrono::high_resolution_clock::now();
     106           1 :     gpmp::linalg::vector_add(vec1, vec2, result_intrin);
     107           1 :     auto end_intrin = std::chrono::high_resolution_clock::now();
     108             : 
     109             :     std::chrono::duration<double> elapsed_seconds_intrin =
     110           1 :         end_intrin - start_intrin;
     111             : 
     112             :     // Measure execution time for standard vector addition
     113           1 :     std::vector<int8_t> result_std(size);
     114             : 
     115           1 :     auto start_std = std::chrono::high_resolution_clock::now();
     116           1 :     gpmp::linalg::std_vector_add(vec1, vec2, result_std);
     117           1 :     auto end_std = std::chrono::high_resolution_clock::now();
     118             : 
     119           1 :     std::chrono::duration<double> elapsed_seconds_std = end_std - start_std;
     120             : 
     121           1 :     TEST_COUT << "INTRINSIC Vector Addition Time      : "
     122           1 :               << elapsed_seconds_intrin.count() << " seconds" << std::endl;
     123             : 
     124           1 :     TEST_COUT << "STANDARD  Vector Addition Time      : "
     125           1 :               << elapsed_seconds_std.count() << " seconds" << std::endl;
     126             : 
     127             :     // Check if the results match
     128           1 :     ASSERT_EQ(result_intrin.size(), result_std.size());
     129    11108890 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     130    11108889 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     131             :     }
     132           1 : }
     133             : 
     134           4 : TEST(VectorVectorTestI8, Subtraction) {
     135             :     // Create input vectors
     136           1 :     std::vector<int8_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
     137           1 :     std::vector<int8_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
     138           1 :     std::vector<int8_t> result(vec1.size());
     139             : 
     140             :     // Perform vector subtraction
     141           1 :     gpmp::linalg::vector_sub(vec1, vec2, result);
     142             : 
     143             :     // Check the result
     144           1 :     EXPECT_EQ(result.size(), vec1.size());
     145           9 :     for (size_t i = 0; i < result.size(); ++i) {
     146           8 :         EXPECT_EQ(result[i], vec1[i] - vec2[i]);
     147             :     }
     148           1 : }
     149             : 
     150           4 : TEST(VectorVectorTestI8, SubtractionComparison) {
     151             :     // Create input vectors
     152           1 :     std::vector<int8_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
     153           1 :     std::vector<int8_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
     154           1 :     std::vector<int8_t> result_intrin(vec1.size());
     155           1 :     std::vector<int8_t> result_std(vec1.size());
     156             : 
     157             :     // Perform vector subtraction using INTRINSIC and standard methods
     158           1 :     gpmp::linalg::vector_sub(vec1, vec2, result_intrin);
     159           1 :     gpmp::linalg::std_vector_sub(vec1, vec2, result_std);
     160             : 
     161             :     // Check if the results match
     162           1 :     ASSERT_EQ(result_intrin.size(), result_std.size());
     163           9 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     164           8 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     165             :     }
     166           1 : }
     167             : 
     168           4 : TEST(VectorVectorTestI8, SubtractionComparisonRandom) {
     169           1 :     const size_t size = 3333;
     170             :     // Create random number generator
     171           1 :     std::random_device rd;
     172           1 :     std::mt19937 rng(rd());
     173           1 :     std::uniform_int_distribution<int8_t> dist(-127, 127);
     174             : 
     175             :     // Generate random vectors
     176           1 :     std::vector<int8_t> vec1;
     177           1 :     std::vector<int8_t> vec2;
     178        3334 :     for (size_t i = 0; i < size; ++i) {
     179        3333 :         vec1.push_back(dist(rng));
     180        3333 :         vec2.push_back(dist(rng));
     181             :     }
     182             : 
     183             :     // Perform vector addition using INTRINSIC and standard methods
     184           1 :     std::vector<int8_t> result_intrin(size);
     185           1 :     std::vector<int8_t> result_std(size);
     186           1 :     gpmp::linalg::vector_add(vec1, vec2, result_intrin);
     187           1 :     gpmp::linalg::std_vector_add(vec1, vec2, result_std);
     188             : 
     189             :     // Check if the results match
     190           1 :     ASSERT_EQ(result_intrin.size(), result_std.size());
     191        3334 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     192        3333 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     193             :     }
     194           1 : }
     195             : 
     196           4 : TEST(VectorVectorTestI8, SubtractionPerformanceComparison) {
     197           1 :     const size_t size = 3333 * 3333;
     198             : 
     199           1 :     TEST_COUT << "Vector size      : " << size << std::endl;
     200             :     // Create random number generator
     201           1 :     std::random_device rd;
     202           1 :     std::mt19937 rng(rd());
     203           1 :     std::uniform_int_distribution<int8_t> dist(-127, 127);
     204             : 
     205             :     // Generate random vectors
     206           1 :     std::vector<int8_t> vec1;
     207           1 :     std::vector<int8_t> vec2;
     208    11108890 :     for (size_t i = 0; i < size; ++i) {
     209    11108889 :         vec1.push_back(dist(rng));
     210    11108889 :         vec2.push_back(dist(rng));
     211             :     }
     212             : 
     213             :     // Measure execution time for INTRINSIC vector addition
     214           1 :     std::vector<int8_t> result_intrin(size);
     215             : 
     216           1 :     auto start_intrin = std::chrono::high_resolution_clock::now();
     217           1 :     gpmp::linalg::vector_sub(vec1, vec2, result_intrin);
     218           1 :     auto end_intrin = std::chrono::high_resolution_clock::now();
     219             : 
     220             :     std::chrono::duration<double> elapsed_seconds_intrin =
     221           1 :         end_intrin - start_intrin;
     222             : 
     223             :     // Measure execution time for standard vector addition
     224           1 :     std::vector<int8_t> result_std(size);
     225             : 
     226           1 :     auto start_std = std::chrono::high_resolution_clock::now();
     227           1 :     gpmp::linalg::std_vector_sub(vec1, vec2, result_std);
     228           1 :     auto end_std = std::chrono::high_resolution_clock::now();
     229             : 
     230           1 :     std::chrono::duration<double> elapsed_seconds_std = end_std - start_std;
     231             : 
     232           1 :     TEST_COUT << "INTRINSIC Vector Subtraction Time      : "
     233           1 :               << elapsed_seconds_intrin.count() << " seconds" << std::endl;
     234             : 
     235           1 :     TEST_COUT << "STANDARD  Vector Subtraction Time      : "
     236           1 :               << elapsed_seconds_std.count() << " seconds" << std::endl;
     237             : 
     238             :     // Check if the results match
     239           1 :     ASSERT_EQ(result_intrin.size(), result_std.size());
     240    11108890 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     241    11108889 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     242             :     }
     243           1 : }
     244             : 
     245             : // Unit test for vector multiplication using INTRINSIC intrinsics
     246           4 : TEST(VectorVectorTestI8, Multiplication) {
     247             :     // Create input vector and scalar
     248           1 :     std::vector<int8_t> vec = {1, 2, 3, 4, 5, 6, 7, 8};
     249           1 :     int scalar = 2;
     250           1 :     std::vector<int8_t> result(vec.size());
     251             : 
     252             :     // Perform vector multiplication
     253           1 :     gpmp::linalg::scalar_mult(vec, scalar, result);
     254             : 
     255             :     // Check the result
     256           9 :     for (size_t i = 0; i < result.size(); ++i) {
     257           8 :         EXPECT_EQ(result[i], vec[i] * scalar);
     258             :     }
     259           1 : }
     260             : 
     261             : // Unit test to compare results of INTRINSIC vector multiplication with standard
     262             : // vector multiplication
     263           4 : TEST(VectorVectorTestI8, MultComparison) {
     264             :     // Create input vector and scalar
     265           1 :     std::vector<int8_t> vec = {1, 2, 3, 4, 5, 6, 7, 8};
     266           1 :     int scalar = 2;
     267           1 :     std::vector<int8_t> result_intrin(vec.size());
     268           1 :     std::vector<int8_t> result_std(vec.size());
     269             : 
     270             :     // Perform vector multiplication using INTRINSIC and standard methods
     271           1 :     gpmp::linalg::scalar_mult(vec, scalar, result_intrin);
     272           1 :     gpmp::linalg::std_scalar_mult(vec, scalar, result_std);
     273             : 
     274             :     // Check if the results match
     275           9 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     276           8 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     277             :     }
     278           1 : }
     279             : 
     280             : // Unit test to compare results of INTRINSIC vector multiplication with standard
     281             : // vector multiplication using random vectors
     282           4 : TEST(VectorVectorTestI8, MultComparisonRandom) {
     283           1 :     const size_t size = 3333;
     284             :     // Create random number generator
     285           1 :     std::random_device rd;
     286           1 :     std::mt19937 rng(rd());
     287           1 :     std::uniform_int_distribution<int8_t> dist(0, 11);
     288             : 
     289           1 :     std::vector<int8_t> vec;
     290           1 :     int scalar = dist(rng);
     291        3334 :     for (size_t i = 0; i < size; ++i) {
     292        3333 :         vec.push_back(dist(rng));
     293             :     }
     294             : 
     295             :     // Perform vector multiplication using INTRINSIC and standard methods
     296           1 :     std::vector<int8_t> result_intrin(size);
     297           1 :     std::vector<int8_t> result_std(size);
     298           1 :     gpmp::linalg::scalar_mult(vec, scalar, result_intrin);
     299           1 :     gpmp::linalg::std_scalar_mult(vec, scalar, result_std);
     300             : 
     301             :     // Check if the results match
     302        3334 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     303        3333 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     304             :     }
     305           1 : }
     306             : 
     307             : // Unit test to compare execution time of INTRINSIC vector multiplication with
     308             : // standard vector multiplication
     309           4 : TEST(VectorVectorTestI8, MultPerformanceComparison) {
     310           1 :     const size_t size = 3333 * 3333;
     311           1 :     TEST_COUT << "Vector size      : " << size << std::endl;
     312             : 
     313           1 :     std::random_device rd;
     314           1 :     std::mt19937 rng(rd());
     315           1 :     std::uniform_int_distribution<int8_t> dist(0, 11);
     316             : 
     317           1 :     std::vector<int8_t> vec;
     318           1 :     int scalar = dist(rng);
     319    11108890 :     for (size_t i = 0; i < size; ++i) {
     320    11108889 :         vec.push_back(dist(rng));
     321             :     }
     322             : 
     323             :     // Measure execution time for INTRINSIC vector multiplication
     324           1 :     std::vector<int8_t> result_intrin(size);
     325           1 :     auto start_intrin = std::chrono::high_resolution_clock::now();
     326           1 :     gpmp::linalg::scalar_mult(vec, scalar, result_intrin);
     327           1 :     auto end_intrin = std::chrono::high_resolution_clock::now();
     328             :     std::chrono::duration<double> elapsed_seconds_intrin =
     329           1 :         end_intrin - start_intrin;
     330             : 
     331             :     // Measure execution time for standard vector multiplication
     332           1 :     std::vector<int8_t> result_std(size);
     333           1 :     auto start_std = std::chrono::high_resolution_clock::now();
     334           1 :     gpmp::linalg::std_scalar_mult(vec, scalar, result_std);
     335           1 :     auto end_std = std::chrono::high_resolution_clock::now();
     336           1 :     std::chrono::duration<double> elapsed_seconds_std = end_std - start_std;
     337             : 
     338             :     // Print the results
     339           1 :     TEST_COUT << "INTRINSIC Vector Multiplication Time      : "
     340           1 :               << elapsed_seconds_intrin.count() << " seconds" << std::endl;
     341           1 :     TEST_COUT << "STANDARD  Vector Multiplication Time      : "
     342           1 :               << elapsed_seconds_std.count() << " seconds" << std::endl;
     343             : 
     344             :     // Check if the results match
     345    11108890 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     346             :         // EXPECT_EQ(result_intrin[i], result_std[i]);
     347             :     }
     348           1 : }
     349             : 
     350             : // Unit test for dot product using INTRINSIC intrinsics
     351           4 : TEST(VectorVectorTestI8, DotProduct) {
     352             :     // Create input vectors
     353           1 :     std::vector<int8_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
     354           1 :     std::vector<int8_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
     355             : 
     356             :     // Calculate dot product
     357           1 :     int result = gpmp::linalg::dot_product(vec1, vec2);
     358             : 
     359             :     // Expected result
     360           1 :     int expected_result = 120;
     361             : 
     362             :     // Check the result
     363           1 :     EXPECT_EQ(result, expected_result);
     364           1 : }
     365             : 
     366             : // Unit test for dot product using INTRINSIC intrinsics with random vectors
     367           4 : TEST(VectorVectorTestI8, DotProductRandom) {
     368           1 :     const size_t size = 3333;
     369             : 
     370           1 :     std::random_device rd;
     371           1 :     std::mt19937 rng(rd());
     372           1 :     std::uniform_int_distribution<int8_t> dist(-128, 127);
     373             : 
     374           1 :     std::vector<int8_t> vec1;
     375           1 :     std::vector<int8_t> vec2;
     376        3334 :     for (size_t i = 0; i < size; ++i) {
     377        3333 :         vec1.push_back(dist(rng));
     378        3333 :         vec2.push_back(dist(rng));
     379             :     }
     380             : 
     381             :     // Calculate dot product using INTRINSIC intrinsics
     382           1 :     int result = gpmp::linalg::dot_product(vec1, vec2);
     383           1 :     int expected_result = gpmp::linalg::std_dot_product(vec1, vec2);
     384             : 
     385             :     // Check the result
     386           1 :     EXPECT_EQ(result, expected_result);
     387           1 : }
     388             : 
     389           4 : TEST(VectorVectorTestI8, DotProductPerformanceComparison) {
     390           1 :     const size_t size = 3333 * 3333;
     391           1 :     TEST_COUT << "Vector size      : " << size << std::endl;
     392             : 
     393           1 :     std::random_device rd;
     394           1 :     std::mt19937 rng(rd());
     395           1 :     std::uniform_int_distribution<int8_t> dist(0, 11);
     396             : 
     397           1 :     std::vector<int8_t> vec1;
     398           1 :     std::vector<int8_t> vec2;
     399    11108890 :     for (size_t i = 0; i < size; ++i) {
     400    11108889 :         vec1.push_back(dist(rng));
     401    11108889 :         vec2.push_back(dist(rng));
     402             :     }
     403             : 
     404             :     // Measure execution time for INTRINSIC dot product calculation
     405           1 :     auto start_intrin = std::chrono::high_resolution_clock::now();
     406           1 :     int result_intrin = gpmp::linalg::dot_product(vec1, vec2);
     407           1 :     auto end_intrin = std::chrono::high_resolution_clock::now();
     408             :     std::chrono::duration<double> elapsed_seconds_intrin =
     409           1 :         end_intrin - start_intrin;
     410             : 
     411             :     // Measure execution time for standard dot product calculation
     412           1 :     auto start_std = std::chrono::high_resolution_clock::now();
     413           1 :     int result_std = gpmp::linalg::std_dot_product(vec1, vec2);
     414           1 :     auto end_std = std::chrono::high_resolution_clock::now();
     415           1 :     std::chrono::duration<double> elapsed_seconds_std = end_std - start_std;
     416             : 
     417             :     // Print the results
     418           1 :     TEST_COUT << "INTRINSIC Dot Product Time      : "
     419           1 :               << elapsed_seconds_intrin.count() << " seconds" << std::endl;
     420           1 :     TEST_COUT << "STANDARD  Dot Product Time      : "
     421           1 :               << elapsed_seconds_std.count() << " seconds" << std::endl;
     422             : 
     423           1 :     EXPECT_EQ(result_std, result_intrin);
     424           1 : }

Generated by: LCOV version 1.14