1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #ifndef __OPEN_CL_GPU_REGISTRY_H__
23 #define __OPEN_CL_GPU_REGISTRY_H__
24 
25 #ifdef OPENCL_SUPPORT
26 
27 #    include <QMap>
28 
29 #    include <U2Algorithm/OpenCLHelper.h>
30 
31 #    include <U2Core/global.h>
32 
33 namespace U2 {
34 
35 typedef long OpenCLGpuId;
36 typedef long OpenCLGpuContext;
37 
38 #    define OPENCL_GPU_REGISTRY_SETTINGS_GPU_ENABLED "/opencl_gpu_registry/enabled_gpu"
39 
40 class U2ALGORITHM_EXPORT OpenCLGpuModel {
41 public:
42     OpenCLGpuModel(const QString &_name,
43                    const cl_context &_context,
44                    const cl_device_id &_id,
45                    quint64 _platformId,
46                    quint64 _globalMemorySizeBytes,
47                    quint64 _maxAllocateMemorySizeBytes,
48                    quint64 _localMemorySizeBytes,
49                    quint32 _maxComputeUnits,
50                    size_t _maxWorkGroupSize,
51                    quint32 _maxClockFrequency,
52                    bool _enabled = false)
name(_name)53         : name(_name),
54           context(_context),
55           id(_id),
56           platformId(_platformId),
57           globalMemorySizeBytes(_globalMemorySizeBytes),
58           maxAllocateMemorySizeBytes(_maxAllocateMemorySizeBytes),
59           localMemorySizeBytes(_localMemorySizeBytes),
60           maxComputeUnits(_maxComputeUnits),
61           maxWorkGroupSize(_maxWorkGroupSize),
62           maxClockFrequency(_maxClockFrequency),
63           enabled(_enabled),
64           acquired(false) {};
65 
getName()66     QString getName() const {
67         return name;
68     }
getId()69     cl_device_id getId() const {
70         return id;
71     }
getContext()72     cl_context getContext() const {
73         return context;
74     }
getGlobalMemorySizeBytes()75     quint64 getGlobalMemorySizeBytes() const {
76         return globalMemorySizeBytes;
77     }
getMaxAllocateMemorySizeBytes()78     quint64 getMaxAllocateMemorySizeBytes() const {
79         return maxAllocateMemorySizeBytes;
80     }
getLocalMemorySizeBytes()81     quint64 getLocalMemorySizeBytes() const {
82         return localMemorySizeBytes;
83     }
getMaxComputeUnits()84     quint32 getMaxComputeUnits() const {
85         return maxComputeUnits;
86     }
getMaxWorkGroupSize()87     size_t getMaxWorkGroupSize() const {
88         return maxWorkGroupSize;
89     }
getMaxClockFrequency()90     quint32 getMaxClockFrequency() const {
91         return maxClockFrequency;
92     }
getPlatformId()93     quint64 getPlatformId() const {
94         return platformId;
95     }
96 
isEnabled()97     bool isEnabled() const {
98         return enabled;
99     }
setEnabled(bool b)100     void setEnabled(bool b) {
101         enabled = b;
102     }
103 
isAcquired()104     bool isAcquired() const {
105         return acquired;
106     }
setAcquired(bool a)107     void setAcquired(bool a) {
108         acquired = a;
109     }
110 
isReady()111     bool isReady() {
112         return !isAcquired() && isEnabled();
113     }
114 
115 private:
116     QString name;
117     cl_context context;  // There should be one context for each device, no need to recreate context billion times TODO: releasing
118     cl_device_id id;
119     quint64 platformId;
120     quint64 globalMemorySizeBytes;
121     quint64 maxAllocateMemorySizeBytes;
122     quint64 localMemorySizeBytes;
123     quint32 maxComputeUnits;
124     size_t maxWorkGroupSize;
125     quint32 maxClockFrequency;
126     bool enabled;
127     bool acquired;
128 };
129 
130 class U2ALGORITHM_EXPORT OpenCLGpuRegistry {
131 public:
132     OpenCLGpuRegistry();
133     ~OpenCLGpuRegistry();
134 
135     void registerOpenCLGpu(OpenCLGpuModel *gpu);
136     void unregisterOpenCLGpu(OpenCLGpuModel *gpu);
137     OpenCLGpuModel *getGpuById(cl_device_id id) const;
138     OpenCLGpuModel *getGpuByName(const QString &name) const;
139     QList<OpenCLGpuModel *> getRegisteredGpus() const;
140     OpenCLGpuModel *getEnabledGpu() const;
141     QString getEnabledGpuName() const;
142 
143     OpenCLGpuModel *acquireEnabledGpuIfReady();
144 
empty()145     bool empty() const {
146         return gpus.empty();
147     }
148 
setOpenCLHelper(OpenCLHelper * _openCLHelper)149     void setOpenCLHelper(OpenCLHelper *_openCLHelper) {
150         openCLHelper = _openCLHelper;
151     }
152 
getOpenCLHelper()153     const OpenCLHelper *getOpenCLHelper() const {
154         return openCLHelper;
155     }
156 
157     void saveGpusSettings() const;
158 
159 private:
160     QHash<cl_device_id, OpenCLGpuModel *> gpus;
161     OpenCLHelper *openCLHelper;
162 };
163 
164 }  // namespace U2
165 
166 #endif /*OPENCL_SUPPORT*/
167 
168 #endif  //__OPEN_CL_GPU_REGISTRY_H__
169