Newer
Older
// Remplace ceci par un header propre si possible
// #include "mlp_sgd.cpp" <-- Éviter cela
#include <iostream>
#include <vector>
#include <cassert>
#include <stdexcept>
// 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;
}
}
// Helper function for approximate float comparison
bool approxEqual(float a, float b, float epsilon = 1e-5f) {
return std::abs(a - b) < epsilon;
}
// 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;
}
}
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
}
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;
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);
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;
return 1;
}
// --- Matrix Multiplication Benchmark ---
std::cout << "\n--- Matrix Multiplication Benchmark (growing sizes) ---" << std::endl;
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
MatrixCL matA(size, size, context, queue, &dataA);
MatrixCL matB(size, size, context, queue, &dataB);
MatrixCL result(size, size, context, queue); // Output matrix
auto start = std::chrono::high_resolution_clock::now();
queue.finish(); // S'assurer que le kernel est bien terminé
auto end = std::chrono::high_resolution_clock::now();
auto elapsed_us = std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// 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}));
std::cerr << "OpenCL Build Error: " << err.what() << " (" << err.err() << ")" << std::endl;
std::cerr << "Device " << pair.first.getInfo<CL_DEVICE_NAME>() << " Build Log:\n"
<< pair.second << std::endl;
std::cerr << "OpenCL Error: " << err.what() << " (" << err.err() << ")" << std::endl;
return 1;
std::cerr << "Standard Exception: " << e.what() << std::endl;
return 1;
}
std::cout << "\nAll OpenCL Matrix and MLP tests completed successfully." << std::endl;
return 0;