1 /******************************************************************************
2 * Copyright (c) 2018-2018 Texas Instruments Incorporated - http://www.ti.com/
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Texas Instruments Incorporated nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 *****************************************************************************/
29 /*! \file pybind_executor.cpp */
31 // Requires https://github.com/pybind/pybind11, branch v2.2
32 // References:
33 // 1. https://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policies
34 // 2. https://pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html#buffer-protocol
35 // 3. https://www.python.org/dev/peps/pep-0008/
37 #include "pybind_common.h"
39 void AllocateMemory(const vector<ExecutionObject *>& eos);
40 void AllocateMemory(const vector<ExecutionObjectPipeline *>& eos);
41 void FreeMemory(const vector<ExecutionObject *>& eos);
42 void FreeMemory(const vector<ExecutionObjectPipeline *>& eos);
44 #define STRING(S) XSTRING(S)
45 #define XSTRING(S) #S
47 PYBIND11_MAKE_OPAQUE(EO);
49 // Class, method names follow PEP8, Style Guide for Python Code (Reference #3)
50 PYBIND11_MODULE(tidl, m)
51 {
52 m.doc() = std::string("TIDL API Python bindings ") + STRING(_BUILD_VER);
53 m.attr("__version__") = STRING(_BUILD_VER);
55 register_exception<Exception>(m, "TidlError");
57 enum_<DeviceType>(m, "DeviceType")
58 .value("DSP", DeviceType::DSP)
59 .value("EVE", DeviceType::EVE);
61 enum_<DeviceId>(m, "DeviceId")
62 .value("ID0", DeviceId::ID0)
63 .value("ID1", DeviceId::ID1)
64 .value("ID2", DeviceId::ID2)
65 .value("ID3", DeviceId::ID3);
67 init_configuration(m);
68 init_eo(m);
69 init_eop(m);
71 // For an explanation of return_value_policy, see Reference #1
72 class_<Executor>(m, "Executor")
73 .def(init<DeviceType, std::set<DeviceId>, Configuration, int>())
75 .def("get_num_execution_objects", &Executor::GetNumExecutionObjects,
76 "Returns number of ExecutionObjects created by this Executor")
78 .def_static("get_num_devices", &Executor::GetNumDevices,
79 "Returns number of devices of the specified type\n"
80 "available for TI DL offload")
82 .def_static("get_api_version", &Executor::GetAPIVersion)
84 .def("at", &Executor::operator[], return_value_policy::reference,
85 "Returns the ExecutionObject at the specified index");
87 // Used to expose the EO's internal input and output buffers to the
88 // python application using the Python buffer protocol (Reference #2)
89 class_<ArgInfo>(m, "ArgInfo", buffer_protocol())
90 .def_buffer([](ArgInfo& ai) -> buffer_info
91 {
92 return buffer_info(
93 ai.ptr(),
94 sizeof(char),
95 pybind11::format_descriptor<char>::format(),
96 1,
97 {ai.size()},
98 {1}
99 );
100 })
101 .def("size", &ArgInfo::size, "Size of the buffer in bytes")
102 .def("__repr__",
103 [](const ArgInfo& ai)
104 {
105 std::stringstream ss;
106 ss << "<ArgInfo: ptr= " << ai.ptr() << " size= " << ai.size()
107 << ">";
108 return ss.str();
109 });
111 // Helper functions to allocate memory from Python
112 m.def("allocate_memory",
113 (void (*)(const vector<EO *>&)) &AllocateMemory,
114 "Allocate input and output buffers for all ExecutionObjects");
116 m.def("free_memory",
117 (void (*)(const vector<EO *>&)) &FreeMemory,
118 "Free input and output buffers of all ExecutionObjects");
120 m.def("allocate_memory",
121 (void (*)(const vector<EOP *>&)) &AllocateMemory,
122 "Allocate input and output buffers for all ExecutionObjectPipelines");
124 m.def("free_memory",
125 (void (*)(const vector<EOP *>&)) &FreeMemory,
126 "Free input and output buffers of all ExecutionObjectPipelines");
128 m.def("enable_time_stamps",
129 &EnableTimeStamps,
130 "Enable timestamp generation for API events");
131 }