Beatmup
Beatmup::NNets::Dense Class Reference

Dense (linear) layer. More...

#include <dense.h>

Inheritance diagram for Beatmup::NNets::Dense:
Beatmup::NNets::AbstractOperation Beatmup::GL::LinearMapping

Public Member Functions

 Dense (Context &context, const std::string &name, int numOutputDims, bool useBias)
 Creates a Dense operation. More...
 
Size getOutputSize (int outputIndex=0) const
 Returns full size of a specific operation output. More...
 
int getInputCount () const
 Returns number of operation inputs. More...
 
int getOutputCount () const
 Returns number of operation outputs. More...
 
bool acceptsStorageInput (int index=0) const
 Returns true if the operation can take a Storage::View at a specific input. More...
 
bool acceptsVectorInput (int index=0) const
 Returns true if the operation can take a GL::Vector at a specific input. More...
 
bool acceptsVectorOutput (int index=0) const
 Returns true if the operation can take a GL::Vector at a specific output. More...
 
void getOutput (GL::Vector *&, int index=0)
 Returns a GL::Vector bound to a specific operation output. More...
 
void setInput (Storage::View &&view, int index=0)
 
void setInput (GL::Vector &vector, int index=0)
 
void setOutput (GL::Vector &vector, int index=0)
 
GL::Vector::Format getOutputVectorFormat () const
 
std::map< std::string, std::string > serialize () const
 Returns a serialized representation of th operation;. More...
 
void disconnect ()
 Assigns empty inputs and outputs. More...
 
unsigned long countMultiplyAdds () const
 Counts (approximate) number of multiply-adds used by this operation. More...
 
unsigned long countTexelFetches () const
 Counts (approximate) number of texels fetches. More...
 
- Public Member Functions inherited from Beatmup::NNets::AbstractOperation
virtual ~AbstractOperation ()
 
virtual bool usesGpu () const
 Returns true if the operation is run on GPU. More...
 
virtual bool acceptsTextureInput (int index=0) const
 Returns true if the operation can take a GL::TextureHandler at a specific input. More...
 
virtual bool acceptsStorageOutput (int index=0) const
 Returns true if the operation can take a Storage::View at a specific output. More...
 
virtual bool acceptsTextureOutput (int index=0) const
 Returns true if the operation can take a GL::TextureHandler at a specific output. More...
 
virtual Storage::View getOutput (int index=0)
 Returns a storage view bound to a specific operation output. More...
 
virtual void getOutput (GL::TextureHandler *&vector, int index=0)
 Returns a GL::TextureHandler bound to a specific operation output. More...
 
virtual void setOutput (Storage::View &&storage, int index=0)
 
virtual void setInput (GL::TextureHandler &image, int index=0)
 
virtual void setOutput (GL::TextureHandler &image, int index=0)
 
std::string getName () const
 

Static Public Member Functions

static bool initDeserializer ()
 Sets up deserialization of the operation. More...
 

Static Public Attributes

static const char * MATRIX_CHUNK_SUFFIX = "/w"
 suffix added to the op name to get the matrix chunk id in the model data More...
 
static const char * BIAS_CHUNK_SUFFIX = "/b"
 suffix added to the op name to get the bias chunk id in the model data More...
 

Private Member Functions

void prepare (GraphicPipeline &gpu, ChunkCollection &data, GL::ProgramBank &bank)
 Compiles GLSL shaders. More...
 
void execute (TaskThread &thread, GraphicPipeline &gpu)
 Executes the operation. More...
 
void getSampledChannels (int index, int &min, int &max) const
 Retrieves range of input features channels sampled at the same time for a specific input. More...
 
- Private Member Functions inherited from Beatmup::GL::LinearMapping
 LinearMapping (Context &context, bool forceFixed16=false)
 Instantiates LinearMapping. More...
 
 ~LinearMapping ()
 
void setMatrix (GraphicPipeline &gpu, const int width, const int height, const float *values)
 
void setBias (GraphicPipeline &gpu, const int height, const float *values)
 
void operator() (GraphicPipeline &gpu, TextureHandler &result, TextureHandler &input)
 
void prepare (GraphicPipeline &gpu, TextureHandler &output, TextureHandler &input, ProgramBank *bank=nullptr)
 Prepares the mapping for application (builds its GPU programs). More...
 
void process (GraphicPipeline &gpu, TextureHandler &output, TextureHandler &input)
 

Private Attributes

const int numOutputDims
 output feature vector size / number of rows in A More...
 
const bool useBias
 if true, the bias vector b is searched in the model data to add to the output More...
 
GL::VectorinputVector
 if not null, points the input vector x; otherwise the input is a storage view More...
 
GL::VectoroutputVector
 pointer to the output vector More...
 
Storage::View inputStorage
 if not empty, contains the input features; otherwise the input is a GL vector More...
 

Additional Inherited Members

- Protected Member Functions inherited from Beatmup::NNets::AbstractOperation
 AbstractOperation (const std::string &name)
 
virtual void execute (TaskThread &thread)
 Executes the operation within a specific CPU thread. More...
 
virtual int getInputPadding (int index=0) const
 Retrieves minimum required size of zero padding for a given input. More...
 

Detailed Description

Dense (linear) layer.

Computes A*x + b for input feature vector x, a matrix A and an optional bias vector b. Accepts a GL::Vector or a flat Storage view on input, amd only a GL::Vector on output.

Constraints:

  • Number of input channels must be a multiple of 8.
  • No activation function is applied on output (not yet implemented).

The matrix and bias coefficients are searched in chunks. The chunk names consist of the operation name followed by Dense::MATRIX_CHUNK_SUFFIX and Dense::BIAS_CHUNK_SUFFIX respectively. The chunk contents is a single precision floating point array. The matrix coefficients are taken in row-major order.

Definition at line 42 of file dense.h.

Constructor & Destructor Documentation

◆ Dense()

Dense::Dense ( Context context,
const std::string &  name,
int  numOutputDims,
bool  useBias 
)

Creates a Dense operation.

Parameters
contextA context instance
nameOperation name
numOutputDimsNumber of output dimensions
useBiasIf true, the bias vector addition is enabled.

Definition at line 30 of file dense.cpp.

30  :
32  LinearMapping(context, false),
34 {
35  OutOfRange::checkMin(numOutputDims, 1, "Positive number of output dimensions expected, %d got");
37 }
LinearMapping(Context &context, bool forceFixed16=false)
Instantiates LinearMapping.
AbstractOperation(const AbstractOperation &)=delete
disabling copying constructor
GL::Vector * outputVector
pointer to the output vector
Definition: dense.h:47
GL::Vector * inputVector
if not null, points the input vector x; otherwise the input is a storage view
Definition: dense.h:46
const bool useBias
if true, the bias vector b is searched in the model data to add to the output
Definition: dense.h:45
const int numOutputDims
output feature vector size / number of rows in A
Definition: dense.h:44
static void checkChannelNumber(int channel)
Checks whether a channel number points to the first channel in a texture.
Definition: storage.h:290
static void checkMin(const datatype value, const datatype min, const char *message)
Definition: exception.h:92

Member Function Documentation

◆ prepare()

void Dense::prepare ( GraphicPipeline gpu,
ChunkCollection data,
GL::ProgramBank bank 
)
privatevirtual

Compiles GLSL shaders.

Parameters
[in,out]gpuA graphic pipeline instance
[in,out]dataChunkfile containing operation data (e.g. weights and biases)
[in,out]bankA program bank with existing GLSL programs to be reused when possible. If a new program is built, it is added to the bank.

Implements Beatmup::NNets::AbstractOperation.

Definition at line 144 of file dense.cpp.

144  {
145  RuntimeError::check(inputVector || inputStorage, "Input is not provided to Dense operation " + getName());
146  RuntimeError::check(outputVector, "Output is not provided to Dense operation " + getName());
147 
148  const int numInputDims = inputVector ? inputVector->getSize() : inputStorage.getSize().volume();
149 
150  // set matrix
151  const Chunk matrix(data, getName() + MATRIX_CHUNK_SUFFIX);
152  if (matrix.size() != numInputDims * numOutputDims * sizeof(float))
153  throw InconsistentModelData(this, "Matrix size mismatch");
154  LinearMapping::setMatrix(gpu, numInputDims, numOutputDims, matrix.ptr<float>());
155 
156  // set bias
157  if (useBias) {
158  const Chunk bias(data, getName() + BIAS_CHUNK_SUFFIX);
159  if (bias.size() != numOutputDims * sizeof(float))
160  throw InconsistentModelData(this, "Bias size mismatch");
161  LinearMapping::setBias(gpu, numOutputDims, bias.ptr<float>());
162  }
163 
164  // prepare
165  if (inputVector) {
166  LinearMapping::prepare(gpu, *outputVector, *inputVector, &bank);
167  }
168  else {
169  Storage::TextureHandler inputHandle(inputStorage, 0);
170  LinearMapping::prepare(gpu, *outputVector, inputHandle, &bank);
171  }
172 }
Simply a piece of binary data of a specific size.
Definition: chunkfile.h:210
Matrix * matrix
the matrix ("A")
Vector * bias
optional bias vector ("b")
const int size
number of samples in the vector
int getSize() const
Returns the length of the vector.
std::string getName() const
Definition: operation.h:242
static const char * BIAS_CHUNK_SUFFIX
suffix added to the op name to get the bias chunk id in the model data
Definition: dense.h:56
static const char * MATRIX_CHUNK_SUFFIX
suffix added to the op name to get the matrix chunk id in the model data
Definition: dense.h:55
Storage::View inputStorage
if not empty, contains the input features; otherwise the input is a GL vector
Definition: dense.h:48
int volume() const
Definition: storage.h:79
TextureHandler representation of a pack of 4 channels from a non-empty View.
Definition: storage.h:403
static void check(const bool condition, const std::string &message)
Definition: exception.h:64

◆ execute()

void Dense::execute ( TaskThread thread,
GraphicPipeline gpu 
)
privatevirtual

Executes the operation.

The operation should be prepared.

Parameters
[in,out]threadCalling CPU thread descriptor
[in,out]gpuA graphic pipeline instance

Implements Beatmup::NNets::AbstractOperation.

Definition at line 175 of file dense.cpp.

175  {
176  if (inputVector) {
177  LinearMapping::process(gpu, *outputVector, *inputVector);
178  }
179  else {
180  Storage::TextureHandler inputHandle(inputStorage, 0);
181  LinearMapping::process(gpu, *outputVector, inputHandle);
182  }
183 }

◆ getSampledChannels()

void Dense::getSampledChannels ( int  index,
int &  min,
int &  max 
) const
privatevirtual

Retrieves range of input features channels sampled at the same time for a specific input.

The operation would typically take the entire storage and sample it at once, if needed. If the number of textures in a storage exceeds the number of texture samplers that the GPU may use simultaneously, an exception occurs. This function provides the necessary information to limit the number of textures in the storage when allocating it. When the limit is reached, multiple channels are packed into a single texture in the storage.

Parameters
[in]indexThe input index. Expected to fall in the valid range, i.e. from zero to getInputCount() - 1 inclusive.
[out]minThe minimum number of channels that can be sampled at once
[out]maxThe maximum number of channels that can be sampled at once

Implements Beatmup::NNets::AbstractOperation.

Definition at line 186 of file dense.cpp.

186  {
187  min = max = (index == 0 ? 4 : 0);
188 }
CustomPoint< numeric > min(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:724
CustomPoint< numeric > max(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:728
jlong jint index

◆ getOutputSize()

Size Beatmup::NNets::Dense::getOutputSize ( int  outputIndex = 0) const
inlinevirtual

Returns full size of a specific operation output.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 67 of file dense.h.

67  {
68  return Size(1, numOutputDims, 1);
69  }

◆ getInputCount()

int Beatmup::NNets::Dense::getInputCount ( ) const
inlinevirtual

Returns number of operation inputs.

Inputs are then indexed from zero to the returned value minus one inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 71 of file dense.h.

71 { return 1; }

◆ getOutputCount()

int Beatmup::NNets::Dense::getOutputCount ( ) const
inlinevirtual

Returns number of operation outputs.

Outputs are then indexed from zero to the returned value minus one inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 72 of file dense.h.

72 { return 1; }

◆ acceptsStorageInput()

bool Beatmup::NNets::Dense::acceptsStorageInput ( int  index = 0) const
inlinevirtual

Returns true if the operation can take a Storage::View at a specific input.

Neural network operations may accept different kinds of data containers on inputs and outputs, namely Storage::View, GL::Vector and textures. This function is used to check whether a given operation accepts a storage view on input.

Parameters
[in]indexThe input index. Expected to fall in the valid range, i.e. from zero to getInputCount() - 1 inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 74 of file dense.h.

74 { return index == 0; }

◆ acceptsVectorInput()

bool Beatmup::NNets::Dense::acceptsVectorInput ( int  index = 0) const
inlinevirtual

Returns true if the operation can take a GL::Vector at a specific input.

Neural network operations may accept different kinds of data containers on inputs and outputs, namely Storage::View, GL::Vector and textures. This function is used to check whether a given operation accepts a vector on input.

Parameters
[in]indexThe input index. Expected to fall in the valid range, i.e. from zero to getInputCount() - 1 inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 75 of file dense.h.

75 { return index == 0; }

◆ acceptsVectorOutput()

bool Beatmup::NNets::Dense::acceptsVectorOutput ( int  index = 0) const
inlinevirtual

Returns true if the operation can take a GL::Vector at a specific output.

Neural network operations may accept different kinds of data containers on outputs and outputs, namely Storage::View, GL::Vector and textures. This function is used to check whether a given operation accepts a vector on output.

Parameters
[in]indexThe output index. Expected to fall in the valid range, i.e. from zero to getOutputCount() - 1 inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 76 of file dense.h.

76 { return index == 0; }

◆ getOutput()

void Dense::getOutput ( GL::Vector *&  vector,
int  index = 0 
)
virtual

Returns a GL::Vector bound to a specific operation output.

Parameters
[out]vectorPointer to the GL::Vector. If no vector is bound, becomes null.
[in]indexThe output index. Expected to fall in the valid range, i.e. from zero to getOutputCount() - 1 inclusive.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 40 of file dense.cpp.

40  {
41  OutOfRange::check(index, 0, 1, "Output index out of range: %d");
42  vector = this->outputVector;
43 }
static void check(const datatype value, const datatype min, const datatype max, const char *message)
Definition: exception.h:86

◆ setInput() [1/2]

void Dense::setInput ( Storage::View &&  view,
int  index = 0 
)
virtual

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 46 of file dense.cpp.

46  {
47  OutOfRange::check(index, 0, 1, "Input index out of range: %d");
48  if (view) {
49  RuntimeError::check(view.getStorage().getPadding() == 0, "Storages with padding are not supported");
50  const auto& storage = view.getStorage();
51  RuntimeError::check(view.getNumberOfTextures() == 1 && storage.getTextureWidth() == 1, "Input size mismatch: a column-like view is expected");
52  }
53  inputStorage = std::move(view);
54  inputVector = nullptr;
55 }
int getNumberOfTextures() const
Returns total number of textures in the storage view.
Definition: storage.h:355
int getPadding() const
Returns storage padding.
Definition: storage.h:268

◆ setInput() [2/2]

void Dense::setInput ( GL::Vector vector,
int  index = 0 
)
virtual

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 58 of file dense.cpp.

58  {
59  OutOfRange::check(index, 0, 1, "Input index out of range: %d");
61  inputVector = &vector;
62 }
friend class View
Definition: storage.h:135

◆ setOutput()

void Dense::setOutput ( GL::Vector vector,
int  index = 0 
)
virtual

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 65 of file dense.cpp.

65  {
66  outputVector = &vector;
67 }

◆ getOutputVectorFormat()

GL::Vector::Format Dense::getOutputVectorFormat ( ) const
Returns
a supported data format for GL::Vector on output.

Definition at line 70 of file dense.cpp.

70  {
71 #ifdef BEATMUP_OPENGLVERSION_GLES20
73 #else
75 #endif
76 }
@ FIXED16
16 bit per element
@ FLOAT
32 bit per element, floating point

◆ serialize()

std::map< std::string, std::string > Dense::serialize ( ) const
virtual

Returns a serialized representation of th operation;.

Implements Beatmup::NNets::AbstractOperation.

Definition at line 79 of file dense.cpp.

79  {
80  return {
81  { "_name", getName() },
82  { "_type", "dense" },
83  { "output_dims", std::to_string(numOutputDims) },
84  { "use_bias", useBias ? "true" : "false" },
85  };
86 }
std::string to_string(Beatmup::NNets::ActivationFunction function)

◆ disconnect()

void Dense::disconnect ( )
virtual

Assigns empty inputs and outputs.

Implements Beatmup::NNets::AbstractOperation.

Definition at line 114 of file dense.cpp.

114  {
115  inputVector = nullptr;
117  outputVector = nullptr;
118 }

◆ countMultiplyAdds()

unsigned long Dense::countMultiplyAdds ( ) const
virtual

Counts (approximate) number of multiply-adds used by this operation.

A single multiply-add is one multiplication and one addition.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 121 of file dense.cpp.

121  {
122  const int numInputDims = inputVector ? inputVector->getSize() : inputStorage.getSize().volume();
123  return numInputDims * numOutputDims;
124 }

◆ countTexelFetches()

unsigned long Dense::countTexelFetches ( ) const
virtual

Counts (approximate) number of texels fetches.

Reimplemented from Beatmup::NNets::AbstractOperation.

Definition at line 127 of file dense.cpp.

127  {
128  const unsigned long numInputDims = inputVector ? inputVector->getSize() : inputStorage.getSize().volume();
129  // sampling the matrix
130  unsigned long count = numInputDims * numOutputDims / 4;
131  // sampling the bias
132  if (useBias)
133  count += numOutputDims / 4;
134 #ifdef BEATMUP_OPENGLVERSION_GLES20
135  // using 16 bit fixed point format
136  count *= 2;
137 #endif
138  // sampling the input vector
140  return count;
141 }
const int getHeight() const
Height of the texture in pixels.
JNIEnv jlong jint jint count

◆ initDeserializer()

static bool Beatmup::NNets::Dense::initDeserializer ( )
static

Sets up deserialization of the operation.

Member Data Documentation

◆ numOutputDims

const int Beatmup::NNets::Dense::numOutputDims
private

output feature vector size / number of rows in A

Definition at line 44 of file dense.h.

◆ useBias

const bool Beatmup::NNets::Dense::useBias
private

if true, the bias vector b is searched in the model data to add to the output

Definition at line 45 of file dense.h.

◆ inputVector

GL::Vector* Beatmup::NNets::Dense::inputVector
private

if not null, points the input vector x; otherwise the input is a storage view

Definition at line 46 of file dense.h.

◆ outputVector

GL::Vector* Beatmup::NNets::Dense::outputVector
private

pointer to the output vector

Definition at line 47 of file dense.h.

◆ inputStorage

Storage::View Beatmup::NNets::Dense::inputStorage
private

if not empty, contains the input features; otherwise the input is a GL vector

Definition at line 48 of file dense.h.

◆ MATRIX_CHUNK_SUFFIX

const char * Dense::MATRIX_CHUNK_SUFFIX = "/w"
static

suffix added to the op name to get the matrix chunk id in the model data

Definition at line 55 of file dense.h.

◆ BIAS_CHUNK_SUFFIX

const char * Dense::BIAS_CHUNK_SUFFIX = "/b"
static

suffix added to the op name to get the bias chunk id in the model data

Definition at line 56 of file dense.h.


The documentation for this class was generated from the following files: