From 2b65607b76d345add04052369986cb7fcc78f428 Mon Sep 17 00:00:00 2001
From: JordanHanotiaux <103147288+JordanHanotiaux@users.noreply.github.com>
Date: Mon, 19 May 2025 10:21:04 +0200
Subject: [PATCH] Update main.cpp

---
 main.cpp | 192 +++++++++++++++++++------------------------------------
 1 file changed, 66 insertions(+), 126 deletions(-)

diff --git a/main.cpp b/main.cpp
index bd4711b..1b92107 100644
--- a/main.cpp
+++ b/main.cpp
@@ -71,151 +71,91 @@ cl_ulong getElapsedTime(const cl::Event& event) {
     return end - start; // In nanoseconds
 }
 
+std::vector<float> fill_random(int rows, int cols) {
+    std::mt19937 gen(42);
+    std::uniform_real_distribution<float> dist(-1.0f, 1.0f);
+    std::vector<float> data(rows*cols);
+    for (int i = 0; i < rows * cols; ++i) {
+        data[i] = dist(gen);
+    }
+    return data;
+}
 
-int main() {
-    try {
-        // --- OpenCL Setup ---
-        std::cout << "--- OpenCL Setup ---" << std::endl;
-
-        std::vector<cl::Platform> platforms;
-        cl::Platform::get(&platforms);
-        if (platforms.empty()) {
-            std::cerr << "No OpenCL platforms found." << std::endl;
-            return 1;
-        }
-
-        cl::Platform platform = platforms.front();
-        std::cout << "Using Platform: " << platform.getInfo<CL_PLATFORM_NAME>() << std::endl;
 
-        std::vector<cl::Device> devices;
-        platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
-        if (devices.empty()) {
-            std::cout << "No GPU found, trying CPU..." << std::endl;
-            platform.getDevices(CL_DEVICE_TYPE_CPU, &devices);
-            if (devices.empty()) {
-                std::cerr << "No OpenCL devices found." << std::endl;
-                return 1;
-            }
-        }
-
-        cl::Device device = devices.front();
-        std::cout << "Using Device: " << device.getInfo<CL_DEVICE_NAME>() << std::endl;
+int main(int argc, char** argv) {
+    if (argc < 3) {
+        std::cerr << "Usage: ./matrix_mul_exec <size> <runs>" << std::endl;
+        return 1;
+    }
 
-        cl::Context context(device);
-        cl_int err;
-        cl_command_queue q = clCreateCommandQueue(context(), device(), CL_QUEUE_PROFILING_ENABLE, &err);
-        if (err != CL_SUCCESS) {
-            std::cerr << "clCreateCommandQueue failed: " << err << std::endl;
-            exit(1);
-        }
-        cl::CommandQueue queue(q);
+    int size = std::stoi(argv[1]);
+    int runs = std::stoi(argv[2]);
 
+    // 1. --- OpenCL Setup ---
+    std::vector<cl::Platform> platforms;
+    cl::Platform::get(&platforms);
+    if (platforms.empty()) {
+        std::cerr << "No OpenCL platforms found." << std::endl;
+        return 1;
+    }
+    cl::Platform platform = platforms.front();
 
-        std::vector<cl::Device> devices_to_init = { device };
-        try {
-            MatrixCL::initializeKernels(context, devices_to_init);
-            std::cout << "Kernel initialization successful." << std::endl;
-        } catch (const std::exception& e) {
-            std::cerr << "FATAL ERROR during kernel initialization: " << e.what() << std::endl;
+    std::vector<cl::Device> devices;
+    platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
+    if (devices.empty()) {
+        platform.getDevices(CL_DEVICE_TYPE_CPU, &devices);
+        if (devices.empty()) {
+            std::cerr << "No OpenCL devices found." << std::endl;
             return 1;
         }
+    }
+    cl::Device device = devices.front();
+
+    cl::Context context(device);
+    cl_int err;
+    cl_command_queue cq = clCreateCommandQueue(context(), device(), CL_QUEUE_PROFILING_ENABLE, &err);
+    if (err != CL_SUCCESS) {
+        std::cerr << "Failed to create command queue: " << err << std::endl;
+        exit(1);
+    }
+    cl::CommandQueue queue(cq, true);
 
-        // --- Matrix Multiplication Benchmark ---
-        std::cout << "\n--- Matrix Multiplication Benchmark (growing sizes) ---" << std::endl;
-        std::vector<int> sizes = {1024};
-
-        for (int size : sizes) {
-            std::cout << "\nMultiplying " << size << "x" << size << " matrices..." << std::endl;
 
-            std::vector<float> dataA(size * size, 1.0f); // Matrix A filled with ones
-            std::vector<float> dataB(size * size, 2.0f); // Matrix B filled with twos
+    std::vector<cl::Device> devices_to_init = {device};
+    try {
+        MatrixCL::initializeKernels(context, devices_to_init);
+    } catch (const std::exception& e) {
+        // Catching std::exception here because initializeKernels wraps cl::Error
+        std::cerr << "FATAL ERROR during kernel initialization: " << e.what() << std::endl;
+        // If the error was a BuildError, the log should have been printed
+        // by the loadAndBuildProgram function within initializeKernels.
+        return 1;
+    }
 
-            MatrixCL matA(size, size, context, queue, &dataA);
-            MatrixCL matB(size, size, context, queue, &dataB);
-            MatrixCL result(size, size, context, queue); // Output matrix
+    const std::vector<int> sizes = {128, 256, 512, 1024, 2048, 4096, 8192, 10000};
+    const int runs = 10;
 
-            auto start = std::chrono::high_resolution_clock::now();
+    for (int size : sizes) {
+        std::chrono::duration<double, std::milli> total_time(0);
 
-            result = matA * matB; // Matrix multiplication
+        for (int i = 0; i < runs; ++i) {
+            std::vector<float> dataA = fill_random(size, size);
+            std::vector<float> dataB = fill_random(size, size);
 
-            queue.finish(); // S'assurer que le kernel est bien terminé
+            MatrixCL A(size, size, context, queue, &dataA);
+            MatrixCL B(size, size, context, queue, &dataB);
 
+            auto start = std::chrono::high_resolution_clock::now();
+            MatrixCL C = A * B;
+            queue.finish();
             auto end = std::chrono::high_resolution_clock::now();
-            auto elapsed_us = std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
 
-            std::cout << elapsed_us << " s " << std::endl;
-
-        }
-
-        // 2. --- Basic Matrix Operations Test ---
-        std::cout << "\n--- Basic Matrix Operations Test ---" << std::endl;
-
-        std::vector<float> dataA = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}; // 2x3
-        std::vector<float> dataB = {7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f}; // 2x3
-        std::vector<float> dataC = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f}; // 3x3
-
-        MatrixCL matA(2, 3, context, queue, &dataA);
-        MatrixCL matB(2, 3, context, queue, &dataB);
-        MatrixCL matC(3, 3, context, queue, &dataC);
-        MatrixCL matD(2, 3, context, queue); // Initialized to 0 by constructor
-
-        printMatrix("Matrix A (original)", matA);
-        printMatrix("Matrix B", matB);
-        printMatrix("Matrix C (3x3)", matC);
-        printMatrix("Matrix D (initially zero)", matD);
-
-        // Test fill
-        matD.fill(5.5f);
-        printMatrix("Matrix D after fill(5.5)", matD);
-        assert(verifyMatrix("Matrix D fill", matD, {5.5f, 5.5f, 5.5f, 5.5f, 5.5f, 5.5f}));
-
-        // Test Copy Constructor
-        MatrixCL matA_copy(matA);
-        printMatrix("Matrix A Copy (via copy constructor)", matA_copy);
-        assert(verifyMatrix("Matrix A Copy Ctor", matA_copy, dataA));
-
-        // Test Copy Assignment Operator
-        MatrixCL matD_assigned(1, 1, context, queue); // Create with different dimensions
-        matD_assigned = matD;
-        printMatrix("Matrix D Assigned (via assignment operator)", matD_assigned);
-        assert(verifyMatrix("Matrix D Assignment Op", matD_assigned, {5.5f, 5.5f, 5.5f, 5.5f, 5.5f, 5.5f}));
-
-
-        // Test Addition
-        MatrixCL matAdd = matA + matB;
-        printMatrix("Matrix A + B", matAdd);
-        assert(verifyMatrix("Matrix A + B", matAdd, {8.0f, 10.0f, 12.0f, 14.0f, 16.0f, 18.0f}));
-
-        // Test Transpose
-        MatrixCL matATrans = matA.transpose();
-        printMatrix("Matrix A Transposed", matATrans); // Should be 3x2
-        assert(verifyMatrix("Matrix A Transposed", matATrans, {1.0f, 4.0f, 2.0f, 5.0f, 3.0f, 6.0f}));
-
-        // Test Matrix Multiplication: A(2x3) * C(3x3) -> Result(2x3)
-        // Expected: [ (1*1+2*4+3*7) (1*2+2*5+3*8) (1*3+2*6+3*9) ] = [ 30 36 42 ]
-        //           [ (4*1+5*4+6*7) (4*2+5*5+6*8) (4*3+5*6+6*9) ] = [ 66 81 96 ]
-        MatrixCL matMul = matA * matC;
-        printMatrix("Matrix A * C", matMul);
-        assert(verifyMatrix("Matrix A * C", matMul, {30.0f, 36.0f, 42.0f, 66.0f, 81.0f, 96.0f}));
-
-
-    } catch (const cl::BuildError& err) {
-        std::cerr << "OpenCL Build Error: " << err.what() << " (" << err.err() << ")" << std::endl;
-        for (const auto& pair : err.getBuildLog()) {
-            std::cerr << "Device " << pair.first.getInfo<CL_DEVICE_NAME>() << " Build Log:\n"
-                      << pair.second << std::endl;
+            total_time += end - start;
         }
-        return 1;
 
-    } catch (const cl::Error& err) {
-        std::cerr << "OpenCL Error: " << err.what() << " (" << err.err() << ")" << std::endl;
-        return 1;
-
-    } catch (const std::exception& e) {
-        std::cerr << "Standard Exception: " << e.what() << std::endl;
-        return 1;
+        double average_time = total_time.count() / runs;
+        std::cout << size << "\t" << average_time << std::endl;
     }
 
-    std::cout << "\nAll OpenCL Matrix and MLP tests completed successfully." << std::endl;
     return 0;
 }
-- 
GitLab