summaryrefslogtreecommitdiffstats
path: root/xmrstak/backend/amd/autoAdjust.hpp
blob: 6157b258805bfb1861dda6e5d99e7a3d1bff1272 (plain)
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

#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 <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) );

		std::string conf;
        int i = 0;
        for(auto& ctx : devVec)
        {
			// keep 64MiB memory free (value is randomly chosen)
			size_t availableMem = ctx.freeMem - (64u * 1024 * 1024);
			// 224byte extra memory is used per thread for meta data
			size_t perThread = (size_t(1u)<<21) + 224u;
			size_t max_intensity = availableMem / perThread;
			// 1000 is a magic selected limit \todo select max intensity depending of the gpu type
			size_t intensity = std::min( size_t(1000u) , max_intensity );
			conf += std::string("  // gpu: ") + ctx.name + "\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, \n"
                "  },\n";
            ++i;
        }

		configTpl.replace("PLATFORMINDEX",std::to_string(platformIndex));
		configTpl.replace("NUMGPUS",std::to_string(devVec.size()));
		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
OpenPOWER on IntegriCloud