source: trunk/CrypPlugins/KeySearcher/ExternalClient/Cryptool.cpp @ 2212

Last change on this file since 2212 was 2212, checked in by Sven Rech, 11 years ago

keysearcher external client

File size: 8.0 KB
Line 
1#include <cstdio>
2#include <cstdlib>
3#include <iostream>
4#include <SDKFile.hpp>
5#include <SDKCommon.hpp>
6#include <SDKApplication.hpp>
7
8#define __NO_STD_VECTOR
9#define __NO_STD_STRING
10
11#include "Cryptool.h"
12
13Cryptool::Cryptool()
14{
15    cl_int err;
16
17    kernel = 0;
18
19    // Platform info
20    cl::vector<cl::Platform> platforms;
21    std::cout<<"HelloCL!\nGetting Platform Information\n";
22    err = cl::Platform::get(&platforms);
23    if(err != CL_SUCCESS)
24    {
25        std::cerr << "Platform::get() failed (" << err << ")" << std::endl;
26        throw std::exception();
27    }
28    if (platforms.size() == 0)
29    {
30        std::cerr << "No platforms available!" << std::endl;
31        throw std::exception();
32    }
33
34    cl::vector<cl::Platform>::iterator i;
35    if(platforms.size() > 0)
36    {
37        for(i = platforms.begin(); i != platforms.end(); ++i)
38        {
39            if(!strcmp((*i).getInfo<CL_PLATFORM_VENDOR>(&err).c_str(), "Advanced Micro Devices, Inc."))
40            {
41                break;
42            }
43        }
44    }
45    if(err != CL_SUCCESS)
46    {
47        std::cerr << "Platform::getInfo() failed (" << err << ")" << std::endl;
48        throw std::exception();
49    }
50
51    /*
52     * If we could find our platform, use it. Otherwise pass a NULL and get whatever the
53     * implementation thinks we should be using.
54     */
55
56    cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(*i)(), 0 };
57
58    std::cout<<"Creating a context AMD platform\n";
59    context = new cl::Context(CL_DEVICE_TYPE_CPU, cps, NULL, NULL, &err);
60    if (err != CL_SUCCESS) {
61        std::cerr << "Context::Context() failed (" << err << ")\n";
62        throw std::exception();
63    }
64
65    std::cout<<"Getting device info\n";
66    devices = context->getInfo<CL_CONTEXT_DEVICES>();
67    if (err != CL_SUCCESS) {
68        std::cerr << "Context::getInfo() failed (" << err << ")\n";
69        throw std::exception();
70    }
71    if (devices.size() == 0) {
72        std::cerr << "No device available\n";
73        throw std::exception();
74    }
75
76    for(uint32_t i=0; i< devices.size(); ++i)
77    {
78        std::string out;
79        devices[i].getInfo(CL_DEVICE_NAME, &out);
80        printf("name: %s\n", out.c_str());
81        devices[i].getInfo(CL_DEVICE_VENDOR, &out);
82        printf("vendor: %s\n", out.c_str());
83        devices[i].getInfo(CL_DEVICE_OPENCL_C_VERSION, &out);
84        printf("version c: %s\n", out.c_str());
85    }
86}
87
88void Cryptool::buildKernel(const Job& j)
89{
90    if (j.Src == "")
91    {
92        if (kernel != 0)
93            return;
94        else
95        {
96            std::cout << "Source transmission failure!" << std::endl;
97            throw new std::exception();
98        }
99    }
100
101    cl_int err;
102
103    std::cout<<"compiling CL source\n";
104    cl::Program::Sources sources(1, std::make_pair(j.Src.c_str(), j.Src.length()));
105
106    cl::Program program = cl::Program(*context, sources, &err);
107    if (err != CL_SUCCESS) {
108        std::cerr << "Program::Program() failed (" << err << ")\n";
109        throw new std::exception();
110    }
111
112    err = program.build(devices);
113    if (err != CL_SUCCESS) {
114
115        if(err == CL_BUILD_PROGRAM_FAILURE)
116        {
117            cl::string str = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0]);
118
119            std::cout << " \n\t\t\tBUILD LOG\n";
120            std::cout << " ************************************************\n";
121                        std::cout << str.c_str() << std::endl;
122            std::cout << " ************************************************\n";
123        }
124
125        std::cerr << "Program::build() failed (" << err << ")\n";
126        throw new std::exception();
127    }
128
129    if (kernel != 0)
130        delete kernel;
131
132    kernel = new cl::Kernel(program, "bruteforceKernel", &err);
133    if (err != CL_SUCCESS) {
134        std::cerr << "Kernel::Kernel() failed (" << err << ")\n";
135        throw new std::exception();
136    }
137}
138
139JobResult Cryptool::doOpenCLJob(const Job& j)
140{
141    cl_int err;
142
143    buildKernel(j);
144
145    cl::CommandQueue queue(*context, devices[0], 0, &err);
146    if (err != CL_SUCCESS) {
147        std::cerr << "CommandQueue::CommandQueue() failed (" << err << ")\n";
148        throw new std::exception();
149    }
150
151    // key
152    cl::Buffer keybuffer = cl::Buffer(*context, CL_MEM_READ_ONLY, j.KeySize*sizeof(float), NULL, &err);
153    if(err != CL_SUCCESS)
154    {
155        std::cerr << "Failed to allocate keybuffer(" << err << ")\n";
156        throw new std::exception();
157    }
158
159    err = queue.enqueueWriteBuffer(keybuffer, 1, 0, j.KeySize*sizeof(float), j.Key);
160    if(err != CL_SUCCESS)
161    {
162        std::cerr << "Failed write to keybuffer(" << err << ")\n";
163        throw new std::exception();
164    }
165
166    // results
167    cl::Buffer costs = cl::Buffer(*context, CL_MEM_WRITE_ONLY, sizeof(float)*j.ResultSize, NULL, &err);
168
169    if(err != CL_SUCCESS)
170    {
171        std::cerr << "Failed allocate to entropybuffer(" << err << ")\n";
172        throw new std::exception();
173    }
174
175    //execute:
176    std::cout<<"Running CL program\n";
177    enqueueKernel(queue, j.Size, keybuffer, costs);
178
179    err = queue.finish();
180    if (err != CL_SUCCESS) {
181        std::cerr << "Event::wait() failed (" << err << ")\n";
182        throw new std::exception();
183    }
184
185    std::cout<<"Done Passed!\n";
186
187    float* localCosts = new float[j.ResultSize];
188
189    queue.enqueueReadBuffer(costs, 1, 0, sizeof(float)*j.ResultSize, localCosts);
190
191    //check results:
192    JobResult res;
193    res.ResultList.resize(j.ResultSize);
194    initTop(res.ResultList, j.LargerThen);
195
196    for(int i=0; i<j.Size; ++i)
197    {
198std::cout << localCosts[i] << std::endl;
199        std::list<std::pair<float, int> >::iterator it = isInTop(res.ResultList, localCosts[i], j.LargerThen);
200        if (it != res.ResultList.end())
201            pushInTop(res.ResultList, it, localCosts[i], i);
202    }
203
204    return res;
205}
206
207const int subbatch = 256;
208
209void Cryptool::enqueueSubbatch(cl::CommandQueue& queue, cl::Buffer& keybuffer, cl::Buffer& costs, cl::NDRange offset, cl::NDRange worksize)
210{
211        cl_int err;
212
213        err = kernel->setArg(0, keybuffer);
214        if (err != CL_SUCCESS) {
215                std::cerr << "Kernel::setArg() failed (" << err << ")\n";
216                throw new std::exception();
217        }
218
219        err = kernel->setArg(1, costs);
220        if (err != CL_SUCCESS) {
221                std::cerr << "Kernel::setArg() failed (" << err << ")\n";
222                throw new std::exception();
223        }
224
225        err = kernel->setArg(2, 0);
226        if (err != CL_SUCCESS) {
227                std::cerr << "Kernel::setArg() failed (" << err << ")\n";
228                throw new std::exception();
229        }
230
231        err = queue.enqueueNDRangeKernel(*kernel, offset, worksize, cl::NullRange);
232
233        if (err != CL_SUCCESS) {
234                std::cerr << "CommandQueue::enqueueNDRangeKernel()" \
235                    " failed (" << err << ")\n";
236                throw new std::exception();
237        }
238
239        err = queue.finish();
240        if (err != CL_SUCCESS) {
241                std::cerr << "Event::wait() failed (" << err << ")\n";
242                throw new std::exception();
243        }
244}
245
246void Cryptool::enqueueKernel(cl::CommandQueue& queue, int size, cl::Buffer& keybuffer, cl::Buffer& costs)
247{
248    for (int i = 0; i < (size/subbatch); i++)
249    {
250        enqueueSubbatch(queue, keybuffer, costs, cl::NDRange(i*subbatch), cl::NDRange(subbatch));
251        std::cout << i << " von " << (size/subbatch) << std::endl;
252    }
253
254    int remain = (size%subbatch);
255    if (remain != 0)
256    {
257        enqueueSubbatch(queue, keybuffer, costs, cl::NDRange(size-remain), cl::NDRange(remain));
258    }
259}
260
261void Cryptool::pushInTop(std::list<std::pair<float, int> >& top, std::list<std::pair<float, int> >::iterator it, float val, int k) {
262        top.insert(it, std::pair<float, int>(val, k));
263        top.pop_back();
264}
265
266std::list<std::pair<float, int> >::iterator Cryptool::isInTop(std::list<std::pair<float, int> >& top, float val, bool LargerThen) {
267        if (LargerThen)
268        {
269                for (std::list<std::pair<float, int> >::iterator k = top.begin(); k != top.end(); k++)
270                        if (val > k->first)
271                                return k;
272        }
273        else
274        {
275                for (std::list<std::pair<float, int> >::iterator k = top.begin(); k != top.end(); k++)
276                        if (val < k->first)
277                                return k;
278        }
279
280        return top.end();
281}
282
283void Cryptool::initTop(std::list<std::pair<float, int> >& top, bool LargerThen) {
284        for (std::list<std::pair<float, int> >::iterator k = top.begin(); k != top.end(); k++)
285        {
286            if (LargerThen)
287                k->first = -1000000.0;
288            else
289                k->first = 1000000.0;
290        }
291}
Note: See TracBrowser for help on using the repository browser.