39#include <cereal/cereal.hpp>
40#include <cereal/archives/json.hpp>
41#include <cereal/archives/binary.hpp>
42#include <cereal/types/string.hpp>
43#include <cereal/types/vector.hpp>
44#include <cereal/types/deque.hpp>
46#include "tiny_dnn/config.h"
47#include "tiny_dnn/util/macro.h"
48#include "tiny_dnn/util/aligned_allocator.h"
49#include "tiny_dnn/util/nn_error.h"
50#include "tiny_dnn/util/parallel_for.h"
51#include "tiny_dnn/util/random.h"
53#if defined(USE_OPENCL) || defined(USE_CUDA)
55#include "third_party/CLCudaAPI/clpp11.h"
57#include "third_party/CLCudaAPI/cupp11.h"
65typedef serial_size_t label_t;
67typedef serial_size_t layer_size_t;
69typedef std::vector<float_t, aligned_allocator<float_t, 64>> vec_t;
71typedef std::vector<vec_t> tensor_t;
84T* reverse_endian(T* p) {
85 std::reverse(
reinterpret_cast<char*
>(p),
reinterpret_cast<char*
>(p) +
sizeof(T));
89inline bool is_little_endian() {
91 return *(
char*) &x != 0;
96size_t max_index(
const T& vec) {
97 auto begin_iterator = std::begin(vec);
98 return std::max_element(begin_iterator, std::end(vec)) - begin_iterator;
101template<
typename T,
typename U>
102U rescale(T x, T src_min, T src_max, U dst_min, U dst_max) {
103 U value =
static_cast<U
>(((x - src_min) * (dst_max - dst_min)) / (src_max - src_min) + dst_min);
104 return std::min(dst_max, std::max(value, dst_min));
112template <
typename T>
inline T sqr(T value) {
return value*value; }
114inline bool isfinite(float_t x) {
118template <
typename Container>
inline bool has_infinite(
const Container& c) {
120 if (!isfinite(v)) return true;
124template <
typename Container>
125serial_size_t max_size(
const Container& c) {
126 typedef typename Container::value_type value_t;
127 const auto max_size = std::max_element(c.begin(), c.end(),
128 [](
const value_t& left,
const value_t& right) { return left.size() < right.size(); })->size();
129 assert(max_size <= std::numeric_limits<serial_size_t>::max());
130 return static_cast<serial_size_t
>(max_size);
133inline std::string format_str(
const char *fmt, ...) {
134 static char buf[2048];
137#pragma warning(disable:4996)
141 vsnprintf(buf,
sizeof(buf), fmt, args);
144#pragma warning(default:4996)
146 return std::string(buf);
152 reshape(width, height, depth);
155 index3d() : width_(0), height_(0), depth_(0) {}
157 void reshape(
T width,
T height,
T depth) {
162 if ((
long long) width * height * depth > std::numeric_limits<T>::max())
164 format_str(
"error while constructing layer: layer size too large for tiny-dnn\nWidthxHeightxChannels=%dx%dx%d >= max size of [%s](=%d)",
165 width, height, depth,
typeid(
T).name(), std::numeric_limits<T>::max()));
172 return (height_ *
channel +
y) * width_ +
x;
176 return width_ * height_;
180 return width_ * height_ * depth_;
183 template <
class Archive>
185 ar(cereal::make_nvp(
"width", width_));
186 ar(cereal::make_nvp(
"height", height_));
187 ar(cereal::make_nvp(
"depth", depth_));
199 return (
lhs.width_ ==
rhs.width_) && (
lhs.height_ ==
rhs.height_) && (
lhs.depth_ ==
rhs.depth_);
203bool operator != (
const index3d<T>& lhs,
const index3d<T>& rhs) {
204 return !(lhs == rhs);
207template <
typename Stream,
typename T>
208Stream& operator << (Stream& s,
const index3d<T>& d) {
209 s << d.width_ <<
"x" << d.height_ <<
"x" << d.depth_;
214std::ostream& operator << (std::ostream& s,
const index3d<T>& d) {
215 s << d.width_ <<
"x" << d.height_ <<
"x" << d.depth_;
219template <
typename Stream,
typename T>
220Stream& operator << (Stream& s,
const std::vector<index3d<T>>& d) {
222 for (serial_size_t i = 0; i < d.size(); i++) {
224 s <<
"[" << d[i] <<
"]";
232std::string to_string(T value) {
233 std::ostringstream os;
239#define CNN_USE_LAYER_MEMBERS using layer::parallelize_; \
240 using feedforward_layer<Activation>::h_
243#define CNN_LOG_VECTOR(vec, name)
262template <
typename T,
typename Pred,
typename Sum>
263serial_size_t sumif(
const std::vector<T>& vec, Pred p, Sum s) {
264 serial_size_t sum = 0;
265 for (serial_size_t i = 0; i < static_cast<serial_size_t>(vec.size()); i++) {
266 if (p(i)) sum += s(vec[i]);
271template <
typename T,
typename Pred>
272std::vector<T> filter(
const std::vector<T>& vec, Pred p) {
274 for (
size_t i = 0; i < vec.size(); i++) {
275 if (p(i)) res.push_back(vec[i]);
280template <
typename Result,
typename T,
typename Pred>
281std::vector<Result> map_(
const std::vector<T>& vec, Pred p) {
282 std::vector<Result> res;
283 for (
auto& v : vec) {
289enum class vector_type : int32_t {
301inline std::string to_string(vector_type vtype) {
304 case tiny_dnn::vector_type::data:
306 case tiny_dnn::vector_type::weight:
308 case tiny_dnn::vector_type::bias:
310 case tiny_dnn::vector_type::label:
312 case tiny_dnn::vector_type::aux:
319inline std::ostream& operator << (std::ostream& os, vector_type vtype) {
320 os << to_string(vtype);
324inline vector_type operator & (vector_type lhs, vector_type rhs) {
325 return (vector_type)(
static_cast<int32_t
>(lhs) &
static_cast<int32_t
>(rhs));
328inline bool is_trainable_weight(vector_type vtype) {
329 return (vtype & vector_type::weight) == vector_type::weight;
332inline std::vector<vector_type> std_input_order(
bool has_bias) {
334 return{ vector_type::data, vector_type::weight, vector_type::bias };
337 return{ vector_type::data, vector_type::weight };
341inline std::vector<vector_type> std_output_order(
bool has_activation) {
342 if (has_activation) {
343 return{ vector_type::data, vector_type::aux };
346 return{ vector_type::data };
350inline void fill_tensor(tensor_t& tensor, float_t value) {
351 for (
auto& t : tensor) {
352 std::fill(t.begin(), t.end(), value);
356inline void fill_tensor(tensor_t& tensor, float_t value, serial_size_t size) {
357 for (
auto& t : tensor) {
358 t.resize(size, value);
362inline serial_size_t conv_out_length(serial_size_t in_length,
363 serial_size_t window_size,
364 serial_size_t stride,
366 serial_size_t output_length;
368 if (pad_type == padding::same) {
369 output_length = in_length;
371 else if (pad_type == padding::valid) {
372 output_length = in_length - window_size + 1;
375 throw nn_error(
"Not recognized pad_type.");
377 return (output_length + stride - 1) / stride;
383inline void printAvailableDevice(
const serial_size_t platform_id,
384 const serial_size_t device_id) {
385#if defined(USE_OPENCL) || defined(USE_CUDA)
388 auto platform = CLCudaAPI::Platform(platform_id);
389 auto device = CLCudaAPI::Device(platform, device_id);
393 printf(
"\n## Printing device information...\n");
394 printf(
" > Platform ID %zu\n", platform_id);
395 printf(
" > Device ID %zu\n", device_id);
396 printf(
" > Framework version %s\n", device.Version().c_str());
397 printf(
" > Vendor %s\n", device.Vendor().c_str());
398 printf(
" > Device name %s\n", device.Name().c_str());
399 printf(
" > Device type %s\n", device.Type().c_str());
400 printf(
" > Max work-group size %zu\n", device.MaxWorkGroupSize());
401 printf(
" > Max thread dimensions %zu\n", device.MaxWorkItemDimensions());
402 printf(
" > Max work-group sizes:\n");
403 for (
auto i=
size_t{0}; i<device.MaxWorkItemDimensions(); ++i) {
404 printf(
" - in the %zu-dimension %zu\n", i, device.MaxWorkItemSizes()[i]);
406 printf(
" > Local memory per work-group %zu bytes\n", device.LocalMemSize());
407 printf(
" > Device capabilities %s\n", device.Capabilities().c_str());
408 printf(
" > Core clock rate %zu MHz\n", device.CoreClock());
409 printf(
" > Number of compute units %zu\n", device.ComputeUnits());
410 printf(
" > Total memory size %zu bytes\n", device.MemorySize());
411 printf(
" > Maximum allocatable memory %zu bytes\n", device.MaxAllocSize());
412 printf(
" > Memory clock rate %zu MHz\n", device.MemoryClock());
413 printf(
" > Memory bus width %zu bits\n", device.MemoryBusWidth());
415 nn_warn(
"TinyDNN was not build with OpenCL or CUDA support.");
419template<
typename T,
typename... Args>
420std::unique_ptr<T> make_unique(Args&&... args)
422 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
Simple image utility class.
Definition image.h:94
error exception class for tiny-dnn
Definition nn_error.h:37