XBTGPUARC Unfertig, aber ein bisschen weiter. Kernel im Folgepost wegen Länge und Größe. :-)

@alucian · 2025-08-29 12:37 · deutsch

//--XBTGPUARC-- //--Bitcoin Gold-- //--Zhash_144_5-- //--Equihash-- over //--Vector-- Calculations for //--Intel ARC Alchemist DG2 GPU--

//--Projekt: XBTGPUARC Miner-- //--Sprache: C++17 + OpenCL-- //--Ziel: Equihash 144,5 Mining auf Intel ARC GPUs--

//--kernels--

//-00--zhash.cl-Exclude-(We build around the Kernel!)--

//--XBTGPUARC_Dateien 0-13 sortiert A-Z-- //--1--globals.cpp-- //--2--globals.hpp-- //--3--main.cpp-- //--0--Makefile-- //--4--miner_loop.cpp-- //--5--miner_loop.hpp-- //--6--mining_job.hpp-- //--7--notify_parser.hpp-- //--8--opencl_utils_devices.cpp-- //--9--opencl_utils.cpp-- //--10--opencl_utils.hpp-- //--11--runs.sh-- //--12--stratum_notify_listener.cpp-- //--13.--stratum_notify_listener.hpp-- //--OpenCL-- //--C++17-- no changes in Codelanguage here without extra attention. All Data are made before Training. Program you see work in early state! Do not change significant Options or Code before EXTRA FAT WARNING! Questions about everything recommend and welcome. Lets work together!

//--Inhalt Dateien A-Z--


//--1--globals.cpp--


include "globals.hpp"

include "miner_loop.hpp"

//--Globale Variablen definieren--

bool abort_mining = false; bool socket_valid = false;

int next_request_id = 1; std::string current_job_id = ""; std::string worker_name = "";

std::array current_target = {};

//--Funktion implementieren--

void stop_mining() { abort_mining = true; }


//--2--globals.hpp--


pragma once

include

include

include

include

define INPUT_SIZE 512

define HASH_SIZE 32

define NONCES_PER_THREAD 1

define BUCKET_COUNT 32

define HASH_ROUNDS_OUTPUT_SIZE 32

struct GpuResources { cl_context context = nullptr; cl_command_queue queue = nullptr; cl_program program = nullptr; cl_kernel kernel = nullptr; cl_device_id device = nullptr; cl_mem input_buffer = nullptr; cl_mem output_buffer = nullptr; cl_mem output_hashes_buffer = nullptr; cl_mem pool_target_buffer = nullptr; };

extern int next_request_id; extern std::string current_job_id; extern std::string worker_name; extern bool abort_mining; extern bool socket_valid; extern std::array current_target;


//--3--main.cpp--


include "globals.hpp"

include "miner_loop.hpp"

include "mining_job.hpp"

include "notify_parser.hpp"

include "opencl_utils.hpp"

include "stratum_notify_listener.hpp"

include

include

include

include

include

include

include

//--Alle OpenCL-Geräte auflisten--

void list_opencl_devices() { cl_uint num_platforms = 0; cl_int err = clGetPlatformIDs(0, nullptr, &num_platforms); if (err != CL_SUCCESS) { std::cerr << "❌ Fehler bei clGetPlatformIDs: " << err << "\n"; return; }

std::vector platforms(num_platforms); clGetPlatformIDs(num_platforms, platforms.data(), nullptr);

std::cout << "🌍 Gefundene OpenCL-Plattformen: " << num_platforms << "\n";

for (cl_uint i = 0; i < num_platforms; ++i) { char name[128], vendor[128], version[128]; clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, sizeof(name), name, nullptr); clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(vendor), vendor, nullptr); clGetPlatformInfo(platforms[i], CL_PLATFORM_VERSION, sizeof(version), version, nullptr);

std::cout << "\n[Plattform " << i << "]\n";
std::cout << "  Name:    " << name << "\n";
std::cout << "  Vendor:  " << vendor << "\n";
std::cout << "  Version: " << version << "\n";

cl_uint num_devices = 0;
err = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, nullptr,
                     &num_devices);
if (err != CL_SUCCESS || num_devices == 0) {
  std::cout << "  ⚠️  Keine Geräte gefunden.\n";
  continue;
}

std::vector devices(num_devices);
clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, num_devices,
               devices.data(), nullptr);

for (cl_uint j = 0; j < num_devices; ++j) {
  char devname[128];
  clGetDeviceInfo(devices[j], CL_DEVICE_NAME, sizeof(devname), devname,
                  nullptr);
  std::cout << "    [Device " << j << "] " << devname << "\n";
}

} }

int main(int argc, char **argv) {

//--Default-Werte--

int platform_index = 0; int device_index = 0; int intensity = 256; std::string algo = "zhash_144_5"; std::string wallet = "Gb4V4a9Jk3p8aH6jkW3Aq3sq8rQCuJQ6S8"; std::string worker = "A730m"; std::string password = "x"; std::string pool_host = "solo-btg.2miners.com"; int pool_port = 4040;

//--🧾 Argumente parsen--

for (int i = 1; i < argc; ++i) { std::string arg = argv[i]; if (arg == "--platform" && i + 1 < argc) platform_index = std::atoi(argv[++i]); else if (arg == "--device" && i + 1 < argc) device_index = std::atoi(argv[++i]); else if (arg == "--intensity" && i + 1 < argc) intensity = std::atoi(argv[++i]); else if (arg == "--algo" && i + 1 < argc) algo = argv[++i]; else if (arg == "--wallet" && i + 1 < argc) wallet = argv[++i]; else if (arg == "--worker" && i + 1 < argc) worker = argv[++i]; else if (arg == "--password" && i + 1 < argc) password = argv[++i]; else if (arg == "--pool" && i + 1 < argc) pool_host = argv[++i]; else if (arg == "--port" && i + 1 < argc) pool_port = std::atoi(argv[++i]); else if (arg == "--help") { std::cout << "Usage: ./xbtgpuarc [options]\n" << "Options:\n" << " --platform N OpenCL Plattform-Index (default 0)\n" << " --device N OpenCL Geräte-Index (default 0)\n" << " --intensity N Threads pro Gerät (default 256)\n" << " --algo NAME Kernel/Algo-Name (default zhash_144_5)\n" << " --wallet ADDR Wallet-Adresse\n" << " --worker NAME Worker-Name\n" << " --password PASS Passwort für Pool (default 'x')\n" << " --pool HOST Pool-Adresse (default 2miners)\n" << " --port PORT Port (default 4040)\n"; return 0; } }

std::cout << "🚀 Starte XBTGPUARC mit Algo: " << algo << "\n"; std::cout << "👤 Worker: " << wallet << "." << worker << "\n"; std::cout << "🎛️ Platform: " << platform_index << " | Device: " << device_index << " | Intensity: " << intensity << "\n"; std::cout << "🌐 Pool: " << pool_host << ":" << pool_port << "\n";

list_opencl_devices();

//--Initialisiere OpenCL--

GpuResources resources; init_opencl("kernels/zhash.cl",algo, platform_index, device_index, intensity, resources);

//--Starte Stratum-Listener + Mining-Thread--

run_stratum_listener(pool_host, pool_port, wallet, worker, password, intensity, resources);

cleanup_opencl(resources); return 0; }


//--0--Makefile--


CXXFLAGS := -std=c++17 -Wall -O2 -DCL_TARGET_OPENCL_VERSION=300 -MMD -MP LDFLAGS := -lOpenCL -lboost_system -lboost_json -lpthread

Quellcode-Dateien

SRC := main.cpp \ miner_loop.cpp \ opencl_utils.cpp \ stratum_notify_listener.cpp \ globals.cpp

OBJ := $(SRC:.cpp=.o) DEPS := $(OBJ:.o=.d) OUT := xbtgpuarc

Optional: CPU-Miner

CPU_SRC := cpu_miner.cpp globals.cpp CPU_OBJ := $(CPU_SRC:.cpp=.o) CPU_OUT := cpu_miner CXXFLAGS := -std=c++17 -Wall -O3 -march=native -DCL_TARGET_OPENCL_VERSION=300 LDFLAGS := -lOpenCL -lboost_system -lboost_json -lpthread

Standard-Target

all: $(OUT)

Build des GPU-Miners

$(OUT): $(OBJ) $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)

Optional: CPU-Miner separat bauen

$(CPU_OUT): $(CPU_OBJ) $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)

Generisches Compile-Ziel

%.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@

Clean

clean: rm -f $(OUT) $(CPU_OUT) .o .d

-include $(DEPS)


//--4--miner_loop.cpp--


include "miner_loop.hpp"

include "mining_job.hpp"

include "opencl_utils.hpp"

include

include

include

include

include

include

include

include

include //--Für std::random_device und std::mt19937--

include

include

//--Externe Status-Variablen- //--Diese Variablen sind nicht in dieser Datei definiert, sondern werden von außen bereitgestellt.- //--Sie dienen dazu, den Abbruch des Minings oder den Status der Socket-Verbindung zu signalisieren.- //--Es sind einfache bool-Werte, die direkt gelesen werden.--

extern bool abort_mining; extern bool socket_valid;

namespace {

//--Prüft, ob ein Zeichen eine Hexadezimalziffer ist-
//--Eine Hexadezimalziffer ist 0-9 oder A-F (Groß- oder Kleinbuchstaben).--


inline bool is_hex_char(unsigned char c) {
    return std::isxdigit(c) != 0;
}

//--Prüft, ob ein String ein gültiger Hexadezimal-String ist-
//--Ein String ist gültig, wenn er leer ist oder nur Hexadezimalziffern enthält-
//--und eine gerade Länge hat (da ein Byte aus zwei Hex-Ziffern besteht).-
//--Optional kann ein "0x"-Präfix erlaubt sein.--


bool is_valid_hex(const std::string& s, bool allow_0x_prefix = true) {
    if (s.empty()) return false;

    std::string clean = s;
    if (allow_0x_prefix && s.size() >= 2 &&
        s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
        clean = s.substr(2); //--Präfix entfernen, wenn erlaubt--
        }

        if (clean.empty() || (clean.size() % 2) != 0) return false; //--Muss eine gerade Länge haben--

        for (unsigned char c : clean) {
            if (!is_hex_char(c)) return false; //--Alle Zeichen müssen Hex-Ziffern sein--
        }
        return true;
}

//--Entfernt ein optionales "0x"-Präfix von einem Hex-String-
//--Wenn der String mit "0x" oder "0X" beginnt, wird dieser Teil entfernt.--


std::string remove_0x_prefix(const std::string& s) {
    if (s.size() >= 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
        return s.substr(2);
    }
    return s;
}

//--Konvertiert einen Hex-String in Bytes und hängt sie an einen Puffer an-
//--Diese Funktion nimmt einen Hex-String und wandelt jedes Paar von Hex-Ziffern-
//--in ein einzelnes Byte um, das dann einem cl_uchar-Vektor hinzugefügt wird.-
//--Sie beinhaltet eine verbesserte Fehlerbehandlung für ungültige Eingaben.--


void append_hex_to_buffer(const std::string& hex, std::vector& buffer,
                          const std::string& field_name = "") {
    if (hex.empty()) return;

    std::string clean_hex = remove_0x_prefix(hex);
    if (!is_valid_hex(clean_hex, false)) { //--Prüfen ohne Präfix--
        throw std::invalid_argument("Ungültiger Hex-String für Feld '" +
        field_name + "': " + hex);
    }

    buffer.reserve(buffer.size() + clean_hex.size() / 2); //--Speicher im Voraus reservieren--
    for (size_t i = 0; i < clean_hex.size(); i += 2) {
        try {
            unsigned long byte_val = std::stoul(clean_hex.substr(i, 2), nullptr, 16);
            if (byte_val > 0xFF) { //--Ein Byte ist max. 255 (0xFF)--
                throw std::out_of_range("Byte-Wert außerhalb des Bereichs");
            }
            buffer.push_back(static_cast(byte_val));
        } catch (const std::exception& e) {
            throw std::invalid_argument("Konvertierungsfehler in Feld '" +
            field_name + "' bei Position " +
            std::to_string(i) + ": " + e.what());
        }
    }
                          }

                          //--Erstellt den Eingabepuffer für den OpenCL-Kernel aus einem MiningJob-
                          //--Diese Funktion sammelt alle relevanten Hex-Strings aus dem MiningJob-Objekt-
                          //--(Version, Prevhash, Ntime, Coinb1, Extranonce1, Extranonce2, Coinb2 und Merkle-Branch)-
                          //--und konvertiert sie in einen Vektor von Bytes, der als Eingabe für die GPU dient.--


                          void build_input_from_job(const MiningJob& job, std::vector& input_buffer) {
                              input_buffer.clear();

                              try {
                                  append_hex_to_buffer(job.version, input_buffer, "version");
                                  append_hex_to_buffer(job.prevhash, input_buffer, "prevhash");
                                  append_hex_to_buffer(job.ntime, input_buffer, "ntime");
                                  append_hex_to_buffer(job.coinb1, input_buffer, "coinb1");
                                  append_hex_to_buffer(job.extranonce1, input_buffer, "extranonce1");
                                  append_hex_to_buffer(job.extranonce2, input_buffer, "extranonce2");
                                  append_hex_to_buffer(job.coinb2, input_buffer, "coinb2");

                                  for (size_t i = 0; i < job.merkle_branch.size(); ++i) {
                                      append_hex_to_buffer(job.merkle_branch[i], input_buffer,
                                                           "merkle_branch[" + std::to_string(i) + "]");
                                  }
                              } catch (const std::exception& e) {


                                  input_buffer.clear(); //--Puffer im Fehlerfall leeren--
                                  throw; //--Fehler weitergeben--
                              }
                          }

                          //--Sichere Konvertierung eines Hex-Strings in einen 32-Bit-Integer (uint32_t)-
                          //--Diese Funktion wandelt einen Hex-String in eine vorzeichenlose 32-Bit-Ganzzahl um.-
                          //--Sie prüft auf Gültigkeit des Hex-Strings und stellt sicher, dass der Wert nicht-
                          //--über den maximalen Wert von uint32_t hinausgeht, um Überläufe zu vermeiden.--


                          std::optional safe_stoul_hex_u32(const std::string& hex) {
                              std::string clean_hex = remove_0x_prefix(hex);
                              if (!is_valid_hex(clean_hex, false)) return std::nullopt; //--Prüfen ohne Präfix--

                              try {
                                  size_t idx = 0;
                                  unsigned long v = std::stoul(clean_hex, &idx, 16);

                                  if (idx != clean_hex.size()) return std::nullopt; //--Nicht alle Zeichen gelesen--
                                  if (v > std::numeric_limits::max()) return std::nullopt; //--Wert zu groß--

                                  return static_cast(v);
                              } catch (...) {
                                  return std::nullopt; //--Konvertierungsfehler--
                              }
                          }

                          //--Verbesserte OpenCL-Fehlerbehandlung-
                          //--Diese Funktion prüft den Rückgabewert eines OpenCL-Aufrufs. Wenn ein Fehler auftritt,-
                          //--wird eine Fehlermeldung ausgegeben und optional das Build-Log des Kernels,-
                          //--falls die GpuResources verfügbar sind und ein Fehler im Build-Prozess vorlag.--


                          bool check_cl(cl_int err, const char* where, const GpuResources* resources = nullptr) {
                              if (err == CL_SUCCESS) return true; //--Alles in Ordnung--

                              std::cerr << "❌ OpenCL-Fehler (" << err << ") bei: " << where << "\n";

                              //--Build-Log ausgeben, falls Programm und Gerät bekannt sind--


                              if (resources && resources->program && resources->device) {
                                  size_t log_size = 0;
                                  clGetProgramBuildInfo(resources->program, resources->device,
                                                        CL_PROGRAM_BUILD_LOG, 0, nullptr, &log_size);

                                  if (log_size > 0) { //--Wenn ein Log vorhanden ist--
                                      std::vector build_log(log_size + 1); //--Dynamisch Puffer allozieren--


                                      clGetProgramBuildInfo(resources->program, resources->device,
                                                            CL_PROGRAM_BUILD_LOG, log_size, build_log.data(), nullptr);
                                      std::cerr << "Build-Log:\n" << build_log.data() << "\n";
                                  }
                              }

                              return false; //--Fehler aufgetreten--
                          }

                          //--RAII-Wrapper für OpenCL-Speicherobjekte (cl_mem)-
                          //--Dieser Wrapper sorgt dafür, dass OpenCL-Speicherobjekte automatisch freigegeben werden,-
                          //--wenn sie nicht mehr benötigt werden (z. B. wenn der Wrapper den Gültigkeitsbereich verlässt).-
                          //--Dies verhindert Speicherlecks und vereinfacht die Fehlerbehandlung.--


                          struct CLMemWrapper {
#deutsch #xbtgpuarc #miner #projekt #opensource #freefee
Payout: 0.000 HBD
Votes: 12
More interactions (upvote, reblog, reply) coming soon.