summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/dnn/tensor.h
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/dnn/tensor.h')
-rw-r--r--ml/dlib/dlib/dnn/tensor.h686
1 files changed, 0 insertions, 686 deletions
diff --git a/ml/dlib/dlib/dnn/tensor.h b/ml/dlib/dlib/dnn/tensor.h
deleted file mode 100644
index 8039fe666..000000000
--- a/ml/dlib/dlib/dnn/tensor.h
+++ /dev/null
@@ -1,686 +0,0 @@
-// Copyright (C) 2015 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_DNn_TENSOR_H_
-#define DLIB_DNn_TENSOR_H_
-
-#include "tensor_abstract.h"
-#include <cstring>
-#include "../matrix.h"
-#include "cudnn_dlibapi.h"
-#include "gpu_data.h"
-#include "../byte_orderer.h"
-#include <memory>
-#include "../any.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class tensor;
- namespace cuda
- {
- void set_tensor (
- tensor& t,
- float value
- );
-
- void scale_tensor (
- tensor& t,
- float value
- );
- }
-
-// ----------------------------------------------------------------------------------------
-
- class tensor
- {
- public:
-
- tensor (
- ) :
- m_n(0), m_k(0), m_nr(0), m_nc(0), m_size(0)
- {
- }
-
- virtual ~tensor() {}
-
- long long num_samples() const { return m_n; }
- long long k() const { return m_k; }
- long long nr() const { return m_nr; }
- long long nc() const { return m_nc; }
- size_t size() const { return m_size; }
-
- typedef float* iterator;
- typedef const float* const_iterator;
- iterator begin() { return host(); }
- const_iterator begin() const { return host(); }
- iterator end() { return host()+size(); }
- const_iterator end() const { return host()+size(); }
-
- void async_copy_to_device() const
- {
- data().async_copy_to_device();
- }
-
- virtual const float* host() const = 0;
- virtual float* host() = 0;
- virtual float* host_write_only() = 0;
- virtual const float* device() const = 0;
- virtual float* device() = 0;
- virtual float* device_write_only() = 0;
-
- virtual const any& annotation() const = 0;
- virtual any& annotation() = 0;
-
- int device_id() const { return data().device_id(); }
-
- tensor& operator= (float val)
- {
-#ifdef DLIB_USE_CUDA
- // If you are using CUDA then presumably you will be mostly using tensors on
- // the GPU. So unless you seem to be actively working with the host side's
- // data then we do this initialization on the device side since this avoids a
- // host to device transfer that would likely immediately follow.
- if (data().device_ready())
- {
- cuda::set_tensor(*this, val);
- return *this;
- }
-#endif
- auto d = host_write_only();
- for (size_t i = 0; i < size(); ++i)
- d[i] = val;
-
- return *this;
- }
-
- tensor& operator*= (float val)
- {
-#ifdef DLIB_USE_CUDA
- cuda::scale_tensor(*this, val);
- return *this;
-#else
- for (auto& d : *this)
- d *= val;
-
- return *this;
-#endif
- }
-
- tensor& operator/= (float val)
- {
- *this *= 1.0/val;
- return *this;
- }
-
- template <typename EXP>
- tensor& operator= (const matrix_exp<EXP>& item)
- {
- DLIB_CASSERT(num_samples() == item.nr() &&
- nr()*nc()*k() == item.nc());
- static_assert((is_same_type<float, typename EXP::type>::value == true),
- "To assign a matrix to a tensor the matrix must contain float values");
-
- set_ptrm(host_write_only(), m_n, m_nr*m_nc*m_k) = item;
- return *this;
- }
-
- template <typename EXP>
- tensor& operator+= (const matrix_exp<EXP>& item)
- {
- DLIB_CASSERT(num_samples() == item.nr() &&
- nr()*nc()*k() == item.nc());
- static_assert((is_same_type<float, typename EXP::type>::value == true),
- "To assign a matrix to a tensor the matrix must contain float values");
- set_ptrm(host(), m_n, m_nr*m_nc*m_k) += item;
- return *this;
- }
-
- template <typename EXP>
- tensor& operator-= (const matrix_exp<EXP>& item)
- {
- DLIB_CASSERT(num_samples() == item.nr() &&
- nr()*nc()*k() == item.nc());
- static_assert((is_same_type<float, typename EXP::type>::value == true),
- "To assign a matrix to a tensor the matrix must contain float values");
- set_ptrm(host(), m_n, m_nr*m_nc*m_k) -= item;
- return *this;
- }
-
- template <typename EXP>
- void set_sample (
- unsigned long long idx,
- const matrix_exp<EXP>& item
- )
- {
- DLIB_CASSERT(idx < (unsigned long long)num_samples());
- DLIB_CASSERT(item.size() == nr()*nc()*k());
- static_assert((is_same_type<float, typename EXP::type>::value == true),
- "To assign a matrix to a tensor the matrix must contain float values");
- set_ptrm(host()+idx*item.size(), item.nr(), item.nc()) = item;
- }
-
-
- template <typename EXP>
- void add_to_sample (
- unsigned long long idx,
- const matrix_exp<EXP>& item
- )
- {
- DLIB_CASSERT(idx < (unsigned long long)num_samples());
- DLIB_CASSERT(item.size() == nr()*nc()*k());
- static_assert((is_same_type<float, typename EXP::type>::value == true),
- "To assign a matrix to a tensor the matrix must contain float values");
- set_ptrm(host()+idx*item.size(), item.nr(), item.nc()) += item;
- }
-
-
-#ifdef DLIB_USE_CUDA
- virtual const cuda::tensor_descriptor& get_cudnn_tensor_descriptor (
- ) const = 0;
-#endif
-
- friend void memcpy (
- tensor& dest,
- const tensor& src
- )
- {
- DLIB_CASSERT(dest.size() == src.size());
- memcpy(dest.data(), dest.get_alias_offset(),
- src.data(), src.get_alias_offset(),
- src.size());
- }
-
-
- protected:
-
- friend class alias_tensor;
-
- virtual gpu_data& data() = 0;
- virtual const gpu_data& data() const = 0;
- virtual size_t get_alias_offset() const { return 0; } // needed by alias_tensor.
-
- long long m_n;
- long long m_k;
- long long m_nr;
- long long m_nc;
- long long m_size; // always equal to m_n*m_k*m_nr*m_nc
- };
-
-// ----------------------------------------------------------------------------------------
-
- inline bool is_vector (
- const tensor& t
- )
- {
- return t.size() == (size_t)t.num_samples() ||
- t.size() == (size_t)t.k() ||
- t.size() == (size_t)t.nr() ||
- t.size() == (size_t)t.nc();
- }
-
-// ----------------------------------------------------------------------------------------
-
- inline const matrix_op<op_pointer_to_mat<float> > mat (
- const tensor& t,
- long long nr,
- long long nc
- )
- {
- DLIB_ASSERT(nr >= 0 && nc >= 0 ,
- "\tconst matrix_exp mat(tensor, nr, nc)"
- << "\n\t nr and nc must be >= 0"
- << "\n\t nr: " << nr
- << "\n\t nc: " << nc
- );
- DLIB_ASSERT(nr*nc == (long long)t.size() ,
- "\tconst matrix_exp mat(tensor, nr, nc)"
- << "\n\t The sizes don't match up."
- << "\n\t nr*nc: " << nr*nc
- << "\n\t t.size(): " << t.size()
- );
- typedef op_pointer_to_mat<float> op;
- return matrix_op<op>(op(t.host(),nr,nc));
- }
-
- inline const matrix_op<op_pointer_to_mat<float> > mat (
- const tensor& t
- )
- {
- if (t.size() != 0)
- return mat(t, t.num_samples(), t.size()/t.num_samples());
- else
- return mat((float*)0,0,0);
- }
-
- inline const matrix_op<op_pointer_to_mat<float> > image_plane (
- const tensor& t,
- long long sample = 0,
- long long k = 0
- )
- {
- DLIB_ASSERT(0 <= sample && sample < t.num_samples() &&
- 0 <= k && k < t.k() &&
- t.size() != 0,
- "\tconst matrix_exp image_plane(tensor,sample,k)"
- << "\n\t Invalid arguments were given to this function."
- << "\n\t sample: " << sample
- << "\n\t k: " << k
- << "\n\t t.num_samples(): " << t.num_samples()
- << "\n\t t.k(): " << t.k()
- << "\n\t t.size(): " << t.size()
- );
-
-
- typedef op_pointer_to_mat<float> op;
- return matrix_op<op>(op(t.host() + ((sample*t.k() + k)*t.nr())*t.nc(),
- t.nr(),
- t.nc()));
- }
-
-// ----------------------------------------------------------------------------------------
-
- inline bool have_same_dimensions (
- const tensor& a,
- const tensor& b
- )
- {
- return a.num_samples() == b.num_samples() &&
- a.k() == b.k() &&
- a.nr() == b.nr() &&
- a.nc() == b.nc();
- }
-
-// ----------------------------------------------------------------------------------------
-
- class resizable_tensor : public tensor
- {
- public:
- resizable_tensor(
- )
- {}
-
- template <typename EXP>
- resizable_tensor(
- const matrix_exp<EXP>& item
- )
- {
- set_size(item.nr(), item.nc());
- *this = item;
- }
-
- explicit resizable_tensor(
- long long n_, long long k_ = 1, long long nr_ = 1, long long nc_ = 1
- )
- {
- DLIB_ASSERT( n_ >= 0 && k_ >= 0 && nr_ >= 0 && nc_ >= 0);
-
- set_size(n_,k_,nr_,nc_);
- }
-
- resizable_tensor(const resizable_tensor& item) : _annotation(item.annotation())
- {
- copy_size(item);
- memcpy(*this, item);
- }
- resizable_tensor(const tensor& item) : _annotation(item.annotation())
- {
- copy_size(item);
- memcpy(*this, item);
- }
-
- resizable_tensor(resizable_tensor&& item) { swap(item); }
- resizable_tensor& operator=(resizable_tensor&& item) { swap(item); return *this; }
-
- virtual const float* host() const { return data_instance.host(); }
- virtual float* host() { return data_instance.host(); }
- virtual float* host_write_only() { return data_instance.host_write_only(); }
- virtual const float* device() const { return data_instance.device(); }
- virtual float* device() { return data_instance.device(); }
- virtual float* device_write_only() { return data_instance.device_write_only(); }
-
- virtual const any& annotation() const { return _annotation; }
- virtual any& annotation() { return _annotation; }
-
- void clear(
- )
- {
- set_size(0,0,0,0);
- _annotation.clear();
- // free underlying memory
- data_instance.set_size(0);
- }
-
- void copy_size (
- const tensor& item
- )
- {
- set_size(item.num_samples(), item.k(), item.nr(), item.nc());
- }
-
- resizable_tensor& operator= (float val)
- {
- tensor::operator=(val);
- return *this;
- }
-
- template <typename EXP>
- resizable_tensor& operator= (
- const matrix_exp<EXP>& item
- )
- {
- if (!(num_samples() == item.nr() && k()*nr()*nc() == item.nc()))
- set_size(item.nr(), item.nc());
- tensor::operator=(item);
- return *this;
- }
-
- void set_size(
- long long n_, long long k_ = 1, long long nr_ = 1, long long nc_ = 1
- )
- {
- DLIB_ASSERT( n_ >= 0 && k_ >= 0 && nr_ >= 0 && nc_ >= 0);
-
- m_n = n_;
- m_k = k_;
- m_nr = nr_;
- m_nc = nc_;
- m_size = n_*k_*nr_*nc_;
- if ((long long)data_instance.size() < m_size)
- data_instance.set_size(m_size);
-#ifdef DLIB_USE_CUDA
- cudnn_descriptor.set_size(m_n,m_k,m_nr,m_nc);
-#endif
- }
-
-
- resizable_tensor& operator= (const resizable_tensor& item)
- {
- resizable_tensor temp(item);
- temp.swap(*this);
- return *this;
- }
-
- resizable_tensor& operator= (const tensor& item)
- {
- resizable_tensor temp(item);
- temp.swap(*this);
- return *this;
- }
-
-
- void swap(resizable_tensor& item)
- {
- std::swap(m_n, item.m_n);
- std::swap(m_k, item.m_k);
- std::swap(m_nr, item.m_nr);
- std::swap(m_nc, item.m_nc);
- std::swap(m_size, item.m_size);
- std::swap(data_instance, item.data_instance);
- std::swap(_annotation, item._annotation);
-#ifdef DLIB_USE_CUDA
- std::swap(cudnn_descriptor, item.cudnn_descriptor);
-#endif
- }
-
-#ifdef DLIB_USE_CUDA
- virtual const cuda::tensor_descriptor& get_cudnn_tensor_descriptor (
- ) const { return cudnn_descriptor; }
-#endif
-
- private:
-
-#ifdef DLIB_USE_CUDA
- cuda::tensor_descriptor cudnn_descriptor;
-#endif
-
- gpu_data data_instance;
- any _annotation;
- virtual gpu_data& data() { return data_instance; }
- virtual const gpu_data& data() const { return data_instance; }
- };
-
- inline void serialize(const tensor& item, std::ostream& out)
- {
- int version = 2;
- serialize(version, out);
- serialize(item.num_samples(), out);
- serialize(item.k(), out);
- serialize(item.nr(), out);
- serialize(item.nc(), out);
- byte_orderer bo;
- auto sbuf = out.rdbuf();
- for (auto d : item)
- {
- // Write out our data as 4byte little endian IEEE floats rather than using
- // dlib's default float serialization. We do this because it will result in
- // more compact outputs. It's slightly less portable but it seems doubtful
- // that any CUDA enabled platform isn't going to use IEEE floats. But if one
- // does we can just update the serialization code here to handle it if such a
- // platform is encountered.
- bo.host_to_little(d);
- static_assert(sizeof(d)==4, "This serialization code assumes we are writing 4 byte floats");
- sbuf->sputn((char*)&d, sizeof(d));
- }
- }
-
- inline void deserialize(resizable_tensor& item, std::istream& in)
- {
- int version;
- deserialize(version, in);
- if (version != 2)
- throw serialization_error("Unexpected version found while deserializing dlib::resizable_tensor.");
-
- long long num_samples=0, k=0, nr=0, nc=0;
- deserialize(num_samples, in);
- deserialize(k, in);
- deserialize(nr, in);
- deserialize(nc, in);
- item.set_size(num_samples, k, nr, nc);
- byte_orderer bo;
- auto sbuf = in.rdbuf();
- for (auto& d : item)
- {
- static_assert(sizeof(d)==4, "This serialization code assumes we are writing 4 byte floats");
- if (sbuf->sgetn((char*)&d,sizeof(d)) != sizeof(d))
- {
- in.setstate(std::ios::badbit);
- throw serialization_error("Error reading data while deserializing dlib::resizable_tensor.");
- }
- bo.little_to_host(d);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- inline double dot(
- const tensor& a,
- const tensor& b
- )
- {
- DLIB_CASSERT(a.size() == b.size());
- const float* da = a.host();
- const float* db = b.host();
- double sum = 0;
- for (size_t i = 0; i < a.size(); ++i)
- sum += da[i]*db[i];
- return sum;
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class alias_tensor_instance : public tensor
- {
- alias_tensor_instance(
- ) : data_instance(0), _annotation(0), data_offset(0) {}
-
- public:
- friend class alias_tensor;
- friend class alias_tensor_const_instance;
-
- alias_tensor_instance& operator= (float val)
- {
- tensor::operator=(val);
- return *this;
- }
-
- template <typename EXP>
- alias_tensor_instance& operator= (const matrix_exp<EXP>& item)
- {
- tensor::operator=(item);
- return *this;
- }
-
- virtual const float* host() const { return data_instance->host()+data_offset; }
- virtual float* host() { return data_instance->host()+data_offset; }
- virtual float* host_write_only() { return data_instance->host()+data_offset; }
- virtual const float* device() const { return data_instance->device()+data_offset; }
- virtual float* device() { return data_instance->device()+data_offset; }
- virtual float* device_write_only() { return data_instance->device()+data_offset; }
-
- virtual const any& annotation() const { return *_annotation; }
- virtual any& annotation() { return *_annotation; }
-
-#ifdef DLIB_USE_CUDA
- virtual const cuda::tensor_descriptor& get_cudnn_tensor_descriptor (
- ) const { return *cudnn_descriptor; }
-#endif
- private:
-
- virtual size_t get_alias_offset() const { return data_offset; }
-
-#ifdef DLIB_USE_CUDA
- std::shared_ptr<cuda::tensor_descriptor> cudnn_descriptor;
-#endif
- gpu_data* data_instance;
- any* _annotation;
- size_t data_offset;
- virtual gpu_data& data() { return *data_instance; }
- virtual const gpu_data& data() const { return *data_instance; }
- };
-
-// ----------------------------------------------------------------------------------------
-
- class alias_tensor_const_instance
- {
- public:
- const tensor& get() const { return inst; }
- operator const tensor& () { return inst; }
-
- alias_tensor_const_instance(const alias_tensor_instance& item) : inst(item) {}
-
- private:
- alias_tensor_instance inst;
-
- friend class alias_tensor;
- alias_tensor_const_instance() {}
- };
-
-// ----------------------------------------------------------------------------------------
-
- class alias_tensor
- {
- public:
-
- alias_tensor (
- ) {}
-
- alias_tensor (
- long long n_, long long k_ = 1, long long nr_ = 1, long long nc_ = 1
- )
- {
- DLIB_ASSERT( n_ >= 0 && k_ >= 0 && nr_ >= 0 && nc_ >= 0);
-
- inst.m_n = n_;
- inst.m_k = k_;
- inst.m_nr = nr_;
- inst.m_nc = nc_;
- inst.m_size = n_*k_*nr_*nc_;
- }
-
- long long num_samples(
- ) const { return inst.m_n; }
-
- long long k(
- ) const { return inst.m_k; }
-
- long long nr(
- ) const { return inst.m_nr; }
-
- long long nc(
- ) const { return inst.m_nc; }
-
- size_t size(
- ) const { return inst.m_size; }
-
- alias_tensor_instance operator() (
- tensor& t,
- size_t offset = 0
- ) const
- {
- DLIB_CASSERT(offset+size() <= t.size(),
- "offset: "<<offset <<"\n"<<
- "size(): "<<size() <<"\n"<<
- "t.size(): "<<t.size() <<"\n");
-
-#ifdef DLIB_USE_CUDA
- if (!inst.cudnn_descriptor)
- {
- inst.cudnn_descriptor = std::make_shared<cuda::tensor_descriptor>();
- inst.cudnn_descriptor->set_size(inst.m_n, inst.m_k, inst.m_nr, inst.m_nc);
- }
-#endif
- inst.data_instance = &t.data();
- inst._annotation = &t.annotation();
- // Note that t might already be an aliasing tensor so we need to take that into
- // account.
- inst.data_offset = t.get_alias_offset()+offset;
- return inst;
- }
-
- alias_tensor_const_instance operator() (
- const tensor& t,
- size_t offset = 0
- ) const
- {
- alias_tensor_const_instance temp;
- temp.inst = (*this)(const_cast<tensor&>(t),offset);
- return temp;
- }
-
- private:
- mutable alias_tensor_instance inst;
- };
-
- inline void serialize(const alias_tensor& item, std::ostream& out)
- {
- int version = 1;
- serialize(version, out);
- serialize(item.num_samples(), out);
- serialize(item.k(), out);
- serialize(item.nr(), out);
- serialize(item.nc(), out);
- }
-
- inline void deserialize(alias_tensor& item, std::istream& in)
- {
- int version = 0;
- deserialize(version, in);
- if (version != 1)
- throw serialization_error("Unexpected version found while deserializing dlib::alias_tensor.");
- long long num_samples, k, nr, nc;
- deserialize(num_samples, in);
- deserialize(k, in);
- deserialize(nr, in);
- deserialize(nc, in);
- item = alias_tensor(num_samples, k, nr, nc);
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_DNn_TENSOR_H_
-