Skip to content
Extraits de code Groupes Projets
main.cpp 5,31 ko
Newer Older
  • Learn to ignore specific revisions
  • JordanHanotiaux's avatar
    JordanHanotiaux a validé
    #include "matrix_opencl.hpp"
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    // Remplace ceci par un header propre si possible
    // #include "mlp_sgd.cpp"  <-- Éviter cela
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    #include <iostream>
    #include <vector>
    #include <cassert>
    #include <stdexcept>
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    #include <cmath>
    #include <limits>
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    #include <chrono>
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    // Helper function to print a matrix (copies to host first)
    void printMatrix(const std::string& label, const MatrixCL& mat) {
        std::cout << label << " (" << mat.numRows() << "x" << mat.numCols() << "):\n";
        try {
            std::vector<float> host_data = mat.copyToHost();
            for (int i = 0; i < mat.numRows(); ++i) {
                std::cout << "  [";
                for (int j = 0; j < mat.numCols(); ++j) {
                    std::cout << " " << host_data[i * mat.numCols() + j];
                }
                std::cout << " ]\n";
            }
             std::cout << std::endl;
        } catch (const std::runtime_error& e) {
            std::cerr << "Error printing matrix: " << e.what() << std::endl;
        }
    }
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    // Helper function for approximate float comparison
    bool approxEqual(float a, float b, float epsilon = 1e-5f) {
        return std::abs(a - b) < epsilon;
    }
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    // Helper function to verify matrix contents
    bool verifyMatrix(const std::string& label, const MatrixCL& mat, const std::vector<float>& expected, float epsilon = 1e-5f) {
        std::cout << "Verifying " << label << "..." << std::endl;
        if (static_cast<size_t>(mat.numRows() * mat.numCols()) != expected.size()) {
            std::cerr << "Verification failed: Dimension mismatch for " << label << ". Got "
                      << mat.numRows() << "x" << mat.numCols() << ", expected " << expected.size() << " elements." << std::endl;
            return false;
        }
        try {
            std::vector<float> actual = mat.copyToHost();
            bool match = true;
            for (size_t i = 0; i < actual.size(); ++i) {
                if (!approxEqual(actual[i], expected[i], epsilon)) {
                    std::cerr << "Verification failed for " << label << " at index " << i
                              << ". Got " << actual[i] << ", expected " << expected[i] << std::endl;
                    match = false;
                    // Don't break, report all mismatches if desired, or break here for efficiency
                     break;
                }
            }
            if (match) {
                std::cout << label << " verified successfully." << std::endl;
            } else {
                 std::cout << label << " verification failed." << std::endl;
            }
            return match;
        } catch (const std::runtime_error& e) {
            std::cerr << "Error verifying matrix " << label << ": " << e.what() << std::endl;
            return false;
        }
    }
    
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    cl_ulong getElapsedTime(const cl::Event& event) {
        cl_ulong start = event.getProfilingInfo<CL_PROFILING_COMMAND_START>();
        cl_ulong end = event.getProfilingInfo<CL_PROFILING_COMMAND_END>();
        return end - start; // In nanoseconds
    }
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    std::vector<float> fill_random(int rows, int cols) {
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
        std::vector<float> data(rows * cols);
        for (auto& val : data) {
            val = static_cast<float>(rand()) / RAND_MAX;
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
        }
        return data;
    }
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    int main(int argc, char** argv) {
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
        // 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();
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
        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;
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
                return 1;
            }
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
        }
        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);
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
        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;
        }
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
        const std::vector<int> sizes = {128, 256, 512, 1024, 2048, 4096, 8192, 10000};
        const int runs = 10;
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
        for (int size : sizes) {
            std::chrono::duration<double, std::milli> total_time(0);
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
            for (int i = 0; i < runs; ++i) {
                std::vector<float> dataA = fill_random(size, size);
                std::vector<float> dataB = fill_random(size, size);
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
                MatrixCL A(size, size, context, queue, &dataA);
                MatrixCL B(size, size, context, queue, &dataB);
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
                auto start = std::chrono::high_resolution_clock::now();
                MatrixCL C = A * B;
                queue.finish();
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
                auto end = std::chrono::high_resolution_clock::now();
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
                total_time += end - start;
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
            }
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
            double average_time = total_time.count() / runs;
            std::cout << size << "\t" << average_time << std::endl;
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
        }
    
        return 0;
    
    JordanHanotiaux's avatar
    JordanHanotiaux a validé
    }