1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
#pragma once
#include "amd_gpu/gpu.hpp"
#include "autoAdjust.hpp"
#include "jconf.hpp"
#include "xmrstak/misc/console.hpp"
#include "xmrstak/misc/configEditor.hpp"
#include "xmrstak/params.hpp"
#include "xmrstak/backend/cryptonight.hpp"
#include "xmrstak/jconf.hpp"
#include <vector>
#include <cstdio>
#include <sstream>
#include <string>
#include <iostream>
#include <algorithm>
#if defined(__APPLE__)
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif
namespace xmrstak
{
namespace amd
{
class autoAdjust
{
public:
autoAdjust()
{
}
/** print the adjusted values if needed
*
* Routine exit the application and print the adjusted values if needed else
* nothing is happened.
*/
bool printConfig()
{
int platformIndex = getAMDPlatformIdx();
if(platformIndex == -1)
{
printer::inst()->print_msg(L0,"WARNING: No AMD OpenCL platform found. Possible driver issues or wrong vendor driver.");
return false;
}
devVec = getAMDDevices(platformIndex);
int deviceCount = devVec.size();
if(deviceCount == 0)
{
printer::inst()->print_msg(L0,"WARNING: No AMD device found.");
return false;
}
generateThreadConfig(platformIndex);
return true;
}
private:
void generateThreadConfig(const int platformIndex)
{
// load the template of the backend config into a char variable
const char *tpl =
#include "./config.tpl"
;
configEditor configTpl{};
configTpl.set( std::string(tpl) );
constexpr size_t byteToMiB = 1024u * 1024u;
size_t hashMemSize;
if(::jconf::inst()->IsCurrencyMonero())
{
hashMemSize = MONERO_MEMORY;
}
else
{
hashMemSize = AEON_MEMORY;
}
std::string conf;
int i = 0;
for(auto& ctx : devVec)
{
/* 1000 is a magic selected limit, the reason is that more than 2GiB memory
* sowing down the memory performance because of TLB cache misses
*/
size_t maxThreads = 1000u;
if(ctx.name.compare("gfx901") == 0)
{
/* Increase the number of threads for AMD VEGA gpus.
* Limit the number of threads based on the issue: https://github.com/fireice-uk/xmr-stak/issues/5#issuecomment-339425089
* to avoid out of memory errors
*/
maxThreads = 2024u;
}
// keep 128MiB memory free (value is randomly chosen)
size_t availableMem = ctx.freeMem - (128u * byteToMiB);
// 224byte extra memory is used per thread for meta data
size_t perThread = hashMemSize + 224u;
size_t maxIntensity = availableMem / perThread;
size_t possibleIntensity = std::min( maxThreads , maxIntensity );
// map intensity to a multiple of the compute unit count, 8 is the number of threads per work group
size_t intensity = (possibleIntensity / (8 * ctx.computeUnits)) * ctx.computeUnits * 8;
//If the intensity is 0, then it's because the multiple of the unit count is greater than intensity
if (intensity == 0) {
/* See Issues:
* https://github.com/fireice-uk/xmr-stak/issues/81
* https://github.com/fireice-uk/xmr-stak/issues/472
* https://github.com/fireice-uk/xmr-stak/issues/490
* Note that it appears that Northern Islands GPUs (HD 6XXX) are unaffected by
* these environment variables, according to my testing (dougvj)
*/
printer::inst()->print_msg(L0, "WARNING: Autodetected intensity unexpectedly low. Try setting GPU_SINGLE_ALLOC_PERCENT and etc.");
intensity = possibleIntensity;
}
conf += std::string(" // gpu: ") + ctx.name + " memory:" + std::to_string(availableMem / byteToMiB) + "\n";
conf += std::string(" // compute units: ") + std::to_string(ctx.computeUnits) + "\n";
// set 8 threads per block (this is a good value for the most gpus)
conf += std::string(" { \"index\" : ") + std::to_string(ctx.deviceIdx) + ",\n" +
" \"intensity\" : " + std::to_string(intensity) + ", \"worksize\" : " + std::to_string(8) + ",\n" +
" \"affine_to_cpu\" : false, \"strided_index\" : true\n"
" },\n";
++i;
}
configTpl.replace("PLATFORMINDEX",std::to_string(platformIndex));
configTpl.replace("GPUCONFIG",conf);
configTpl.write(params::inst().configFileAMD);
printer::inst()->print_msg(L0, "AMD: GPU configuration stored in file '%s'", params::inst().configFileAMD.c_str());
}
std::vector<GpuContext> devVec;
};
} // namespace amd
} // namepsace xmrstak
|