good import.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
/docs/2025
|
||||
/CMakeCache.txt
|
||||
*.zip
|
||||
/build/
|
||||
|
||||
182
compile_test.cpp
Normal file
182
compile_test.cpp
Normal file
@ -0,0 +1,182 @@
|
||||
// opencl_cache.cpp
|
||||
#include <CL/opencl.hpp> // OpenCL C++ bindings
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <filesystem> // C++17
|
||||
#include <stdexcept>
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Helpers
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Read a text file into a string
|
||||
std::string read_file(const std::string &path)
|
||||
{
|
||||
std::ifstream f(path, std::ios::in | std::ios::binary);
|
||||
if (!f) throw std::runtime_error("Cannot open file: " + path);
|
||||
std::ostringstream ss;
|
||||
ss << f.rdbuf();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Read a binary file into a std::vector<uint8_t>
|
||||
std::vector<uint8_t> read_binary(const std::string &path)
|
||||
{
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
if (!f) throw std::runtime_error("Cannot open binary file: " + path);
|
||||
return std::vector<uint8_t>(std::istreambuf_iterator<char>(f),
|
||||
std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
// Write a binary buffer to file
|
||||
void write_binary(const std::string &path, const std::vector<uint8_t> &data)
|
||||
{
|
||||
std::ofstream f(path, std::ios::binary);
|
||||
if (!f) throw std::runtime_error("Cannot write binary file: " + path);
|
||||
f.write(reinterpret_cast<const char*>(data.data()), data.size());
|
||||
}
|
||||
|
||||
// Create a unique key for the device (vendor + name + global mem size)
|
||||
std::string device_key(const cl::Device &dev)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << dev.getInfo<CL_DEVICE_VENDOR>()
|
||||
<< "-" << dev.getInfo<CL_DEVICE_NAME>()
|
||||
<< "-" << dev.getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Main
|
||||
// -------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 1) Pick the first GPU device on the first platform
|
||||
std::vector<cl::Platform> platforms;
|
||||
cl::Platform::get(&platforms);
|
||||
if (platforms.empty())
|
||||
throw std::runtime_error("No OpenCL platforms found");
|
||||
|
||||
cl::Platform platform = platforms[0];
|
||||
std::vector<cl::Device> devices;
|
||||
platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
|
||||
if (devices.empty())
|
||||
throw std::runtime_error("No GPU devices on the platform");
|
||||
|
||||
cl::Device device = devices[0];
|
||||
std::cout << "Using platform: "
|
||||
<< platform.getInfo<CL_PLATFORM_NAME>() << '\n';
|
||||
std::cout << "Using device : "
|
||||
<< device.getInfo<CL_DEVICE_NAME>() << '\n';
|
||||
|
||||
// 2) Context & cache file name
|
||||
cl::Context ctx(device);
|
||||
std::string bin_file = device_key(device) + ".bin";
|
||||
std::filesystem::path bin_path = std::filesystem::current_path() / bin_file;
|
||||
|
||||
cl::Program program;
|
||||
|
||||
// 3) If we already have a binary, load it
|
||||
if (std::filesystem::exists(bin_path))
|
||||
{
|
||||
std::cout << "Loading binary from " << bin_path << '\n';
|
||||
std::vector<uint8_t> bin = read_binary(bin_path.string());
|
||||
|
||||
// OpenCL expects an array of *unsigned char* pointers, one per
|
||||
// device. We are using only one device here.
|
||||
std::vector<const unsigned char*> binaries(1, bin.data());
|
||||
std::vector<size_t> lengths(1, bin.size());
|
||||
|
||||
std::vector<cl::Program> progs(1);
|
||||
cl_int err = ctx.createProgramWithBinary(devices,
|
||||
lengths,
|
||||
binaries.data(),
|
||||
nullptr,
|
||||
&progs[0]);
|
||||
|
||||
if (err != CL_SUCCESS)
|
||||
throw std::runtime_error("clCreateProgramWithBinary failed");
|
||||
|
||||
program = progs[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4) Compile from source, extract the binary, save it
|
||||
|
||||
std::cout << "Compiling source (first run)...\n";
|
||||
|
||||
std::string src = read_file("example.cl");
|
||||
cl::Program::Sources srcs(1, { src.c_str(), src.length() + 1 });
|
||||
|
||||
program = cl::Program(ctx, srcs);
|
||||
cl_int err = program.build(devices);
|
||||
if (err != CL_SUCCESS)
|
||||
{
|
||||
std::string log = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device);
|
||||
throw std::runtime_error("Program build failed: " + log);
|
||||
}
|
||||
|
||||
// Retrieve the binary
|
||||
std::vector<unsigned char> bin;
|
||||
std::vector<size_t> lengths;
|
||||
program.getInfo(CL_PROGRAM_BINARY_SIZES, &lengths);
|
||||
program.getInfo(CL_PROGRAM_BINARIES, &bin);
|
||||
|
||||
// Save it for next run
|
||||
write_binary(bin_path.string(), std::vector<uint8_t>(bin.begin(), bin.end()));
|
||||
std::cout << "Saved binary to " << bin_path << '\n';
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 5) Demo: add two float vectors
|
||||
// -------------------------------------------------------------------
|
||||
size_t N = 1024;
|
||||
std::vector<float> a(N, 1.0f), b(N, 2.0f), c(N, 0.0f);
|
||||
|
||||
// Allocate device buffers
|
||||
cl::Buffer bufA(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
sizeof(float) * N, a.data());
|
||||
cl::Buffer bufB(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
sizeof(float) * N, b.data());
|
||||
cl::Buffer bufC(ctx, CL_MEM_WRITE_ONLY,
|
||||
sizeof(float) * N);
|
||||
|
||||
// Create kernel
|
||||
cl::Kernel kernel(program, "add_vectors");
|
||||
|
||||
// Set arguments
|
||||
kernel.setArg(0, bufA);
|
||||
kernel.setArg(1, bufB);
|
||||
kernel.setArg(2, bufC);
|
||||
|
||||
// Launch
|
||||
cl::CommandQueue queue(ctx, device);
|
||||
queue.enqueueNDRangeKernel(kernel, cl::NullRange,
|
||||
cl::NDRange(N), cl::NullRange);
|
||||
queue.finish();
|
||||
|
||||
// Read back
|
||||
queue.enqueueReadBuffer(bufC, CL_TRUE, 0,
|
||||
sizeof(float) * N, c.data());
|
||||
|
||||
// Verify a few elements
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
if (c[i] != a[i] + b[i]) { ok = false; break; }
|
||||
}
|
||||
std::cout << "Demo " << (ok ? "succeeded" : "failed") << '\n';
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cerr << "ERROR: " << e.what() << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using OpenCL, pocl_jll
|
||||
using BenchmarkTools
|
||||
|
||||
function vadd(a, b, c)
|
||||
gid = get_global_id(1)
|
||||
@ -6,28 +7,11 @@ function vadd(a, b, c)
|
||||
return
|
||||
end
|
||||
|
||||
a = rand(Float32, 50_000)
|
||||
b = rand(Float32, 50_000)
|
||||
|
||||
d_a = CLArray(a)
|
||||
d_b = CLArray(b)
|
||||
d_c = similar(d_a)
|
||||
|
||||
@opencl global_size=size(a) vadd(d_a, d_b, d_c)
|
||||
|
||||
c = Array(d_c)
|
||||
|
||||
@assert a + b ≈ c
|
||||
using OpenCL, pocl_jll
|
||||
|
||||
function vadd(a, b, c)
|
||||
gid = get_global_id(1)
|
||||
@inbounds c[gid] = a[gid] + b[gid]
|
||||
return
|
||||
end
|
||||
|
||||
a = rand(Float32, 50_000)
|
||||
b = rand(Float32, 50_000)
|
||||
size = 50
|
||||
|
||||
a = rand(Float32, size)
|
||||
b = rand(Float32, size)
|
||||
|
||||
|
||||
d_a = CLArray(a)
|
||||
d_b = CLArray(b)
|
||||
|
||||
29
src/main.cpp
29
src/main.cpp
@ -3,7 +3,7 @@
|
||||
#include <vector>
|
||||
|
||||
// opencl
|
||||
#include <CL/cl.hpp>
|
||||
#include <CL/opencl.hpp>
|
||||
// raylib
|
||||
// #include <raylib.h>
|
||||
// sqllite
|
||||
@ -11,12 +11,25 @@
|
||||
|
||||
//#include "include/layers.hpp"
|
||||
|
||||
cl::Platform select_platform (){
|
||||
|
||||
std::vector<cl::Platform> all_platforms;
|
||||
cl::Platform::get(&all_platforms);
|
||||
if(all_platforms.size() == 0)
|
||||
{
|
||||
std::cout << "No Platforms found. Check OpenCl installation!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return all_platforms[0];
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
// import data
|
||||
|
||||
cl::Platform default_platform=select_platform();
|
||||
std::cout << "Using platform: "<<default_platform.getInfo<CL_PLATFORM_NAME>()<<"\n";
|
||||
std::cout << "Using platform: "<< default_platform.getInfo<CL_PLATFORM_NAME>() <<"\n";
|
||||
|
||||
return 0;
|
||||
|
||||
@ -29,15 +42,3 @@ int main(){
|
||||
// opencl sim (every 15 seconds) swap data every 15 seconds
|
||||
}
|
||||
|
||||
cl::Platform select_platform (){
|
||||
|
||||
std::vector<cl::Platform> all_platforms;
|
||||
cl::Platform::get(&all_platforms);
|
||||
if(all_platforms.size() == 0)
|
||||
{
|
||||
std::cout << "No Platforms found. Check OpenCl installation!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return all_platforms[0]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user