LCOV - code coverage report
Current view: top level - tests/linalg - t_vector_vector_i32.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 228 228 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<INT32> TESTS */
      21             : 
      22           4 : TEST(VectorVectorTestI32, Addition) {
      23           1 :     INFO_COUT << "Vector (as Vectors) INT32" << std::endl;
      24             : 
      25             :     // Create input vectors
      26           1 :     std::vector<int32_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
      27           1 :     std::vector<int32_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
      28           1 :     std::vector<int32_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(VectorVectorTestI32, AdditionComparison) {
      41             :     // Create input vectors
      42           1 :     std::vector<int32_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
      43           1 :     std::vector<int32_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
      44           1 :     std::vector<int32_t> result_intrin(vec1.size());
      45           1 :     std::vector<int32_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(VectorVectorTestI32, AdditionComparisonRandom) {
      59           1 :     const size_t size = 3333;
      60             : 
      61             :     // Create random number generator
      62           1 :     std::mt19937 rng(std::random_device{}());
      63           1 :     std::uniform_int_distribution<int32_t> dist(-1000, 1000);
      64             : 
      65             :     // Generate random vectors
      66           1 :     std::vector<int32_t> vec1(size);
      67           1 :     std::vector<int32_t> vec2(size);
      68        3334 :     for (size_t i = 0; i < size; ++i) {
      69        3333 :         vec1[i] = dist(rng);
      70        3333 :         vec2[i] = dist(rng);
      71             :     }
      72             : 
      73             :     // Perform vector addition using INTRINSIC and standard methods
      74           1 :     std::vector<int32_t> result_intrin(size);
      75           1 :     std::vector<int32_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             : 
      86           4 : TEST(VectorVectorTestI32, AdditionPerformanceComparison) {
      87           1 :     const size_t size = 3333 * 3333;
      88             : 
      89           1 :     TEST_COUT << "Vector size      : " << size << std::endl;
      90             :     // Create random number generator
      91           1 :     std::mt19937 rng(std::random_device{}());
      92           1 :     std::uniform_int_distribution<int32_t> dist(-1000, 1000);
      93             : 
      94             :     // Generate random vectors
      95           1 :     std::vector<int32_t> vec1(size);
      96           1 :     std::vector<int32_t> vec2(size);
      97    11108890 :     for (size_t i = 0; i < size; ++i) {
      98    11108889 :         vec1[i] = dist(rng);
      99    11108889 :         vec2[i] = dist(rng);
     100             :     }
     101             : 
     102             :     // Measure execution time for INTRINSIC vector addition
     103           1 :     std::vector<int32_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<int32_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           1 : }
     127             : 
     128           4 : TEST(VectorVectorTestI32, Subtraction) {
     129             :     // Create input vectors
     130           1 :     std::vector<int32_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
     131           1 :     std::vector<int32_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
     132           1 :     std::vector<int32_t> result(vec1.size());
     133             : 
     134             :     // Perform vector subtraction
     135           1 :     gpmp::linalg::vector_sub(vec1, vec2, result);
     136             : 
     137             :     // Check the result
     138           1 :     EXPECT_EQ(result.size(), vec1.size());
     139           9 :     for (size_t i = 0; i < result.size(); ++i) {
     140           8 :         EXPECT_EQ(result[i], vec1[i] - vec2[i]);
     141             :     }
     142           1 : }
     143             : 
     144           4 : TEST(VectorVectorTestI32, SubtractionComparison) {
     145             :     // Create input vectors
     146           1 :     std::vector<int32_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
     147           1 :     std::vector<int32_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
     148           1 :     std::vector<int32_t> result_intrin(vec1.size());
     149           1 :     std::vector<int32_t> result_std(vec1.size());
     150             : 
     151             :     // Perform vector subtraction using INTRINSIC and standard methods
     152           1 :     gpmp::linalg::vector_sub(vec1, vec2, result_intrin);
     153           1 :     gpmp::linalg::std_vector_sub(vec1, vec2, result_std);
     154             : 
     155             :     // Check if the results match
     156           1 :     ASSERT_EQ(result_intrin.size(), result_std.size());
     157           9 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     158           8 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     159             :     }
     160           1 : }
     161             : 
     162           4 : TEST(VectorVectorTestI32, SubtractionComparisonRandom) {
     163           1 :     const size_t size = 3333;
     164             : 
     165             :     // Create random number generator
     166           1 :     std::mt19937 rng(std::random_device{}());
     167           1 :     std::uniform_int_distribution<int32_t> dist(-1000, 1000);
     168             : 
     169             :     // Generate random vectors
     170           1 :     std::vector<int32_t> vec1(size);
     171           1 :     std::vector<int32_t> vec2(size);
     172        3334 :     for (size_t i = 0; i < size; ++i) {
     173        3333 :         vec1[i] = dist(rng);
     174        3333 :         vec2[i] = dist(rng);
     175             :     }
     176             : 
     177             :     // Perform vector subtraction using INTRINSIC and standard methods
     178           1 :     std::vector<int32_t> result_intrin(size);
     179           1 :     std::vector<int32_t> result_std(size);
     180           1 :     gpmp::linalg::vector_sub(vec1, vec2, result_intrin);
     181           1 :     gpmp::linalg::std_vector_sub(vec1, vec2, result_std);
     182             : 
     183             :     // Check if the results match
     184           1 :     ASSERT_EQ(result_intrin.size(), result_std.size());
     185        3334 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     186        3333 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     187             :     }
     188           1 : }
     189             : 
     190           4 : TEST(VectorVectorTestI32, SubtractionPerformanceComparison) {
     191           1 :     const size_t size = 3333 * 3333;
     192             : 
     193           1 :     TEST_COUT << "Vector size      : " << size << std::endl;
     194             :     // Create random number generator
     195           1 :     std::mt19937 rng(std::random_device{}());
     196           1 :     std::uniform_int_distribution<int32_t> dist(-1000, 1000);
     197             : 
     198             :     // Generate random vectors
     199           1 :     std::vector<int32_t> vec1(size);
     200           1 :     std::vector<int32_t> vec2(size);
     201    11108890 :     for (size_t i = 0; i < size; ++i) {
     202    11108889 :         vec1[i] = dist(rng);
     203    11108889 :         vec2[i] = dist(rng);
     204             :     }
     205             : 
     206             :     // Measure execution time for INTRINSIC vector addition
     207           1 :     std::vector<int32_t> result_intrin(size);
     208             : 
     209           1 :     auto start_intrin = std::chrono::high_resolution_clock::now();
     210           1 :     gpmp::linalg::vector_sub(vec1, vec2, result_intrin);
     211           1 :     auto end_intrin = std::chrono::high_resolution_clock::now();
     212             : 
     213             :     std::chrono::duration<double> elapsed_seconds_intrin =
     214           1 :         end_intrin - start_intrin;
     215             : 
     216             :     // Measure execution time for standard vector addition
     217           1 :     std::vector<int32_t> result_std(size);
     218             : 
     219           1 :     auto start_std = std::chrono::high_resolution_clock::now();
     220           1 :     gpmp::linalg::std_vector_sub(vec1, vec2, result_std);
     221           1 :     auto end_std = std::chrono::high_resolution_clock::now();
     222             : 
     223           1 :     std::chrono::duration<double> elapsed_seconds_std = end_std - start_std;
     224             : 
     225           1 :     TEST_COUT << "INTRINSIC Vector Subtraction Time      : "
     226           1 :               << elapsed_seconds_intrin.count() << " seconds" << std::endl;
     227             : 
     228           1 :     TEST_COUT << "STANDARD  Vector Subtraction Time      : "
     229           1 :               << elapsed_seconds_std.count() << " seconds" << std::endl;
     230           1 :     ASSERT_EQ(result_intrin.size(), result_std.size());
     231    11108890 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     232    11108889 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     233             :     }
     234           1 : }
     235             : 
     236             : // Unit test for vector multiplication using INTRINSIC intrinsics
     237           4 : TEST(VectorVectorTestI32, Multiplication) {
     238             :     // Create input vector and scalar
     239           1 :     std::vector<int32_t> vec = {1, 2, 3, 4, 5, 6, 7, 8};
     240           1 :     int scalar = 2;
     241           1 :     std::vector<int32_t> result(vec.size());
     242             : 
     243             :     // Perform vector multiplication
     244           1 :     gpmp::linalg::scalar_mult(vec, scalar, result);
     245             : 
     246             :     // Check the result
     247           9 :     for (size_t i = 0; i < result.size(); ++i) {
     248           8 :         EXPECT_EQ(result[i], vec[i] * scalar);
     249             :     }
     250           1 : }
     251             : 
     252             : // Unit test to compare results of INTRINSIC vector multiplication with standard
     253             : // vector multiplication
     254           4 : TEST(VectorVectorTestI32, MultComparison) {
     255             :     // Create input vector and scalar
     256           1 :     std::vector<int32_t> vec = {1, 2, 3, 4, 5, 6, 7, 8};
     257           1 :     int scalar = 2;
     258           1 :     std::vector<int32_t> result_intrin(vec.size());
     259           1 :     std::vector<int32_t> result_std(vec.size());
     260             : 
     261             :     // Perform vector multiplication using INTRINSIC and standard methods
     262           1 :     gpmp::linalg::scalar_mult(vec, scalar, result_intrin);
     263           1 :     gpmp::linalg::std_scalar_mult(vec, scalar, result_std);
     264             : 
     265             :     // Check if the results match
     266           9 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     267           8 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     268             :     }
     269           1 : }
     270             : 
     271             : // Unit test to compare results of INTRINSIC vector multiplication with standard
     272             : // vector multiplication using random vectors
     273           4 : TEST(VectorVectorTestI32, MultComparisonRandom) {
     274           1 :     const size_t size = 3333;
     275             : 
     276             :     // Create random number generator
     277           1 :     std::mt19937 rng(std::random_device{}());
     278           1 :     std::uniform_int_distribution<int32_t> dist(-1000, 1000);
     279             : 
     280             :     // Generate random vector and scalar
     281           1 :     std::vector<int32_t> vec(size);
     282           1 :     int scalar = dist(rng);
     283        3334 :     for (size_t i = 0; i < size; ++i) {
     284        3333 :         vec[i] = dist(rng);
     285             :     }
     286             : 
     287             :     // Perform vector multiplication using INTRINSIC and standard methods
     288           1 :     std::vector<int32_t> result_intrin(size);
     289           1 :     std::vector<int32_t> result_std(size);
     290           1 :     gpmp::linalg::scalar_mult(vec, scalar, result_intrin);
     291           1 :     gpmp::linalg::std_scalar_mult(vec, scalar, result_std);
     292             : 
     293             :     // Check if the results match
     294        3334 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     295        3333 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     296             :     }
     297           1 : }
     298             : 
     299           4 : TEST(VectorVectorTestI32, MultPerformanceComparison) {
     300           1 :     const size_t size = 3333 * 3333;
     301           1 :     TEST_COUT << "Vector size      : " << size << std::endl;
     302             : 
     303             :     // Create random number generator
     304           1 :     std::mt19937 rng(std::random_device{}());
     305           1 :     std::uniform_int_distribution<int32_t> dist(-1000, 1000);
     306             : 
     307             :     // Generate random vector and scalar
     308           1 :     std::vector<int32_t> vec(size);
     309           1 :     int scalar = dist(rng);
     310    11108890 :     for (size_t i = 0; i < size; ++i) {
     311    11108889 :         vec[i] = dist(rng);
     312             :     }
     313             : 
     314             :     // Measure execution time for INTRINSIC vector multiplication
     315           1 :     std::vector<int32_t> result_intrin(size);
     316           1 :     auto start_intrin = std::chrono::high_resolution_clock::now();
     317           1 :     gpmp::linalg::scalar_mult(vec, scalar, result_intrin);
     318           1 :     auto end_intrin = std::chrono::high_resolution_clock::now();
     319             :     std::chrono::duration<double> elapsed_seconds_intrin =
     320           1 :         end_intrin - start_intrin;
     321             : 
     322             :     // Measure execution time for standard vector multiplication
     323           1 :     std::vector<int32_t> result_std(size);
     324           1 :     auto start_std = std::chrono::high_resolution_clock::now();
     325           1 :     gpmp::linalg::std_scalar_mult(vec, scalar, result_std);
     326           1 :     auto end_std = std::chrono::high_resolution_clock::now();
     327           1 :     std::chrono::duration<double> elapsed_seconds_std = end_std - start_std;
     328             : 
     329             :     // Print the results
     330           1 :     TEST_COUT << "INTRINSIC Vector Multiplication Time      : "
     331           1 :               << elapsed_seconds_intrin.count() << " seconds" << std::endl;
     332           1 :     TEST_COUT << "STANDARD  Vector Multiplication Time      : "
     333           1 :               << elapsed_seconds_std.count() << " seconds" << std::endl;
     334             : 
     335             :     // Check if the results match
     336    11108890 :     for (size_t i = 0; i < result_intrin.size(); ++i) {
     337    11108889 :         EXPECT_EQ(result_intrin[i], result_std[i]);
     338             :     }
     339           1 : }
     340             : 
     341             : // Unit test for dot product using INTRINSIC intrinsics
     342           4 : TEST(VectorVectorTestI32, DotProduct) {
     343             :     // Create input vectors
     344           1 :     std::vector<int32_t> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
     345           1 :     std::vector<int32_t> vec2 = {8, 7, 6, 5, 4, 3, 2, 1};
     346             : 
     347             :     // Calculate dot product
     348           1 :     int result = gpmp::linalg::dot_product(vec1, vec2);
     349             : 
     350             :     // Expected result
     351           1 :     int expected_result = 120;
     352             : 
     353             :     // Check the result
     354           1 :     EXPECT_EQ(result, expected_result);
     355           1 : }
     356             : 
     357             : // Unit test for dot product using INTRINSIC intrinsics with random vectors
     358           4 : TEST(VectorVectorTestI32, DotProductRandom) {
     359           1 :     const size_t size = 3333;
     360             : 
     361             :     // Create random number generator
     362           1 :     std::mt19937 rng(std::random_device{}());
     363           1 :     std::uniform_int_distribution<int32_t> dist(-1000, 1000);
     364             : 
     365             :     // Generate random vectors
     366           1 :     std::vector<int32_t> vec1(size);
     367           1 :     std::vector<int32_t> vec2(size);
     368        3334 :     for (size_t i = 0; i < size; ++i) {
     369        3333 :         vec1[i] = dist(rng);
     370        3333 :         vec2[i] = dist(rng);
     371             :     }
     372             : 
     373             :     // Calculate dot product using INTRINSIC intrinsics
     374           1 :     int result = gpmp::linalg::dot_product(vec1, vec2);
     375             : 
     376             :     // Calculate dot product using standard method
     377           1 :     int expected_result = 0;
     378        3334 :     for (size_t i = 0; i < size; ++i) {
     379        3333 :         expected_result += vec1[i] * vec2[i];
     380             :     }
     381             : 
     382             :     // Check the result
     383           1 :     EXPECT_EQ(result, expected_result);
     384           1 : }
     385             : 
     386           4 : TEST(VectorVectorTestI32, DotProductPerformanceComparison) {
     387           1 :     const size_t size = 3333 * 3333;
     388           1 :     TEST_COUT << "Vector size      : " << size << std::endl;
     389             : 
     390             :     // Create input vectors
     391           1 :     std::vector<int32_t> vec1(size, 1);
     392           1 :     std::vector<int32_t> vec2(size, 2);
     393             : 
     394             :     // Measure execution time for INTRINSIC dot product calculation
     395           1 :     auto start_intrin = std::chrono::high_resolution_clock::now();
     396           1 :     int result_intrin = gpmp::linalg::dot_product(vec1, vec2);
     397           1 :     auto end_intrin = std::chrono::high_resolution_clock::now();
     398             :     std::chrono::duration<double> elapsed_seconds_intrin =
     399           1 :         end_intrin - start_intrin;
     400             : 
     401             :     // Measure execution time for standard dot product calculation
     402           1 :     auto start_std = std::chrono::high_resolution_clock::now();
     403           1 :     int result_std = gpmp::linalg::std_dot_product(vec1, vec2);
     404           1 :     auto end_std = std::chrono::high_resolution_clock::now();
     405           1 :     std::chrono::duration<double> elapsed_seconds_std = end_std - start_std;
     406             : 
     407             :     // Print the results
     408           1 :     TEST_COUT << "INTRINSIC Dot Product Time      : "
     409           1 :               << elapsed_seconds_intrin.count() << " seconds" << std::endl;
     410           1 :     TEST_COUT << "STANDARD  Dot Product Time      : "
     411           1 :               << elapsed_seconds_std.count() << " seconds" << std::endl;
     412             : 
     413           1 :     EXPECT_EQ(result_std, result_intrin);
     414           1 : }

Generated by: LCOV version 1.14