1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 //
5 // Copyright (C) 2017, Intel Corporation, all rights reserved.
6 // Third party copyrights are property of their respective owners.
7 
8 #ifndef __OPENCV_DNN_OP_HALIDE_HPP__
9 #define __OPENCV_DNN_OP_HALIDE_HPP__
10 
11 #ifdef HAVE_HALIDE
12 #if defined(__GNUC__) && __GNUC__ >= 5
13 #pragma GCC diagnostic push
14 #pragma GCC diagnostic ignored "-Wsuggest-override"
15 #endif
16 #include <Halide.h>
17 #if defined(__GNUC__) && __GNUC__ >= 5
18 #pragma GCC diagnostic pop
19 #endif
20 #endif  // HAVE_HALIDE
21 
22 namespace cv
23 {
24 namespace dnn
25 {
26 #ifdef HAVE_HALIDE
27     // Returns four-dimensional buffer with float32 type that wrap cv::Mat data.
28     // No data copy here.
29     Halide::Buffer<float> wrapToHalideBuffer(const Mat& mat);
30 
31     Halide::Buffer<float> wrapToHalideBuffer(const Mat& mat,
32                                              const std::vector<int>& shape);
33 
34     // Extract batch size, number of channels, width and height from buffer.
35     void getCanonicalSize(const Halide::Buffer<>& buffer, int* width, int* height,
36                           int* channels, int* batch);
37 
38     // Cast pointer and create copy of Halide buffer. No data copy.
39     Halide::Buffer<> halideBuffer(const Ptr<BackendWrapper>& ptr);
40 
41     std::vector<Halide::Buffer<> > halideBuffers(const std::vector<Ptr<BackendWrapper> >& ptrs);
42 
43     class HalideBackendNode : public BackendNode
44     {
45     public:
46         HalideBackendNode(const Halide::Func& func);
47 
48         HalideBackendNode(const std::vector<Halide::Func>& funcs);
49 
50         // Initialize from the <base> node but replace last function to <top>.
51         // It's using in case of layers fusing when we want to keep functions of
52         // root layer but replace top by fused one (i.e. conv+padding to relu+padding).
53         HalideBackendNode(const Ptr<HalideBackendNode>& base, const Halide::Func& top);
54 
55         std::vector<Halide::Func> funcs;
56     };
57 
58     class HalideBackendWrapper : public BackendWrapper
59     {
60     public:
61         HalideBackendWrapper(int targetId, const cv::Mat& m);
62 
63         HalideBackendWrapper(const Ptr<BackendWrapper>& base, const MatShape& shape);
64 
65         ~HalideBackendWrapper() CV_OVERRIDE;
66 
67         virtual void copyToHost() CV_OVERRIDE;
68 
69         virtual void setHostDirty() CV_OVERRIDE;
70 
71         Halide::Buffer<float> buffer;
72 
73     private:
74         bool managesDevMemory;
75     };
76 #endif  // HAVE_HALIDE
77 
78     // Extract batch size, number of channels, width and height from MatSize.
79     void getCanonicalSize(const MatSize& size, int* width, int* height,
80                           int* channels, int* batch);
81 
82     void getCanonicalSize(const MatShape& shape, int* width, int* height,
83                           int* channels, int* batch);
84 
85     // Realize Halide pipeline into output blobs.
86     void forwardHalide(std::vector<Ptr<BackendWrapper> > &outputs,
87                        const Ptr<BackendNode>& node);
88 
89     // Compile Halide pipeline to specific target. Use outputs to set bounds of functions.
90     void compileHalide(const std::vector<Mat> &outputs, Ptr<BackendNode>& node, int targetId);
91 
92     bool haveHalide();
93 }  // namespace dnn
94 }  // namespace cv
95 
96 #endif  // __OPENCV_DNN_OP_HALIDE_HPP__
97