Ordner Inhalt, Dateien müssen selbst gebaut werden:
./DEV/XBTGPUARC
-> Ordner: logs (noch keine Logs bisher Notwendig gewesen, fliegt evtl wieder raus)
-> Ordner: kernels (Aufgeschlüsselt unten)
-> Makefile (Aufgeschlüsselt unten)
-> main.cpp (Aufgeschlüsselt unten)
-> run.sh (Aufgeschlüsselt unten)
Aufgeschlüsselte Dateien im Detail:
Makefile
CXX = g++
CXXFLAGS = -std=c++17 -Wall -O2
LDFLAGS = -lOpenCL
SRC = main.cpp
OUT = xbtgpuarc
all:
$(CXX) $(CXXFLAGS) $(SRC) -o $(OUT) $(LDFLAGS)
clean:
rm -f $(OUT)
main.cpp
#include
#include <CL/cl.h>
#include
#include
#include
#include
#include
#include
int main(int argc, char** argv) {
int platform_index = 0;
int device_index = 0;
int intensity = 4;
std::string algo = "zhash_144_5";
std::string kernel_file = "kernels/zhash_144_5.cl";
std::string kernel_name = "zhash_144_5";
// Kommandozeilenargumente verarbeiten
for (int i = 1; i < argc; ++i) {
if (std::string(argv[i]) == "--platform" && i + 1 < argc)
platform_index = std::atoi(argv[++i]);
else if (std::string(argv[i]) == "--device" && i + 1 < argc)
device_index = std::atoi(argv[++i]);
else if (std::string(argv[i]) == "--intensity" && i + 1 < argc)
intensity = std::atoi(argv[++i]);
else if (std::string(argv[i]) == "--algo" && i + 1 < argc) {
algo = argv[++i];
if (algo == "zhash_144_5") {
kernel_file = "kernels/zhash_144_5.cl";
kernel_name = "zhash_144_5";
} else {
kernel_file = "kernels/" + algo + ".cl";
kernel_name = algo;
}
}
}
auto start = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end - start;
std::cout << "\n⏱️ Laufzeit: " << elapsed.count() << " ms\n";
std::cout << "🧮 WorkItems: " << globalWorkSize << "\n";
std::cout << "🧠 Intensity: " << intensity << "\n";
std::cout << "🚀 Starte XBTGPUARC\nAlgo: " << algo << std::endl;
// Plattformen ermitteln
cl_uint platformCount;
clGetPlatformIDs(0, nullptr, &platformCount);
std::vector<cl_platform_id> platforms(platformCount);
clGetPlatformIDs(platformCount, platforms.data(), nullptr);
if (platform_index >= (int)platformCount) {
std::cerr << "Ungültiger Plattform-Index\n";
return 1;
}
cl_platform_id platform = platforms[platform_index];
// Geräte ermitteln
cl_uint deviceCount;
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, nullptr, &deviceCount);
std::vector<cl_device_id> devices(deviceCount);
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, deviceCount, devices.data(), nullptr);
if (device_index >= (int)deviceCount) {
std::cerr << "Ungültiger Geräteindex\n";
return 1;
}
cl_device_id device = devices[device_index];
size_t nameSize;
clGetDeviceInfo(device, CL_DEVICE_NAME, 0, nullptr, &nameSize);
std::vector<char> name(nameSize);
clGetDeviceInfo(device, CL_DEVICE_NAME, nameSize, name.data(), nullptr);
std::cout << "\nPlattform: " << platform_index
<< " | Gerät: " << name.data()
<< "\nIntensität: " << intensity << std::endl;
// Kontext und Queue erstellen
cl_int err;
cl_context context = clCreateContext(nullptr, 1, &device, nullptr, nullptr, &err);
cl_queue_properties props[] = {CL_QUEUE_PROPERTIES, 0, 0};
cl_command_queue queue = clCreateCommandQueueWithProperties(context, device, props, &err);
// Kernel-Quelltext laden
std::ifstream file(kernel_file);
if (!file.is_open()) {
std::cerr << "❌ Fehler beim Öffnen der Kernel-Datei: " << kernel_file << std::endl;
return 1;
}
std::string source((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
const char* src = source.c_str();
// Programm kompilieren
cl_program program = clCreateProgramWithSource(context, 1, &src, nullptr, &err);
cl_int buildErr = clBuildProgram(program, 1, &device, nullptr, nullptr, nullptr);
if (buildErr != CL_SUCCESS) {
size_t log_size;
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, nullptr, &log_size);
std::vector<char> build_log(log_size);
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size, build_log.data(), nullptr);
std::cerr << "❌ Build Log:\n" << build_log.data() << std::endl;
return 1;
}
// 🔧 Kernel erstellen
cl_kernel kernel = clCreateKernel(program, kernel_name.c_str(), &err);
if (err != CL_SUCCESS) {
std::cerr << "❌ Fehler beim Erstellen des Kernels: " << err << std::endl;
return 1;
}
// 🧪 Beispiel-Daten erzeugen
std::vector<uchar> input(intensity * 4);
for (size_t i = 0; i < input.size(); ++i)
input[i] = std::rand() % 256;
// 📦 Input-Puffer
cl_mem inputBuffer = clCreateBuffer(context,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
input.size(), input.data(), &err);
if (err != CL_SUCCESS) {
std::cerr << "❌ Fehler beim Erstellen des inputBuffer: " << err << std::endl;
return 1;
}
// 📦 Output-Puffer
cl_mem outBuffer = clCreateBuffer(context,
CL_MEM_WRITE_ONLY,
input.size(), nullptr, &err);
if (err != CL_SUCCESS) {
std::cerr << "❌ Fehler beim Erstellen des outBuffer: " << err << std::endl;
return 1;
}
// 🎛️ Kernel-Argumente setzen
err = clSetKernelArg(kernel, 0, sizeof(int), &intensity);
err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &inputBuffer);
err |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &outBuffer);
if (err != CL_SUCCESS) {
std::cerr << "❌ Fehler beim Setzen der Kernel-Argumente: " << err << std::endl;
return 1;
}
// 🧠 WorkSize = Anzahl WorkItems
size_t globalWorkSize = static_cast<size_t>(intensity);
// ⏱️ Kernel starten & messen
auto start = std::chrono::high_resolution_clock::now();
err = clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &globalWorkSize, nullptr, 0, nullptr, nullptr);
if (err != CL_SUCCESS) {
std::cerr << "❌ Fehler beim Enqueue des Kernels: " << err << std::endl;
return 1;
}
clFinish(queue);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end - start;
std::cout << "\n⏱️ Laufzeit: " << elapsed.count() << " ms\n";
// 📥 Ergebnisse auslesen
std::vector<char> result(input.size());
clEnqueueReadBuffer(queue, outBuffer, CL_TRUE, 0, result.size(), result.data(), 0, nullptr, nullptr);
// 📊 Input anzeigen
std::cout << "🔍 Input-Daten:\n";
for (size_t i = 0; i < input.size(); i += 4) {
std::cout << "[" << (int)(uchar)input[i] << " "
<< (int)(uchar)input[i + 1] << " "
<< (int)(uchar)input[i + 2] << " "
<< (int)(uchar)input[i + 3] << "] ";
}
std::cout << "\n";
// 📊 Output anzeigen
std::cout << "✅ Output-Daten:\n";
for (size_t i = 0; i < result.size(); i += 4) {
std::cout << "[" << (int)(uchar)result[i] << " "
<< (int)(uchar)result[i + 1] << " "
<< (int)(uchar)result[i + 2] << " "
<< (int)(uchar)result[i + 3] << "] ";
}
std::cout << "\n";
// Aufräumen
clReleaseMemObject(inputBuffer);
clReleaseMemObject(outBuffer);
clReleaseKernel(kernel);
clReleaseProgram(program);
clReleaseCommandQueue(queue);
clReleaseContext(context);
return 0;
}
run.sh
#!/bin/bash
export GPU_MAX_HEAP_SIZE=100
export GPU_MAX_USE_SYNC_OBJECTS=1
export GPU_SINGLE_ALLOC_PERCENT=100
export GPU_MAX_ALLOC_PERCENT=100
export GPU_MAX_SINGLE_ALLOC_PERCENT=100
export GPU_ENABLE_LARGE_ALLOCATION=100
export GPU_MAX_WORKGROUP_SIZE=1024
./xbtgpuarc --platform 0 --device 0 --algo zhash_144_5 --intensity 4
zhash_144_5.cpp (alter Kernel! Aktueller aber noch nicht Funktionsfähig!)
// kernels/zhash_144_5.cl
__constant uchar blake2b_IV[8][8] = {
{0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08},
{0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b},
{0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b},
{0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1},
{0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1},
{0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f},
{0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b},
{0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79}
};
// Linksrotation für 32 Bit
inline uint rotl32(uint x, uint n) {
return (x << n) | (x >> (32 - n));
}
inline void G(uint2 *a, uint2 *b, uint2 *c, uint2 *d, uint r1, uint r2) {
// Addieren
a->x += b->x; a->y += b->y;
// XOR + rotieren
d->x ^= a->x; d->y ^= a->y;
d->x = rotl32(d->x, r1); d->y = rotl32(d->y, r1);
// Addieren
c->x += d->x; c->y += d->y;
// XOR + rotieren
b->x ^= c->x; b->y ^= c->y;
b->x = rotl32(b->x, r2); b->y = rotl32(b->y, r2);
}
// Einfacher XOR für uchar4
inline uchar4 simple_xor(uchar4 a, uchar4 b) {
return (uchar4)(a.x ^ b.x, a.y ^ b.y, a.z ^ b.z, a.w ^ b.w);
}
__kernel void zhash_144_5(int intensity, __global uchar* output) {
int gid = get_global_id(0);
uchar val = (uchar)((gid + intensity) & 0xFF);
output[gid * 4 + 0] = val;
output[gid * 4 + 1] = val + 1;
output[gid * 4 + 2] = val + 2;
output[gid * 4 + 3] = val + 3;
}
Ich glaube das es das war? Wenn man Fragen hat einfach Fragen.^^ Ich habe keine Ahnung.
Nur das des heute net aus der Luft geboren wurde hier.^^
Edit zwei Stunden habsch mich mit den Tabellen rumgestritten und naja jetzt haben wir eine eigene Wertetabelle in Arbeit für des Zeug das gilt also nemmer was ich vorher geschrieben hatte in den Posts über die Intensität. Ein Gefummel. Aber des macht auch Laune.
Der wollte halt sagen, das man in der run.sh, jetzt mit der Intensity rumspielen kann, aber net so wie ich des vorher behauptet habe, die werte, sind andere jetzt die auswertung ist noch net durch bei mir. Der hat völlig verrücktes Zeug gelabert die KI was des Thema angeht. Aber später wieder mehr dazu.
Salve
Alucian
Edit sagt und wenns net geht, mal guggen ob die Plattform und des Device gefunden wird bei sich und wenn net is des komisch wenn net dann ist es keine ARC Grafikkarte mit OpenCL oder die ganzen Tools für Linux im Hintergrund fehlen das ist auch noch was man machen sollte. Aber wer damit rumspielt weis des sowieso vermutlich. :-)