From 123c7ab140120a4e107ee49aa3da1730f21d280a Mon Sep 17 00:00:00 2001
From: XMRig <support@xmrig.com>
Date: Sun, 29 Aug 2021 14:22:19 +0700
Subject: [PATCH] Added support for new CUDA plugin API.

---
 src/backend/cuda/wrappers/CudaLib.cpp | 45 ++++++++++++++++++++-------
 src/base/crypto/Algorithm.cpp         |  5 ---
 src/base/crypto/Algorithm.h           |  2 +-
 3 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp
index 6e947bce5..4848f8c84 100644
--- a/src/backend/cuda/wrappers/CudaLib.cpp
+++ b/src/backend/cuda/wrappers/CudaLib.cpp
@@ -54,6 +54,7 @@ static const char *kAstroBWTHash                        = "astroBWTHash";
 static const char *kAstroBWTPrepare                     = "astroBWTPrepare";
 static const char *kCnHash                              = "cnHash";
 static const char *kDeviceCount                         = "deviceCount";
+static const char *kDeviceInfo                          = "deviceInfo";
 static const char *kDeviceInfo_v2                       = "deviceInfo_v2";
 static const char *kDeviceInit                          = "deviceInit";
 static const char *kDeviceInt                           = "deviceInt";
@@ -61,14 +62,15 @@ static const char *kDeviceName                          = "deviceName";
 static const char *kDeviceUint                          = "deviceUint";
 static const char *kDeviceUlong                         = "deviceUlong";
 static const char *kInit                                = "init";
+static const char *kKawPowHash                          = "kawPowHash";
+static const char *kKawPowPrepare_v2                    = "kawPowPrepare_v2";
+static const char *kKawPowStopHash                      = "kawPowStopHash";
 static const char *kLastError                           = "lastError";
 static const char *kPluginVersion                       = "pluginVersion";
 static const char *kRelease                             = "release";
 static const char *kRxHash                              = "rxHash";
 static const char *kRxPrepare                           = "rxPrepare";
-static const char *kKawPowHash                          = "kawPowHash";
-static const char *kKawPowPrepare_v2                    = "kawPowPrepare_v2";
-static const char *kKawPowStopHash                      = "kawPowStopHash";
+static const char *kSetJob                              = "setJob";
 static const char *kSetJob_v2                           = "setJob_v2";
 static const char *kVersion                             = "version";
 
@@ -78,6 +80,7 @@ using astroBWTHash_t                                    = bool (*)(nvid_ctx *, u
 using astroBWTPrepare_t                                 = bool (*)(nvid_ctx *, uint32_t);
 using cnHash_t                                          = bool (*)(nvid_ctx *, uint32_t, uint64_t, uint64_t, uint32_t *, uint32_t *);
 using deviceCount_t                                     = uint32_t (*)();
+using deviceInfo_t                                      = bool (*)(nvid_ctx *, int32_t, int32_t, uint32_t, int32_t);
 using deviceInfo_v2_t                                   = bool (*)(nvid_ctx *, int32_t, int32_t, const char *, int32_t);
 using deviceInit_t                                      = bool (*)(nvid_ctx *);
 using deviceInt_t                                       = int32_t (*)(nvid_ctx *, CudaLib::DeviceProperty);
@@ -85,14 +88,15 @@ using deviceName_t                                      = const char * (*)(nvid_
 using deviceUint_t                                      = uint32_t (*)(nvid_ctx *, CudaLib::DeviceProperty);
 using deviceUlong_t                                     = uint64_t (*)(nvid_ctx *, CudaLib::DeviceProperty);
 using init_t                                            = void (*)();
+using kawPowHash_t                                      = bool (*)(nvid_ctx *, uint8_t*, uint64_t, uint32_t *, uint32_t *, uint32_t *);
+using kawPowPrepare_v2_t                                = bool (*)(nvid_ctx *, const void *, size_t, const void *, size_t, uint32_t, const uint64_t*);
+using kawPowStopHash_t                                  = bool (*)(nvid_ctx *);
 using lastError_t                                       = const char * (*)(nvid_ctx *);
 using pluginVersion_t                                   = const char * (*)();
 using release_t                                         = void (*)(nvid_ctx *);
 using rxHash_t                                          = bool (*)(nvid_ctx *, uint32_t, uint64_t, uint32_t *, uint32_t *);
 using rxPrepare_t                                       = bool (*)(nvid_ctx *, const void *, size_t, bool, uint32_t);
-using kawPowHash_t                                      = bool (*)(nvid_ctx *, uint8_t*, uint64_t, uint32_t *, uint32_t *, uint32_t *);
-using kawPowPrepare_v2_t                                = bool (*)(nvid_ctx *, const void *, size_t, const void *, size_t, uint32_t, const uint64_t*);
-using kawPowStopHash_t                                  = bool (*)(nvid_ctx *);
+using setJob_t                                          = bool (*)(nvid_ctx *, const void *, size_t, uint32_t);
 using setJob_v2_t                                       = bool (*)(nvid_ctx *, const void *, size_t, const char *);
 using version_t                                         = uint32_t (*)(Version);
 
@@ -102,6 +106,7 @@ static astroBWTHash_t pAstroBWTHash                     = nullptr;
 static astroBWTPrepare_t pAstroBWTPrepare               = nullptr;
 static cnHash_t pCnHash                                 = nullptr;
 static deviceCount_t pDeviceCount                       = nullptr;
+static deviceInfo_t pDeviceInfo                         = nullptr;
 static deviceInfo_v2_t pDeviceInfo_v2                   = nullptr;
 static deviceInit_t pDeviceInit                         = nullptr;
 static deviceInt_t pDeviceInt                           = nullptr;
@@ -109,14 +114,15 @@ static deviceName_t pDeviceName                         = nullptr;
 static deviceUint_t pDeviceUint                         = nullptr;
 static deviceUlong_t pDeviceUlong                       = nullptr;
 static init_t pInit                                     = nullptr;
+static kawPowHash_t pKawPowHash                         = nullptr;
+static kawPowPrepare_v2_t pKawPowPrepare_v2             = nullptr;
+static kawPowStopHash_t pKawPowStopHash                 = nullptr;
 static lastError_t pLastError                           = nullptr;
 static pluginVersion_t pPluginVersion                   = nullptr;
 static release_t pRelease                               = nullptr;
 static rxHash_t pRxHash                                 = nullptr;
 static rxPrepare_t pRxPrepare                           = nullptr;
-static kawPowHash_t pKawPowHash                         = nullptr;
-static kawPowPrepare_v2_t pKawPowPrepare_v2             = nullptr;
-static kawPowStopHash_t pKawPowStopHash                 = nullptr;
+static setJob_t pSetJob                                 = nullptr;
 static setJob_v2_t pSetJob_v2                           = nullptr;
 static version_t pVersion                               = nullptr;
 
@@ -192,6 +198,10 @@ bool xmrig::CudaLib::deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads,
 {
     const Algorithm algo = RxAlgo::id(algorithm);
 
+    if (pDeviceInfo) {
+        return pDeviceInfo(ctx, blocks, threads, algo, dataset_host);
+    }
+
     return pDeviceInfo_v2(ctx, blocks, threads, algo.isValid() ? algo.name() : nullptr, dataset_host);
 }
 
@@ -235,6 +245,9 @@ bool xmrig::CudaLib::kawPowStopHash(nvid_ctx *ctx) noexcept
 bool xmrig::CudaLib::setJob(nvid_ctx *ctx, const void *data, size_t size, const Algorithm &algorithm) noexcept
 {
     const Algorithm algo = RxAlgo::id(algorithm);
+    if (pSetJob) {
+        return pSetJob(ctx, data, size, algo);
+    }
 
     return pSetJob_v2(ctx, data, size, algo.name());
 }
@@ -378,7 +391,8 @@ void xmrig::CudaLib::load()
 {
     DLSYM(Version);
 
-    if (pVersion(ApiVersion) != 3U) {
+    const uint32_t api = pVersion(ApiVersion);
+    if (api < 3U || api > 4U) {
         throw std::runtime_error("API version mismatch");
     }
 
@@ -401,8 +415,15 @@ void xmrig::CudaLib::load()
     DLSYM(KawPowHash);
     DLSYM(KawPowPrepare_v2);
     DLSYM(KawPowStopHash);
-    DLSYM(DeviceInfo_v2);
-    DLSYM(SetJob_v2);
+
+    if (api == 4U) {
+        DLSYM(DeviceInfo);
+        DLSYM(SetJob);
+    }
+    else if (api == 3U) {
+        DLSYM(DeviceInfo_v2);
+        DLSYM(SetJob_v2);
+    }
 
     pInit();
 }
diff --git a/src/base/crypto/Algorithm.cpp b/src/base/crypto/Algorithm.cpp
index dd2df673d..8c3a1ad36 100644
--- a/src/base/crypto/Algorithm.cpp
+++ b/src/base/crypto/Algorithm.cpp
@@ -107,11 +107,6 @@ const char *Algorithm::kKAWPOW_RVN      = "kawpow";
 #define ALGO_ALIAS_AUTO(ALGO)   { Algorithm::k##ALGO, Algorithm::ALGO }
 
 
-#ifdef _MSC_VER
-#   define strcasecmp _stricmp
-#endif
-
-
 static const std::map<uint32_t, const char *> kAlgorithmNames = {
     ALGO_NAME(CN_0),
     ALGO_NAME(CN_1),
diff --git a/src/base/crypto/Algorithm.h b/src/base/crypto/Algorithm.h
index 15df2a2c0..ca1588979 100644
--- a/src/base/crypto/Algorithm.h
+++ b/src/base/crypto/Algorithm.h
@@ -166,7 +166,7 @@ public:
     static inline constexpr bool isCN(Id id)                { return (id & 0xff000000) == CN_ANY; }
     static inline constexpr Id base(Id id)                  { return isCN(id) ? static_cast<Id>(CN_0 | (id & 0xff00)) : INVALID; }
     static inline constexpr size_t l2(Id id)                { return family(id) == RANDOM_X ? (1U << ((id >> 8) & 0xff)) : 0U; }
-    static inline constexpr size_t l3(Id id)                { return 1U << ((id >> 16) & 0xff); }
+    static inline constexpr size_t l3(Id id)                { return 1ULL << ((id >> 16) & 0xff); }
     static inline constexpr uint32_t family(Id id)          { return id & (isCN(id) ? 0xffff0000 : 0xff000000); }
 
     inline bool isCN() const                                { return isCN(m_id); }