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 21 # Let's suppose we want to build a JIT compiler with support for binary code:
22 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 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 28 endif()
... ...
sdk/plugins/llvm.cpp
... ... @@ -21,6 +21,7 @@
21 21 #include <openbr_plugin.h>
22 22  
23 23 #include "core/opencvutils.h"
  24 +#include "jitcv/jitcv.h"
24 25  
25 26 using namespace br;
26 27 using namespace cv;
... ... @@ -32,136 +33,71 @@ static FunctionPassManager *TheFunctionPassManager = NULL;
32 33 static FunctionPassManager *TheExtraFunctionPassManager = NULL;
33 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 89 return dbg;
154 90 }
155 91  
156   -struct MatrixBuilder : public Matrix
  92 +struct MatrixBuilder : public jit_matrix
157 93 {
158 94 Value *m;
159 95 IRBuilder<> *b;
160 96 Function *f;
161 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 102 static Value *zero() { return constant(0); }
167 103 static Value *one() { return constant(1); }
... ... @@ -263,7 +199,7 @@ struct MatrixBuilder : public Matrix
263 199 template <typename T>
264 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 204 const int bits = m.bits();
269 205 if (m.isFloating()) {
... ... @@ -283,7 +219,7 @@ struct MatrixBuilder : public Matrix
283 219 inline Type *ty() const { return ty(*this); }
284 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 224 const int bits = m.bits();
289 225 if (m.isFloating()) {
... ... @@ -307,30 +243,40 @@ namespace br
307 243 {
308 244  
309 245 /*!
310   - * \brief LLVM Kernel
  246 + * \brief LLVM Unary Kernel
311 247 * \author Josh Klontz \cite jklontz
312 248 */
313   -class Kernel : public UntrainableMetaTransform
  249 +class UnaryKernel : public UntrainableMetaTransform
314 250 {
315 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 254 kernel_t kernel;
319 255 quint16 hash;
320 256  
321 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 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 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 281 Constant *c = TheModule->getOrInsertFunction(qPrintable(mangledName(m)),
336 282 Type::getVoidTy(getGlobalContext()),
... ... @@ -356,7 +302,7 @@ private:
356 302 BasicBlock *kernel;
357 303 PHINode *i = MatrixBuilder::beginLoop(builder, function, entry, &kernel, "i");
358 304  
359   - Matrix n;
  305 + jit_matrix n;
360 306 preallocate(m, n);
361 307 build(MatrixBuilder(m, src, &builder, function, "src"), MatrixBuilder(n, dst, &builder, function, "dst"), i);
362 308  
... ... @@ -368,32 +314,132 @@ private:
368 314  
369 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 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 327 static QMutex compilerLock;
378 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 333 Function *function = TheModule->getFunction(qPrintable(functionName));
384 334 if (function == NULL) {
385   - function = compile(m);
  335 + function = compile(src);
386 336 while (TheFunctionPassManager->run(*function));
387 337 TheExtraFunctionPassManager->run(*function);
388 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 447 * \brief LLVM Stitchable Kernel
402 448 * \author Josh Klontz \cite jklontz
403 449 */
404   -class StitchableKernel : public Kernel
  450 +class StitchableKernel : public UnaryKernel
405 451 {
406 452 Q_OBJECT
407 453  
408 454 public:
409 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 459 dst.copyHeader(src);
414 460 return dst.elements();
... ... @@ -428,7 +474,7 @@ private:
428 474 * \brief LLVM stitch transform
429 475 * \author Josh Klontz \cite jklontz
430 476 */
431   -class stitchTransform : public Kernel
  477 +class stitchTransform : public UnaryKernel
432 478 {
433 479 Q_OBJECT
434 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 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 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 495 tmp = dst;
450 496 }
451 497 return dst.elements();
... ... @@ -457,7 +503,7 @@ class stitchTransform : public Kernel
457 503 MatrixBuilder dst(dst_);
458 504 Value *val = src.load(i);
459 505 foreach (Transform *transform, kernels) {
460   - static_cast<Kernel*>(transform)->preallocate(src, dst);
  506 + static_cast<UnaryKernel*>(transform)->preallocate(src, dst);
461 507 val = static_cast<StitchableKernel*>(transform)->stitch(src, dst, val);
462 508 src.copyHeader(dst);
463 509 src.m = dst.m;
... ... @@ -497,7 +543,7 @@ class powTransform : public StitchableKernel
497 543 Q_PROPERTY(double exponent READ get_exponent WRITE set_exponent RESET reset_exponent STORED false)
498 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 548 dst.copyHeader(src);
503 549 dst.setFloating(true);
... ... @@ -530,7 +576,7 @@ BR_REGISTER(Transform, powTransform)
530 576 * \brief LLVM sum transform
531 577 * \author Josh Klontz \cite jklontz
532 578 */
533   -class sumTransform : public Kernel
  579 +class sumTransform : public UnaryKernel
534 580 {
535 581 Q_OBJECT
536 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 588 BR_PROPERTY(bool, rows, true)
543 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 594 dst.setBits(std::min(2*dst.bits(), dst.isFloating() ? 64 : 32));
549 595 return dst.elements();
550 596 }
... ... @@ -622,23 +668,23 @@ class castTransform : public StitchableKernel
622 668  
623 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 684 private:
639 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 689 dst.copyHeader(src);
644 690 dst.setType(type);
... ... @@ -754,8 +800,8 @@ BR_REGISTER(Transform, clampTransform)
754 800 class _QuantizeTransform : public Transform
755 801 {
756 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 805 BR_PROPERTY(float, a, 1)
760 806 BR_PROPERTY(float, b, 0)
761 807  
... ... @@ -821,24 +867,24 @@ class LLVMInitializer : public Initializer
821 867 Type::getInt16Ty(getGlobalContext()), // hash
822 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 890 void finalize() const
... ... @@ -884,4 +930,20 @@ class LLVMInitializer : public Initializer
884 930  
885 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 949 #include "llvm.moc"
... ...
sdk/plugins/plugins.cmake
1 1 # Add source to BR_THIRDPARTY_SRC
2 2 # Add libs to BR_THIRDPARTY_LIBS
3 3  
4   -include(ExternalProject)
5 4 file(GLOB PLUGINS plugins/*.cpp)
6 5 foreach(PLUGIN ${PLUGINS} ${BR_THIRDPARTY_PLUGINS})
7 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)
... ...