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

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

keysearcher

File size: 7.9 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    // results
88    costs = cl::Buffer(*context, CL_MEM_WRITE_ONLY, sizeof(float)*subbatch, NULL, &err);
89
90    if(err != CL_SUCCESS)
91    {
92        std::cerr << "Failed allocate to costsbuffer(" << err << ")\n";
93        throw new std::exception();
94    }
95   
96    localCosts = new float[subbatch];
97}
98
99void Cryptool::buildKernel(const Job& j)
100{
101    if (j.Src == "")
102    {
103        if (kernel != 0)
104            return;
105        else
106        {
107            std::cout << "Source transmission failure!" << std::endl;
108            throw new std::exception();
109        }
110    }
111
112    cl_int err;
113
114    std::cout<<"compiling CL source\n";
115    cl::Program::Sources sources(1, std::make_pair(j.Src.c_str(), j.Src.length()));
116
117    cl::Program program = cl::Program(*context, sources, &err);
118    if (err != CL_SUCCESS) {
119        std::cerr << "Program::Program() failed (" << err << ")\n";
120        throw new std::exception();
121    }
122
123    err = program.build(devices);
124    if (err != CL_SUCCESS) {
125
126        if(err == CL_BUILD_PROGRAM_FAILURE)
127        {
128            cl::string str = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0]);
129
130            std::cout << " \n\t\t\tBUILD LOG\n";
131            std::cout << " ************************************************\n";
132                        std::cout << str.c_str() << std::endl;
133            std::cout << " ************************************************\n";
134        }
135
136        std::cerr << "Program::build() failed (" << err << ")\n";
137        throw new std::exception();
138    }
139
140    if (kernel != 0)
141        delete kernel;
142
143    kernel = new cl::Kernel(program, "bruteforceKernel", &err);
144    if (err != CL_SUCCESS) {
145        std::cerr << "Kernel::Kernel() failed (" << err << ")\n";
146        throw new std::exception();
147    }
148}
149
150JobResult Cryptool::doOpenCLJob(const Job& j)
151{
152    cl_int err;
153
154    buildKernel(j);
155
156    cl::CommandQueue queue(*context, devices[0], 0, &err);
157    if (err != CL_SUCCESS) {
158        std::cerr << "CommandQueue::CommandQueue() failed (" << err << ")\n";
159        throw new std::exception();
160    }
161
162    // key
163    cl::Buffer keybuffer = cl::Buffer(*context, CL_MEM_READ_ONLY, j.KeySize*sizeof(float), NULL, &err);
164    if(err != CL_SUCCESS)
165    {
166        std::cerr << "Failed to allocate keybuffer(" << err << ")\n";
167        throw new std::exception();
168    }
169
170    err = queue.enqueueWriteBuffer(keybuffer, 1, 0, j.KeySize*sizeof(float), j.Key);
171    if(err != CL_SUCCESS)
172    {
173        std::cerr << "Failed write to keybuffer(" << err << ")\n";
174        throw new std::exception();
175    }
176
177    res.ResultList.resize(j.ResultSize);
178    initTop(res.ResultList, j.LargerThen);
179
180    //execute:
181    std::cout<<"Running CL program with " << j.Size << " calculations!\n";
182    enqueueKernel(queue, j.Size, keybuffer, costs, j);
183
184    std::cout<<"Done!\n";
185
186    return res;
187}
188
189void Cryptool::enqueueSubbatch(cl::CommandQueue& queue, cl::Buffer& keybuffer, cl::Buffer& costs, int add, int length, const Job& j)
190{
191        cl_int err;
192
193        err = kernel->setArg(0, keybuffer);
194        if (err != CL_SUCCESS) {
195                std::cerr << "Kernel::setArg() failed (" << err << ")\n";
196                throw new std::exception();
197        }
198
199        err = kernel->setArg(1, costs);
200        if (err != CL_SUCCESS) {
201                std::cerr << "Kernel::setArg() failed (" << err << ")\n";
202                throw new std::exception();
203        }
204
205        err = kernel->setArg(2, add);
206        if (err != CL_SUCCESS) {
207                std::cerr << "Kernel::setArg() failed (" << err << ")\n";
208                throw new std::exception();
209        }
210
211        err = queue.enqueueNDRangeKernel(*kernel, cl::NullRange, cl::NDRange(256, 256), cl::NullRange);
212
213        if (err != CL_SUCCESS) {
214                std::cerr << "CommandQueue::enqueueNDRangeKernel()" \
215                    " failed (" << err << ")\n";
216                throw new std::exception();
217        }
218
219        err = queue.finish();
220        if (err != CL_SUCCESS) {
221                std::cerr << "Event::wait() failed (" << err << ")\n";
222                throw new std::exception();
223        }
224
225        queue.enqueueReadBuffer(costs, 1, 0, sizeof(float)*length, localCosts);
226        err = queue.finish();
227        if (err != CL_SUCCESS) {
228                std::cerr << "Event::wait() failed (" << err << ")\n";
229                throw new std::exception();
230        }
231
232        //check results:
233        for(int i=0; i<length; ++i)
234        {
235                //std::cout << localCosts[i] << std::endl;
236                std::list<std::pair<float, int> >::iterator it = isInTop(res.ResultList, localCosts[i], j.LargerThen);
237                if (it != res.ResultList.end())
238                        pushInTop(res.ResultList, it, localCosts[i], i+add);
239        }
240}
241
242void Cryptool::enqueueKernel(cl::CommandQueue& queue, int size, cl::Buffer& keybuffer, cl::Buffer& costs, const Job& j)
243{
244    for (int i = 0; i < (size/subbatch); i++)
245    {
246        enqueueSubbatch(queue, keybuffer, costs, i*subbatch, subbatch, j);
247    }
248
249    int remain = (size%subbatch);
250    if (remain != 0)
251    {
252        enqueueSubbatch(queue, keybuffer, costs, size-remain, remain, j);
253    }
254}
255
256void Cryptool::pushInTop(std::list<std::pair<float, int> >& top, std::list<std::pair<float, int> >::iterator it, float val, int k) {
257        top.insert(it, std::pair<float, int>(val, k));
258        top.pop_back();
259}
260
261std::list<std::pair<float, int> >::iterator Cryptool::isInTop(std::list<std::pair<float, int> >& top, float val, bool LargerThen) {
262        if (LargerThen)
263        {
264                for (std::list<std::pair<float, int> >::iterator k = top.begin(); k != top.end(); k++)
265                        if (val > k->first)
266                                return k;
267        }
268        else
269        {
270                for (std::list<std::pair<float, int> >::iterator k = top.begin(); k != top.end(); k++)
271                        if (val < k->first)
272                                return k;
273        }
274
275        return top.end();
276}
277
278void Cryptool::initTop(std::list<std::pair<float, int> >& top, bool LargerThen) {
279        for (std::list<std::pair<float, int> >::iterator k = top.begin(); k != top.end(); k++)
280        {
281            if (LargerThen)
282                k->first = -1000000.0;
283            else
284                k->first = 1000000.0;
285        }
286}
Note: See TracBrowser for help on using the repository browser.