XBTGPUARC Hauptprogramm in Deutsch erklährt und ausgeführt.

@alucian · 2025-09-09 06:26 · deutsch

09.09.25 SAPU //--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-- //-Zeilen um 777 Beachten!--

//-00--zhash.cl-Exclude-(Wir bauen ausschließlich um diesen einen Kernel herum!)--

//--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-- //--ARC INTEL DG2--

-------------------------------------> -------------------------------------> //--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

//--Hier werden die Ressourcen der Grafikkarte im Detail eingeteilt.

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; };

//--Externe Werte mit eingetragen.--

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 auf dem Computer 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-- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------->

Hier startet man den Bauvorgang für das Miningprogramm auf seinem Computer um es Einsatzbereit zu machen.--

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

//--Standard-Ziel/Target--

all: $(OUT)

Bau des GPU-Miners--

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

Generisches Compile-Ziel--

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

Säubern--

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 //--Eventuell Austragbar weil fester Algo--

include

include //--Atomic Nutzen Ja Nein Vielleicht erstmal Ja--

include //--Für std::isxdigit--

include //--Für Uhrzeit der Netzwekoperation--

include

include

include

include

include

include

include

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

include

include

include //--FÜr Intel ARC GPUs DG2 Alchmemist--

//--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 std::atomic abort_mining; extern std::atomic socket_valid; extern std::atomic job_wurde_übernommen;

//--Globale OpenCL-Objekte--

cl_context context = nullptr; cl_command_queue queue = nullptr; cl_kernel kernel = nullptr; cl_program program = nullptr; cl_device_id device = nullptr;

//--🧱 Erstellt den Eingabepuffer aus dem MiningJob--

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--
                          }
#deutsch #xbtgpuarc #haupt #programm #zhash
Payout: 1.150 HBD
Votes: 30
More interactions (upvote, reblog, reply) coming soon.