Commit 93193003565225a253ec5e54cd3042d784249b00

Authored by M Taborsky
2 parents b739adca 1998d428

Merge branch 'master' of https://github.com/biometrics/openbr

sdk/jitcv/jitcv.cpp 0 โ†’ 100644
  1 +#include "jitcv.h"
sdk/jitcv/jitcv.h 0 โ†’ 100644
  1 +#ifndef __JITCV_H
  2 +#define __JITCV_H
  3 +
  4 +#include <stddef.h>
  5 +#include <stdint.h>
  6 +
  7 +#ifdef __cplusplus
  8 +extern "C" {
  9 +#endif
  10 +
  11 +/*!
  12 + * \brief jitcv matrix
  13 + * \author Josh Klontz \cite jklontz
  14 + * \note Not part of the core SDK
  15 + */
  16 +struct jit_matrix
  17 +{
  18 + uint8_t *data; /*!< Data */
  19 + uint32_t channels; /*!< Channels */
  20 + uint32_t columns; /*!< Columns */
  21 + uint32_t rows; /*!< Rows */
  22 + uint32_t frames; /*!< Frames */
  23 + uint16_t hash; /*!< Bits : 8
  24 + Floating : 1
  25 + Signed : 1
  26 + (Reserved) : 2
  27 + Single-channel : 1
  28 + Single-column : 1
  29 + Single-row : 1
  30 + Single-frame : 1 */
  31 +
  32 +#ifdef __cplusplus
  33 + enum Hash { Bits = 0x00FF,
  34 + Floating = 0x0100,
  35 + Signed = 0x0200,
  36 + SingleChannel = 0x1000,
  37 + SingleColumn = 0x2000,
  38 + SingleRow = 0x4000,
  39 + SingleFrame = 0x8000,
  40 + u1 = 1,
  41 + u8 = 8,
  42 + u16 = 16,
  43 + u32 = 32,
  44 + u64 = 64,
  45 + s8 = 8 + Signed,
  46 + s16 = 16 + Signed,
  47 + s32 = 32 + Signed,
  48 + s64 = 64 + Signed,
  49 + f16 = 16 + Floating + Signed,
  50 + f32 = 32 + Floating + Signed,
  51 + f64 = 64 + Floating + Signed };
  52 +
  53 + jit_matrix() : data(NULL), channels(0), columns(0), rows(0), frames(0), hash(0) {}
  54 +
  55 + jit_matrix(uint32_t _channels, uint32_t _columns, uint32_t _rows, uint32_t _frames, uint16_t _hash)
  56 + : data(NULL), channels(_channels), columns(_columns), rows(_rows), frames(_frames), hash(_hash)
  57 + {
  58 + setSingleChannel(channels == 1);
  59 + setSingleColumn(columns == 1);
  60 + setSingleRow(rows == 1);
  61 + setSingleFrame(frames == 1);
  62 + }
  63 +
  64 + inline void copyHeader(const jit_matrix &other) { channels = other.channels; columns = other.columns; rows = other.rows; frames = other.frames; hash = other.hash; }
  65 + inline void allocate() { deallocate(); data = new uint8_t[bytes()]; }
  66 + inline void deallocate() { delete[] data; data = NULL; }
  67 +
  68 + inline int bits() const { return hash & Bits; }
  69 + inline void setBits(int bits) { hash &= ~Bits; hash |= bits & Bits; }
  70 + inline bool isFloating() const { return hash & Floating; }
  71 + inline void setFloating(bool isFloating) { isFloating ? setSigned(true), hash |= Floating : hash &= ~Floating; }
  72 + inline bool isSigned() const { return hash & Signed; }
  73 + inline void setSigned(bool isSigned) { isSigned ? hash |= Signed : hash &= ~Signed; }
  74 + inline int type() const { return hash & (Bits + Floating + Signed); }
  75 + inline void setType(int type) { hash &= ~(Bits + Floating + Signed); hash |= type & (Bits + Floating + Signed); }
  76 + inline bool singleChannel() const { return hash & SingleChannel; }
  77 + inline void setSingleChannel(bool singleChannel) { singleChannel ? hash |= SingleChannel : hash &= ~SingleChannel; }
  78 + inline bool singleColumn() const { return hash & SingleColumn; }
  79 + inline void setSingleColumn(bool singleColumn) { singleColumn ? hash |= SingleColumn : hash &= ~SingleColumn; }
  80 + inline bool singleRow() const { return hash & SingleRow; }
  81 + inline void setSingleRow(bool singleRow) { singleRow ? hash |= SingleRow : hash &= ~SingleRow; }
  82 + inline bool singleFrame() const { return hash & SingleFrame; }
  83 + inline void setSingleFrame(bool singleFrame) { singleFrame ? hash |= SingleFrame : hash &= ~SingleFrame; }
  84 + inline uint32_t elements() const { return channels * columns * rows * frames; }
  85 + inline uint32_t bytes() const { return bits() / 8 * elements(); }
  86 +#endif // __cplusplus
  87 +};
  88 +
  89 +typedef void* jit_unary_kernel;
  90 +typedef void* jit_binary_kernel;
  91 +
  92 +jit_unary_kernel jit_square();
  93 +
  94 +void jit_unary_apply(const jit_unary_kernel &kernel, const jit_matrix &src, jit_matrix &dst);
  95 +void jit_binary_apply(const jit_binary_kernel &kernel, const jit_matrix &src, jit_matrix &dst);
  96 +
  97 +#ifdef __cplusplus
  98 +}
  99 +#endif
  100 +
  101 +#endif // __JITCV_H
sdk/plugins/llvm.cmake
@@ -21,6 +21,8 @@ if(${BR_WITH_LLVM}) @@ -21,6 +21,8 @@ if(${BR_WITH_LLVM})
21 # Let's suppose we want to build a JIT compiler with support for binary code: 21 # Let's suppose we want to build a JIT compiler with support for binary code:
22 llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native) 22 llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native)
23 23
  24 + set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC}
  25 + ${CMAKE_SOURCE_DIR}/sdk/plugins/llvm.cpp
  26 + ${CMAKE_SOURCE_DIR}/sdk/jitcv/jitcv.cpp)
24 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${REQ_LLVM_LIBRARIES}) 27 set(BR_THIRDPARTY_LIBS ${BR_THIRDPARTY_LIBS} ${REQ_LLVM_LIBRARIES})
25 - set(BR_THIRDPARTY_SRC ${BR_THIRDPARTY_SRC} ${CMAKE_SOURCE_DIR}/sdk/plugins/llvm.cpp)  
26 endif() 28 endif()
sdk/plugins/llvm.cpp
@@ -21,6 +21,7 @@ @@ -21,6 +21,7 @@
21 #include <openbr_plugin.h> 21 #include <openbr_plugin.h>
22 22
23 #include "core/opencvutils.h" 23 #include "core/opencvutils.h"
  24 +#include "jitcv/jitcv.h"
24 25
25 using namespace br; 26 using namespace br;
26 using namespace cv; 27 using namespace cv;
@@ -32,136 +33,71 @@ static FunctionPassManager *TheFunctionPassManager = NULL; @@ -32,136 +33,71 @@ static FunctionPassManager *TheFunctionPassManager = NULL;
32 static FunctionPassManager *TheExtraFunctionPassManager = NULL; 33 static FunctionPassManager *TheExtraFunctionPassManager = NULL;
33 static StructType *TheMatrixStruct = NULL; 34 static StructType *TheMatrixStruct = NULL;
34 35
35 -/*!  
36 - * \brief LLVM matrix  
37 - * \author Josh Klontz \cite jklontz  
38 - * \note Not part of the core SDK  
39 - */  
40 -struct Matrix 36 +static QString MatrixToString(const jit_matrix &m)
41 { 37 {
42 - quint8 *data; /*!< Data */  
43 - quint32 channels; /*!< Channels */  
44 - quint32 columns; /*!< Columns */  
45 - quint32 rows; /*!< Rows */  
46 - quint32 frames; /*!< Frames */  
47 - quint16 hash; /*!< Bits : 8  
48 - Floating : 1  
49 - Signed : 1  
50 - Single-channel : 1  
51 - Single-column : 1  
52 - Single-row : 1  
53 - Single-frame : 1 */  
54 -  
55 - enum Hash { Bits = 0x00FF,  
56 - Floating = 0x0100,  
57 - Signed = 0x0200,  
58 - SingleChannel = 0x1000,  
59 - SingleColumn = 0x2000,  
60 - SingleRow = 0x4000,  
61 - SingleFrame = 0x8000,  
62 - u1 = 1,  
63 - u8 = 8,  
64 - u16 = 16,  
65 - u32 = 32,  
66 - u64 = 64,  
67 - s8 = 8 + Signed,  
68 - s16 = 16 + Signed,  
69 - s32 = 32 + Signed,  
70 - s64 = 64 + Signed,  
71 - f16 = 16 + Floating + Signed,  
72 - f32 = 32 + Floating + Signed,  
73 - f64 = 64 + Floating + Signed };  
74 -  
75 - Matrix() : data(NULL), channels(0), columns(0), rows(0), frames(0), hash(0) {}  
76 -  
77 - Matrix(quint32 _channels, quint32 _columns, quint32 _rows, quint32 _frames, quint16 _hash)  
78 - : data(NULL), channels(_channels), columns(_columns), rows(_rows), frames(_frames), hash(_hash)  
79 - {  
80 - setSingleChannel(channels == 1);  
81 - setSingleColumn(columns == 1);  
82 - setSingleRow(rows == 1);  
83 - setSingleFrame(frames == 1);  
84 - }  
85 -  
86 - Matrix(const cv::Mat &mat)  
87 - {  
88 - if (!mat.isContinuous()) qFatal("Matrix requires continuous data.");  
89 - channels = mat.channels();  
90 - columns = mat.cols;  
91 - rows = mat.rows;  
92 - frames = 1;  
93 -  
94 - switch (mat.depth()) {  
95 - case CV_8U: hash = Matrix::u8; break;  
96 - case CV_8S: hash = Matrix::s8; break;  
97 - case CV_16U: hash = Matrix::u16; break;  
98 - case CV_16S: hash = Matrix::s16; break;  
99 - case CV_32S: hash = Matrix::s32; break;  
100 - case CV_32F: hash = Matrix::f32; break;  
101 - case CV_64F: hash = Matrix::f64; break;  
102 - default: qFatal("Unrecognized matrix depth.");  
103 - } 38 + return QString("%1%2%3%4%5%6%7").arg(QString::number(m.bits()), (m.isSigned() ? "s" : "u"), (m.isFloating() ? "f" : "i"),
  39 + QString::number(m.singleChannel()), QString::number(m.singleColumn()), QString::number(m.singleRow()), QString::number(m.singleFrame()));
  40 +}
104 41
105 - data = mat.data;  
106 - }  
107 -  
108 - void copyHeader(const Matrix &other) { channels = other.channels; columns = other.columns; rows = other.rows; frames = other.frames; hash = other.hash; }  
109 - void allocate() { deallocate(); data = new quint8[bytes()]; }  
110 - void allocate(Mat &m) { deallocate(); m = Mat(rows, columns, CV_MAKETYPE(getOpenCVDepth(), channels)); data = m.data; }  
111 - void deallocate() { delete[] data; data = NULL; }  
112 -  
113 - inline int bits() const { return hash & Bits; }  
114 - inline void setBits(int bits) { hash &= ~Bits; hash |= bits & Bits; }  
115 - inline bool isFloating() const { return hash & Floating; }  
116 - inline void setFloating(bool isFloating) { isFloating ? setSigned(true), hash |= Floating : hash &= ~Floating; }  
117 - inline bool isSigned() const { return hash & Signed; }  
118 - inline void setSigned(bool isSigned) { isSigned ? hash |= Signed : hash &= ~Signed; }  
119 - inline int type() const { return hash & (Bits + Floating + Signed); }  
120 - inline void setType(int type) { hash &= ~(Bits + Floating + Signed); hash |= type & (Bits + Floating + Signed); }  
121 - inline bool singleChannel() const { return hash & SingleChannel; }  
122 - inline void setSingleChannel(bool singleChannel) { singleChannel ? hash |= SingleChannel : hash &= ~SingleChannel; }  
123 - inline bool singleColumn() const { return hash & SingleColumn; }  
124 - inline void setSingleColumn(bool singleColumn) { singleColumn ? hash |= SingleColumn : hash &= ~SingleColumn; }  
125 - inline bool singleRow() const { return hash & SingleRow; }  
126 - inline void setSingleRow(bool singleRow) { singleRow ? hash |= SingleRow : hash &= ~SingleRow; }  
127 - inline bool singleFrame() const { return hash & SingleFrame; }  
128 - inline void setSingleFrame(bool singleFrame) { singleFrame ? hash |= SingleFrame : hash &= ~SingleFrame; }  
129 - inline quint32 elements() const { return channels * columns * rows * frames; }  
130 - inline quint32 bytes() const { return bits() / 8 * elements(); }  
131 -  
132 - QString toString() const { return QString("%1%2%3%4%5%6%7").arg(QString::number(bits()), (isSigned() ? "s" : "u"), (isFloating() ? "f" : "i"),  
133 - QString::number(singleChannel()), QString::number(singleColumn()), QString::number(singleRow()), QString::number(singleFrame())); }  
134 -  
135 - int getOpenCVDepth() const {  
136 - switch (type()) {  
137 - case u8: return CV_8U;  
138 - case s8: return CV_8S;  
139 - case u16: return CV_16U;  
140 - case s16: return CV_16S;  
141 - case s32: return CV_32S;  
142 - case f32: return CV_32F;  
143 - case f64: return CV_64F;  
144 - default: qFatal("OpenCV does not support Matrix format: %s", qPrintable(toString()));  
145 - }  
146 - return -1;  
147 - }  
148 -}; 42 +static jit_matrix MatrixFromMat(const cv::Mat &mat)
  43 +{
  44 + jit_matrix m;
  45 +
  46 + if (!mat.isContinuous()) qFatal("Matrix requires continuous data.");
  47 + m.channels = mat.channels();
  48 + m.columns = mat.cols;
  49 + m.rows = mat.rows;
  50 + m.frames = 1;
  51 +
  52 + switch (mat.depth()) {
  53 + case CV_8U: m.hash = jit_matrix::u8; break;
  54 + case CV_8S: m.hash = jit_matrix::s8; break;
  55 + case CV_16U: m.hash = jit_matrix::u16; break;
  56 + case CV_16S: m.hash = jit_matrix::s16; break;
  57 + case CV_32S: m.hash = jit_matrix::s32; break;
  58 + case CV_32F: m.hash = jit_matrix::f32; break;
  59 + case CV_64F: m.hash = jit_matrix::f64; break;
  60 + default: qFatal("Unrecognized matrix depth.");
  61 + }
  62 +
  63 + m.data = mat.data;
  64 + return m;
  65 +}
  66 +
  67 +static void AllocateMatrixFromMat(jit_matrix &m, cv::Mat &mat)
  68 +{
  69 + int cvType = -1;
  70 + switch (m.type()) {
  71 + case jit_matrix::u8: cvType = CV_8U; break;
  72 + case jit_matrix::s8: cvType = CV_8S; break;
  73 + case jit_matrix::u16: cvType = CV_16U; break;
  74 + case jit_matrix::s16: cvType = CV_16S; break;
  75 + case jit_matrix::s32: cvType = CV_32S; break;
  76 + case jit_matrix::f32: cvType = CV_32F; break;
  77 + case jit_matrix::f64: cvType = CV_64F; break;
  78 + default: qFatal("OpenCV does not support Matrix format: %s", qPrintable(MatrixToString(m)));
  79 + }
  80 +
  81 + m.deallocate();
  82 + mat = Mat(m.rows, m.columns, CV_MAKETYPE(cvType, m.channels));
  83 + m.data = mat.data;
  84 +}
149 85
150 -QDebug operator<<(QDebug dbg, const Matrix &m) 86 +QDebug operator<<(QDebug dbg, const jit_matrix &m)
151 { 87 {
152 - dbg.nospace() << m.toString(); 88 + dbg.nospace() << MatrixToString(m);
153 return dbg; 89 return dbg;
154 } 90 }
155 91
156 -struct MatrixBuilder : public Matrix 92 +struct MatrixBuilder : public jit_matrix
157 { 93 {
158 Value *m; 94 Value *m;
159 IRBuilder<> *b; 95 IRBuilder<> *b;
160 Function *f; 96 Function *f;
161 Twine name; 97 Twine name;
162 98
163 - MatrixBuilder(const Matrix &matrix, Value *value, IRBuilder<> *builder, Function *function, const Twine &name_)  
164 - : Matrix(matrix), m(value), b(builder), f(function), name(name_) {} 99 + MatrixBuilder(const jit_matrix &matrix, Value *value, IRBuilder<> *builder, Function *function, const Twine &name_)
  100 + : jit_matrix(matrix), m(value), b(builder), f(function), name(name_) {}
165 101
166 static Value *zero() { return constant(0); } 102 static Value *zero() { return constant(0); }
167 static Value *one() { return constant(1); } 103 static Value *one() { return constant(1); }
@@ -263,7 +199,7 @@ struct MatrixBuilder : public Matrix @@ -263,7 +199,7 @@ struct MatrixBuilder : public Matrix
263 template <typename T> 199 template <typename T>
264 inline static std::vector<T> toVector(T value) { std::vector<T> vector; vector.push_back(value); return vector; } 200 inline static std::vector<T> toVector(T value) { std::vector<T> vector; vector.push_back(value); return vector; }
265 201
266 - static Type *ty(const Matrix &m) 202 + static Type *ty(const jit_matrix &m)
267 { 203 {
268 const int bits = m.bits(); 204 const int bits = m.bits();
269 if (m.isFloating()) { 205 if (m.isFloating()) {
@@ -283,7 +219,7 @@ struct MatrixBuilder : public Matrix @@ -283,7 +219,7 @@ struct MatrixBuilder : public Matrix
283 inline Type *ty() const { return ty(*this); } 219 inline Type *ty() const { return ty(*this); }
284 inline std::vector<Type*> tys() const { return toVector<Type*>(ty()); } 220 inline std::vector<Type*> tys() const { return toVector<Type*>(ty()); }
285 221
286 - static Type *ptrTy(const Matrix &m) 222 + static Type *ptrTy(const jit_matrix &m)
287 { 223 {
288 const int bits = m.bits(); 224 const int bits = m.bits();
289 if (m.isFloating()) { 225 if (m.isFloating()) {
@@ -307,30 +243,40 @@ namespace br @@ -307,30 +243,40 @@ namespace br
307 { 243 {
308 244
309 /*! 245 /*!
310 - * \brief LLVM Kernel 246 + * \brief LLVM Unary Kernel
311 * \author Josh Klontz \cite jklontz 247 * \author Josh Klontz \cite jklontz
312 */ 248 */
313 -class Kernel : public UntrainableMetaTransform 249 +class UnaryKernel : public UntrainableMetaTransform
314 { 250 {
315 Q_OBJECT 251 Q_OBJECT
316 252
317 - typedef void (*kernel_t)(const Matrix*, Matrix*, quint32); 253 + typedef void (*kernel_t)(const jit_matrix*, jit_matrix*, quint32);
318 kernel_t kernel; 254 kernel_t kernel;
319 quint16 hash; 255 quint16 hash;
320 256
321 public: 257 public:
322 - Kernel() : kernel(NULL), hash(0) {}  
323 - virtual int preallocate(const Matrix &src, Matrix &dst) const = 0; /*!< Preallocate destintation matrix based on source matrix. */ 258 + UnaryKernel() : kernel(NULL), hash(0) {}
  259 + virtual int preallocate(const jit_matrix &src, jit_matrix &dst) const = 0; /*!< Preallocate destintation matrix based on source matrix. */
324 virtual void build(const MatrixBuilder &src, const MatrixBuilder &dst, PHINode *i) const = 0; /*!< Build the kernel. */ 260 virtual void build(const MatrixBuilder &src, const MatrixBuilder &dst, PHINode *i) const = 0; /*!< Build the kernel. */
325 261
  262 + void apply(const jit_matrix &src, jit_matrix &dst) const
  263 + {
  264 + const int size = preallocate(src, dst);
  265 + dst.allocate();
  266 + invoke(src, dst, size);
  267 + }
  268 +
326 private: 269 private:
327 - QString mangledName(const Matrix &m) const {  
328 - QStringList kernelArguments = arguments();  
329 - kernelArguments.append(m.toString());  
330 - return "jitcv_" + name().remove("Transform") + "_" + kernelArguments.join("_"); 270 + QString mangledName(const jit_matrix &src) const
  271 + {
  272 + static QHash<QString, int> argsLUT;
  273 + const QString args = arguments().join(",");
  274 + if (!argsLUT.contains(args)) argsLUT.insert(args, argsLUT.size());
  275 + int uid = argsLUT.value(args);
  276 + return "jitcv_" + name().remove("Transform") + (args.isEmpty() ? QString() : QString::number(uid)) + "_" + MatrixToString(src);
331 } 277 }
332 278
333 - Function *compile(const Matrix &m) const 279 + Function *compile(const jit_matrix &m) const
334 { 280 {
335 Constant *c = TheModule->getOrInsertFunction(qPrintable(mangledName(m)), 281 Constant *c = TheModule->getOrInsertFunction(qPrintable(mangledName(m)),
336 Type::getVoidTy(getGlobalContext()), 282 Type::getVoidTy(getGlobalContext()),
@@ -356,7 +302,7 @@ private: @@ -356,7 +302,7 @@ private:
356 BasicBlock *kernel; 302 BasicBlock *kernel;
357 PHINode *i = MatrixBuilder::beginLoop(builder, function, entry, &kernel, "i"); 303 PHINode *i = MatrixBuilder::beginLoop(builder, function, entry, &kernel, "i");
358 304
359 - Matrix n; 305 + jit_matrix n;
360 preallocate(m, n); 306 preallocate(m, n);
361 build(MatrixBuilder(m, src, &builder, function, "src"), MatrixBuilder(n, dst, &builder, function, "dst"), i); 307 build(MatrixBuilder(m, src, &builder, function, "src"), MatrixBuilder(n, dst, &builder, function, "dst"), i);
362 308
@@ -368,32 +314,132 @@ private: @@ -368,32 +314,132 @@ private:
368 314
369 void project(const Template &src, Template &dst) const 315 void project(const Template &src, Template &dst) const
370 { 316 {
371 - const Matrix m(src.m());  
372 - Matrix n; 317 + const jit_matrix m(MatrixFromMat(src));
  318 + jit_matrix n;
373 const int size = preallocate(m, n); 319 const int size = preallocate(m, n);
374 - n.allocate(dst.m()); 320 + AllocateMatrixFromMat(n, dst);
  321 + invoke(m, n, size);
  322 + }
375 323
376 - if (m.hash != hash) { 324 + void invoke(const jit_matrix &src, jit_matrix &dst, int size) const
  325 + {
  326 + if (src.hash != hash) {
377 static QMutex compilerLock; 327 static QMutex compilerLock;
378 QMutexLocker locker(&compilerLock); 328 QMutexLocker locker(&compilerLock);
379 329
380 - if (m.hash != hash) {  
381 - const QString functionName = mangledName(m); 330 + if (src.hash != hash) {
  331 + const QString functionName = mangledName(src);
382 332
383 Function *function = TheModule->getFunction(qPrintable(functionName)); 333 Function *function = TheModule->getFunction(qPrintable(functionName));
384 if (function == NULL) { 334 if (function == NULL) {
385 - function = compile(m); 335 + function = compile(src);
386 while (TheFunctionPassManager->run(*function)); 336 while (TheFunctionPassManager->run(*function));
387 TheExtraFunctionPassManager->run(*function); 337 TheExtraFunctionPassManager->run(*function);
388 function = TheModule->getFunction(qPrintable(functionName)); 338 function = TheModule->getFunction(qPrintable(functionName));
389 } 339 }
390 340
391 - const_cast<Kernel*>(this)->kernel = (kernel_t)TheExecutionEngine->getPointerToFunction(function);  
392 - const_cast<Kernel*>(this)->hash = m.hash; 341 + const_cast<UnaryKernel*>(this)->kernel = (kernel_t)TheExecutionEngine->getPointerToFunction(function);
  342 + const_cast<UnaryKernel*>(this)->hash = src.hash;
393 } 343 }
394 } 344 }
395 345
396 - kernel(&m, &n, size); 346 + kernel(&src, &dst, size);
  347 + }
  348 +};
  349 +
  350 +/*!
  351 + * \brief LLVM Binary Kernel
  352 + * \author Josh Klontz \cite jklontz
  353 + */
  354 +class BinaryKernel: public UntrainableMetaTransform
  355 +{
  356 + Q_OBJECT
  357 +
  358 + typedef void (*kernel_t)(const jit_matrix*, const jit_matrix*, jit_matrix*, quint32);
  359 + kernel_t kernel;
  360 + quint16 hashA, hashB;
  361 +
  362 +public:
  363 + BinaryKernel() : kernel(NULL), hashA(0), hashB(0) {}
  364 + virtual int preallocate(const jit_matrix &srcA, const jit_matrix &srcB, jit_matrix &dst) const = 0; /*!< Preallocate destintation matrix based on source matrix. */
  365 + virtual void build(const MatrixBuilder &srcA, const MatrixBuilder &srcB, const MatrixBuilder &dst, PHINode *i) const = 0; /*!< Build the kernel. */
  366 +
  367 + void apply(const jit_matrix &srcA, const jit_matrix &srcB, jit_matrix &dst) const
  368 + {
  369 + const int size = preallocate(srcA, srcB, dst);
  370 + dst.allocate();
  371 + invoke(srcA, srcB, dst, size);
  372 + }
  373 +
  374 +private:
  375 + QString mangledName(const jit_matrix &srcA, const jit_matrix &srcB) const
  376 + {
  377 + return "jitcv_" + name().remove("Transform") + "_" + MatrixToString(srcA) + "_" + MatrixToString(srcB);
  378 + }
  379 +
  380 + Function *compile(const jit_matrix &m, const jit_matrix &n) const
  381 + {
  382 + Constant *c = TheModule->getOrInsertFunction(qPrintable(mangledName(m, n)),
  383 + Type::getVoidTy(getGlobalContext()),
  384 + PointerType::getUnqual(TheMatrixStruct),
  385 + PointerType::getUnqual(TheMatrixStruct),
  386 + PointerType::getUnqual(TheMatrixStruct),
  387 + Type::getInt32Ty(getGlobalContext()),
  388 + NULL);
  389 +
  390 + Function *function = cast<Function>(c);
  391 + function->setCallingConv(CallingConv::C);
  392 +
  393 + Function::arg_iterator args = function->arg_begin();
  394 + Value *srcA = args++;
  395 + srcA->setName("srcA");
  396 + Value *srcB = args++;
  397 + srcB->setName("srcB");
  398 + Value *dst = args++;
  399 + dst->setName("dst");
  400 + Value *len = args++;
  401 + len->setName("len");
  402 +
  403 + BasicBlock *entry = BasicBlock::Create(getGlobalContext(), "entry", function);
  404 + IRBuilder<> builder(entry);
  405 +
  406 + BasicBlock *kernel;
  407 + PHINode *i = MatrixBuilder::beginLoop(builder, function, entry, &kernel, "i");
  408 +
  409 + jit_matrix o;
  410 + preallocate(m, n, o);
  411 + build(MatrixBuilder(m, srcA, &builder, function, "srcA"), MatrixBuilder(n, srcB, &builder, function, "srcB"), MatrixBuilder(o, dst, &builder, function, "dst"), i);
  412 +
  413 + MatrixBuilder::endLoop(builder, function, kernel, i, len, "i");
  414 +
  415 + builder.CreateRetVoid();
  416 + return function;
  417 + }
  418 +
  419 + void invoke(const jit_matrix &srcA, const jit_matrix &srcB, jit_matrix &dst, int size) const
  420 + {
  421 + if ((srcA.hash != hashA) || (srcB.hash != hashB)) {
  422 + static QMutex compilerLock;
  423 + QMutexLocker locker(&compilerLock);
  424 +
  425 + if ((srcA.hash != hashA) || (srcB.hash != hashB)) {
  426 + const QString functionName = mangledName(srcA, srcB);
  427 +
  428 + Function *function = TheModule->getFunction(qPrintable(functionName));
  429 + if (function == NULL) {
  430 + function = compile(srcA, srcB);
  431 + while (TheFunctionPassManager->run(*function));
  432 + TheExtraFunctionPassManager->run(*function);
  433 + function = TheModule->getFunction(qPrintable(functionName));
  434 + }
  435 +
  436 + const_cast<BinaryKernel*>(this)->kernel = (kernel_t)TheExecutionEngine->getPointerToFunction(function);
  437 + const_cast<BinaryKernel*>(this)->hashA = srcA.hash;
  438 + const_cast<BinaryKernel*>(this)->hashB = srcB.hash;
  439 + }
  440 + }
  441 +
  442 + kernel(&srcA, &srcB, &dst, size);
397 } 443 }
398 }; 444 };
399 445
@@ -401,14 +447,14 @@ private: @@ -401,14 +447,14 @@ private:
401 * \brief LLVM Stitchable Kernel 447 * \brief LLVM Stitchable Kernel
402 * \author Josh Klontz \cite jklontz 448 * \author Josh Klontz \cite jklontz
403 */ 449 */
404 -class StitchableKernel : public Kernel 450 +class StitchableKernel : public UnaryKernel
405 { 451 {
406 Q_OBJECT 452 Q_OBJECT
407 453
408 public: 454 public:
409 virtual Value *stitch(const MatrixBuilder &src, const MatrixBuilder &dst, Value *val) const = 0; /*!< A simplification of Kernel::build() for stitchable kernels. */ 455 virtual Value *stitch(const MatrixBuilder &src, const MatrixBuilder &dst, Value *val) const = 0; /*!< A simplification of Kernel::build() for stitchable kernels. */
410 456
411 - virtual int preallocate(const Matrix &src, Matrix &dst) const 457 + virtual int preallocate(const jit_matrix &src, jit_matrix &dst) const
412 { 458 {
413 dst.copyHeader(src); 459 dst.copyHeader(src);
414 return dst.elements(); 460 return dst.elements();
@@ -428,7 +474,7 @@ private: @@ -428,7 +474,7 @@ private:
428 * \brief LLVM stitch transform 474 * \brief LLVM stitch transform
429 * \author Josh Klontz \cite jklontz 475 * \author Josh Klontz \cite jklontz
430 */ 476 */
431 -class stitchTransform : public Kernel 477 +class stitchTransform : public UnaryKernel
432 { 478 {
433 Q_OBJECT 479 Q_OBJECT
434 Q_PROPERTY(QList<br::Transform*> kernels READ get_kernels WRITE set_kernels RESET reset_kernels STORED false) 480 Q_PROPERTY(QList<br::Transform*> kernels READ get_kernels WRITE set_kernels RESET reset_kernels STORED false)
@@ -441,11 +487,11 @@ class stitchTransform : public Kernel @@ -441,11 +487,11 @@ class stitchTransform : public Kernel
441 qFatal("%s is not a stitchable kernel!", qPrintable(transform->name())); 487 qFatal("%s is not a stitchable kernel!", qPrintable(transform->name()));
442 } 488 }
443 489
444 - int preallocate(const Matrix &src, Matrix &dst) const 490 + int preallocate(const jit_matrix &src, jit_matrix &dst) const
445 { 491 {
446 - Matrix tmp = src; 492 + jit_matrix tmp = src;
447 foreach (const Transform *kernel, kernels) { 493 foreach (const Transform *kernel, kernels) {
448 - static_cast<const Kernel*>(kernel)->preallocate(tmp, dst); 494 + static_cast<const UnaryKernel*>(kernel)->preallocate(tmp, dst);
449 tmp = dst; 495 tmp = dst;
450 } 496 }
451 return dst.elements(); 497 return dst.elements();
@@ -457,7 +503,7 @@ class stitchTransform : public Kernel @@ -457,7 +503,7 @@ class stitchTransform : public Kernel
457 MatrixBuilder dst(dst_); 503 MatrixBuilder dst(dst_);
458 Value *val = src.load(i); 504 Value *val = src.load(i);
459 foreach (Transform *transform, kernels) { 505 foreach (Transform *transform, kernels) {
460 - static_cast<Kernel*>(transform)->preallocate(src, dst); 506 + static_cast<UnaryKernel*>(transform)->preallocate(src, dst);
461 val = static_cast<StitchableKernel*>(transform)->stitch(src, dst, val); 507 val = static_cast<StitchableKernel*>(transform)->stitch(src, dst, val);
462 src.copyHeader(dst); 508 src.copyHeader(dst);
463 src.m = dst.m; 509 src.m = dst.m;
@@ -497,7 +543,7 @@ class powTransform : public StitchableKernel @@ -497,7 +543,7 @@ class powTransform : public StitchableKernel
497 Q_PROPERTY(double exponent READ get_exponent WRITE set_exponent RESET reset_exponent STORED false) 543 Q_PROPERTY(double exponent READ get_exponent WRITE set_exponent RESET reset_exponent STORED false)
498 BR_PROPERTY(double, exponent, 2) 544 BR_PROPERTY(double, exponent, 2)
499 545
500 - int preallocate(const Matrix &src, Matrix &dst) const 546 + int preallocate(const jit_matrix &src, jit_matrix &dst) const
501 { 547 {
502 dst.copyHeader(src); 548 dst.copyHeader(src);
503 dst.setFloating(true); 549 dst.setFloating(true);
@@ -530,7 +576,7 @@ BR_REGISTER(Transform, powTransform) @@ -530,7 +576,7 @@ BR_REGISTER(Transform, powTransform)
530 * \brief LLVM sum transform 576 * \brief LLVM sum transform
531 * \author Josh Klontz \cite jklontz 577 * \author Josh Klontz \cite jklontz
532 */ 578 */
533 -class sumTransform : public Kernel 579 +class sumTransform : public UnaryKernel
534 { 580 {
535 Q_OBJECT 581 Q_OBJECT
536 Q_PROPERTY(bool channels READ get_channels WRITE set_channels RESET reset_channels STORED false) 582 Q_PROPERTY(bool channels READ get_channels WRITE set_channels RESET reset_channels STORED false)
@@ -542,9 +588,9 @@ class sumTransform : public Kernel @@ -542,9 +588,9 @@ class sumTransform : public Kernel
542 BR_PROPERTY(bool, rows, true) 588 BR_PROPERTY(bool, rows, true)
543 BR_PROPERTY(bool, frames, true) 589 BR_PROPERTY(bool, frames, true)
544 590
545 - int preallocate(const Matrix &src, Matrix &dst) const 591 + int preallocate(const jit_matrix &src, jit_matrix &dst) const
546 { 592 {
547 - dst = Matrix(channels ? 1 : src.channels, columns ? 1 : src.columns, rows ? 1 : src.rows, frames ? 1 : src.frames, src.hash); 593 + dst = jit_matrix(channels ? 1 : src.channels, columns ? 1 : src.columns, rows ? 1 : src.rows, frames ? 1 : src.frames, src.hash);
548 dst.setBits(std::min(2*dst.bits(), dst.isFloating() ? 64 : 32)); 594 dst.setBits(std::min(2*dst.bits(), dst.isFloating() ? 64 : 32));
549 return dst.elements(); 595 return dst.elements();
550 } 596 }
@@ -622,23 +668,23 @@ class castTransform : public StitchableKernel @@ -622,23 +668,23 @@ class castTransform : public StitchableKernel
622 668
623 public: 669 public:
624 /*!< */ 670 /*!< */
625 - enum Type { u1 = Matrix::u1,  
626 - u8 = Matrix::u8,  
627 - u16 = Matrix::u16,  
628 - u32 = Matrix::u32,  
629 - u64 = Matrix::u64,  
630 - s8 = Matrix::s8,  
631 - s16 = Matrix::s16,  
632 - s32 = Matrix::s32,  
633 - s64 = Matrix::s64,  
634 - f16 = Matrix::f16,  
635 - f32 = Matrix::f32,  
636 - f64 = Matrix::f64 }; 671 + enum Type { u1 = jit_matrix::u1,
  672 + u8 = jit_matrix::u8,
  673 + u16 = jit_matrix::u16,
  674 + u32 = jit_matrix::u32,
  675 + u64 = jit_matrix::u64,
  676 + s8 = jit_matrix::s8,
  677 + s16 = jit_matrix::s16,
  678 + s32 = jit_matrix::s32,
  679 + s64 = jit_matrix::s64,
  680 + f16 = jit_matrix::f16,
  681 + f32 = jit_matrix::f32,
  682 + f64 = jit_matrix::f64 };
637 683
638 private: 684 private:
639 BR_PROPERTY(Type, type, f32) 685 BR_PROPERTY(Type, type, f32)
640 686
641 - int preallocate(const Matrix &src, Matrix &dst) const 687 + int preallocate(const jit_matrix &src, jit_matrix &dst) const
642 { 688 {
643 dst.copyHeader(src); 689 dst.copyHeader(src);
644 dst.setType(type); 690 dst.setType(type);
@@ -754,8 +800,8 @@ BR_REGISTER(Transform, clampTransform) @@ -754,8 +800,8 @@ BR_REGISTER(Transform, clampTransform)
754 class _QuantizeTransform : public Transform 800 class _QuantizeTransform : public Transform
755 { 801 {
756 Q_OBJECT 802 Q_OBJECT
757 - Q_PROPERTY(float a READ get_a WRITE set_a RESET reset_a STORED false)  
758 - Q_PROPERTY(float b READ get_b WRITE set_b RESET reset_b STORED false) 803 + Q_PROPERTY(float a READ get_a WRITE set_a RESET reset_a)
  804 + Q_PROPERTY(float b READ get_b WRITE set_b RESET reset_b)
759 BR_PROPERTY(float, a, 1) 805 BR_PROPERTY(float, a, 1)
760 BR_PROPERTY(float, b, 0) 806 BR_PROPERTY(float, b, 0)
761 807
@@ -821,24 +867,24 @@ class LLVMInitializer : public Initializer @@ -821,24 +867,24 @@ class LLVMInitializer : public Initializer
821 Type::getInt16Ty(getGlobalContext()), // hash 867 Type::getInt16Ty(getGlobalContext()), // hash
822 NULL); 868 NULL);
823 869
824 -// QSharedPointer<Transform> kernel(Transform::make("abs", NULL)); 870 + QSharedPointer<Transform> kernel(Transform::make("abs", NULL));
825 871
826 -// Template src, dst;  
827 -// src.m() = (Mat_<qint8>(2,2) << -1, -2, 3, 4);  
828 -// kernel->project(src, dst);  
829 -// qDebug() << dst.m(); 872 + Template src, dst;
  873 + src.m() = (Mat_<qint8>(2,2) << -1, -2, 3, 4);
  874 + kernel->project(src, dst);
  875 + qDebug() << dst.m();
830 876
831 -// src.m() = (Mat_<qint32>(2,2) << -1, -3, 9, 27);  
832 -// kernel->project(src, dst);  
833 -// qDebug() << dst.m(); 877 + src.m() = (Mat_<qint32>(2,2) << -1, -3, 9, 27);
  878 + kernel->project(src, dst);
  879 + qDebug() << dst.m();
834 880
835 -// src.m() = (Mat_<float>(2,2) << -1.5, -2.5, 3.5, 4.5);  
836 -// kernel->project(src, dst);  
837 -// qDebug() << dst.m(); 881 + src.m() = (Mat_<float>(2,2) << -1.5, -2.5, 3.5, 4.5);
  882 + kernel->project(src, dst);
  883 + qDebug() << dst.m();
838 884
839 -// src.m() = (Mat_<double>(2,2) << 1.75, 2.75, -3.75, -4.75);  
840 -// kernel->project(src, dst);  
841 -// qDebug() << dst.m(); 885 + src.m() = (Mat_<double>(2,2) << 1.75, 2.75, -3.75, -4.75);
  886 + kernel->project(src, dst);
  887 + qDebug() << dst.m();
842 } 888 }
843 889
844 void finalize() const 890 void finalize() const
@@ -884,4 +930,20 @@ class LLVMInitializer : public Initializer @@ -884,4 +930,20 @@ class LLVMInitializer : public Initializer
884 930
885 BR_REGISTER(Initializer, LLVMInitializer) 931 BR_REGISTER(Initializer, LLVMInitializer)
886 932
  933 +void jit_unary_apply(const jit_unary_kernel &kernel, const jit_matrix &src, jit_matrix &dst)
  934 +{
  935 + ((UnaryKernel*)kernel)->apply(src, dst);
  936 +}
  937 +
  938 +void jit_binary_apply(const jit_binary_kernel &kernel, const jit_matrix &srcA, const jit_matrix &srcB, jit_matrix &dst)
  939 +{
  940 + ((BinaryKernel*)kernel)->apply(srcA, srcB, dst);
  941 +}
  942 +
  943 +jit_unary_kernel jit_square()
  944 +{
  945 + static squareTransform transform;
  946 + return &transform;
  947 +}
  948 +
887 #include "llvm.moc" 949 #include "llvm.moc"
sdk/plugins/plugins.cmake
1 # Add source to BR_THIRDPARTY_SRC 1 # Add source to BR_THIRDPARTY_SRC
2 # Add libs to BR_THIRDPARTY_LIBS 2 # Add libs to BR_THIRDPARTY_LIBS
3 3
4 -include(ExternalProject)  
5 file(GLOB PLUGINS plugins/*.cpp) 4 file(GLOB PLUGINS plugins/*.cpp)
6 foreach(PLUGIN ${PLUGINS} ${BR_THIRDPARTY_PLUGINS}) 5 foreach(PLUGIN ${PLUGINS} ${BR_THIRDPARTY_PLUGINS})
7 get_filename_component(PLUGIN_BASENAME ${PLUGIN} NAME_WE) 6 get_filename_component(PLUGIN_BASENAME ${PLUGIN} NAME_WE)
share/openbr/cmake/FindIPC2013.cmake 0 โ†’ 100644
  1 +# ================================================================
  2 +# The Intel Perceptual Computing SDK 2013 CMake configuration file
  3 +#
  4 +# Usage from an external project:
  5 +# In your CMakeLists.txt, add these lines:
  6 +#
  7 +# find_package(IPC2013 REQUIRED)
  8 +# target_link_libraries(MY_TARGET ${IPC2013_LIBS})
  9 +# ================================================================
  10 +
  11 +find_path(IPC2013_DIR include/pxcimage.h "C:/Program Files/Intel/PCSDK")
  12 +include_directories(${IPC2013_DIR}/include)
  13 +link_directories(${IPC2013_DIR}/lib/x64)
  14 +set(IPC2013_LIBS libpxc)