Skip to content
Extraits de code Groupes Projets
Valider 2b65607b rédigé par JordanHanotiaux's avatar JordanHanotiaux
Parcourir les fichiers

Update main.cpp

parent d8854396
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -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;
}
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter