NVIDIA NvNeural SDK  2022.2
GPU inference framework for NVIDIA Nsight Deep Learning Designer
BaseLayer.h
Go to the documentation of this file.
1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2020-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 
25 
26 #ifndef NVNEURAL_BASELAYER_H
27 #define NVNEURAL_BASELAYER_H
28 
29 #include <nvneural/CoreTypes.h>
30 #include <nvneural/CoreHelpers.h>
31 #include <nvneural/LayerTypes.h>
32 #include <string>
33 #include <sstream>
34 #include <vector>
35 
36 namespace nvneural {
37 
73  class BaseLayer : public ILayer
74  {
75  public:
76  NeuralResult setName(const char* pName) noexcept override;
77  const char* name() const noexcept override;
78 
79  NeuralResult setNetworkRuntime(INetworkRuntime* pNetworkRuntime) noexcept override;
80 
81  NetworkBackendId backendId() const noexcept override;
82  TensorFormat tensorFormat() const noexcept override;
83  TensorDimension stepping() const noexcept override;
84  // Derived: TensorDimension dimensions() const noexcept override;
85  TensorDimension internalDimensions() const noexcept override;
86  size_t tensorBufferSize() const noexcept override;
87  size_t tensorInternalBufferSize() const noexcept override;
88 
89 
90  NeuralResult loadFromParameters(const IParameterNode* pParameters) noexcept override;
91 
93  ActivationFunctionId activationFunction() const noexcept override;
94 
95  NeuralResult setActivationCoefficient(std::size_t coefficientIndex, float value) noexcept override;
96  float activationCoefficient(std::size_t coefficientIndex) const noexcept override;
97 
98  NeuralResult setPermanent(bool permanent) noexcept override;
99  bool isPermanent() const noexcept override;
100 
101  NeuralResult setAffected(bool affected) noexcept override;
102  bool isAffected() const noexcept override;
103 
104  NeuralResult getInputLayers(ILayerList** ppInputLayers) const noexcept override;
105  NeuralResult setInputLayer(std::size_t index, ILayer* pLayer) noexcept override;
106 
107  // Derived: NeuralResult reshape() noexcept override;
108  // Derived: NeuralResult evaluateForward() noexcept override;
109 
110  const char* weightsName() const noexcept override;
111  NeuralResult setWeightsName(const char* pWeightsName) noexcept override;
112 
113  TensorDimension weightsDimensions(const char* pWeightsName, WeightsQuery queryType) const noexcept override;
114 
115  NeuralResult getData(void** ppOut, TensorFormat format, const ILayer* pRequestingLayer) noexcept override;
116  NeuralResult getConstData(const void** ppOut, TensorFormat format, const ILayer* pRequestingLayer) const noexcept override;
117  NeuralResult getCpuConstData(void* pOutBuffer, size_t bufferByteCount, size_t* pBytesCopied, TensorFormat format) const noexcept override;
118 
119  protected:
120  BaseLayer();
125 
131  NeuralResult allocateMemoryBlock(MemoryHandle* pHandle, size_t byteCount) noexcept;
132 
139  NeuralResult allocateMemoryBlock(MemoryHandle* pHandle, size_t byteCount, const char* pTrackingKey) noexcept;
140 
142  void* data(TensorFormat format);
143 
149  const ILayer* inputLayer(size_t index) const;
150 
152  ILayer* inputLayer(size_t index);
153 
157  size_t inputLayerCount() const;
158 
184  void registerImplementation(NetworkBackendId backendId, TensorDataType elementType, TensorDataLayout layout, int penalty);
185 
192  virtual void onImplementationChanged() const;
193 
199  const void* weightsData(const char* pWeightsName) const;
200 
207  TensorDimension loadedWeightsSize(const ILayer* pWeightsLayer, const char* pWeightsName) const;
208 
213  template<typename... Indices>
214  bool verifyInputConnected(Indices... indices) const noexcept
215  {
216  const std::size_t arraySize = sizeof...(Indices);
217  const std::array<size_t, arraySize> checklist = { (size_t)indices... };
218  bool result = true;
219  size_t checklistIndex;
220 
221  for (checklistIndex = 0; checklistIndex < arraySize; ++checklistIndex)
222  {
223  if (!inputLayer(checklist[checklistIndex]))
224  {
225  result = false;
226  break;
227  }
228  }
229 
230  if (!result)
231  {
232  std::stringstream errorStream;
233  errorStream << name() << ": These mandatory inputs are not connected: " << checklist[checklistIndex];
234  for (checklistIndex += 1; checklistIndex < arraySize; ++checklistIndex)
235  {
236  const std::size_t inputIndex = checklist[checklistIndex];
237  if (!inputLayer(inputIndex))
238  {
239  errorStream << ", " << inputIndex;
240  }
241  }
242 
243  DefaultLogger()->logError(0, "%s", errorStream.str().c_str());
244  return false;
245  }
246  else
247  {
248  return true;
249  }
250  }
251 
255  void requestReshape() noexcept;
256 
259 
261  enum class LoadResult : std::uint16_t
262  {
263  Success = 0,
264  Failure = 1,
265  NonNumericInput = 2,
266  CouldNotTranslate = 3,
267  };
268 
278  static LoadResult load2ElementParameter(const std::vector<std::string>& inArray, size_t& outElementX, size_t& outElementY, size_t inFill, bool inFillFirstElement = false)
279  {
280  // Sanity check the input array
281  if (inArray.empty())
282  {
283  return LoadResult::Failure;
284  }
285 
286  // Calculate the fill which needs the first element, it is saved for later use
288  size_t calcFill = inFill;
289 
290  size_t firstElement = inFill;
291  if (isdigit(inArray[0][0]))
292  {
293  try
294  {
295  firstElement = static_cast<size_t>(std::stoul(inArray[0]));
296  }
297  catch (const std::exception&)
298  {
300  }
301  }
302  else
303  {
305  }
306 
307  if (inFillFirstElement)
308  {
309  if (status != LoadResult::Success)
310  {
311  return LoadResult::Failure;
312  }
313  calcFill = firstElement;
314  }
315 
316  // Loaded elements go here locally, so on error, outElements is not changed.
317  size_t elementsOut[2] = { calcFill, calcFill };
318 
319  // Deal with the saved first element from above
320  if (status == LoadResult::Success)
321  {
322  elementsOut[0] = firstElement;
323  }
324 
325  // Deal with the second element
326  size_t secondElement = calcFill;
327  if (inArray.size() >= 2)
328  {
329  if (isdigit(inArray[1].data()[0]))
330  {
331  try
332  {
333  secondElement = static_cast<size_t>(std::stoul(inArray[1]));
334  }
335  catch (const std::exception&)
336  {
338  }
339  }
340  else
341  {
343  }
344  }
345 
346  elementsOut[1] = secondElement;
347 
348  // Finalize output
349  outElementX = elementsOut[0];
350  outElementY = elementsOut[1];
351 
352  return status;
353  }
354 
356 
357  private:
358  ActivationFunctionId m_activationFunction;
359  std::vector<float> m_activationCoefficients;
360  std::string m_name;
361  bool m_permanent;
362  bool m_affected;
363  std::string m_weightsName;
364 
365  INetworkRuntime* m_pNetwork;
366  INetworkBackend* m_pBackend;
367  std::vector<ILayer*> m_inputLayers;
368 
369  struct InternalImplementation
370  {
372  TensorFormat format;
373  int penalty;
374  };
375  std::vector<InternalImplementation> m_implementations;
376  mutable const InternalImplementation* m_pCurrentImplementation;
377 
379  void updateImplementation() const;
380  };
381 
382 } // namespace nvneural
383 
384 #endif // NVNEURAL_BASELAYER_H
Common helper classes and template function implementations.
ILogger * DefaultLogger()
Returns a pointer to the default logger for this module.
Definition: Logging.cpp:38
Fundamental NvNeural data types are declared here.
TensorDataType
Enumeration describing common tensor element types.
Definition: CoreTypes.h:60
TensorDataLayout
Enumeration describing common tensor data layouts.
Definition: CoreTypes.h:77
MemoryHandle__type * MemoryHandle
Opaque typedef used to represent INetworkBackend memory handles.
Definition: CoreTypes.h:626
NetworkBackendId
Enumeration describing common network backends.
Definition: CoreTypes.h:239
ActivationFunctionId
Enumeration describing common activation functions.
Definition: CoreTypes.h:259
NeuralResult
NeuralResult is a generic success/failure result type similar to COM HRESULT.
Definition: CoreTypes.h:275
@ Success
Operation succeeded. Generic result.
@ Failure
Operation failed. Generic result.
Interface types needed by layer objects.
WeightsQuery
WeightsQuery describes the different types of queries for weights data.
Definition: LayerTypes.h:39
BaseLayer provides common implementations for most of ILayer.
Definition: BaseLayer.h:74
void * data(TensorFormat format)
Returns a pointer to the output tensor memory in the provided format.
Definition: BaseLayer.cpp:310
NeuralResult setWeightsName(const char *pWeightsName) noexcept
Sets the name used to identify this layer's weights.
Definition: BaseLayer.cpp:340
NeuralResult loadFromParameters(const IParameterNode *pParameters) noexcept
Loads layer parameters from a serialized key-value representation.
Definition: BaseLayer.cpp:147
const char * weightsName() const noexcept
Retrieves the name used to identify this layer's weights.
Definition: BaseLayer.cpp:335
NeuralResult setActivationCoefficient(std::size_t coefficientIndex, float value) noexcept
Sets an activation coefficient.
Definition: BaseLayer.cpp:163
INetworkRuntime * networkRuntime() const
Returns the INetworkRuntime object most recently set with setNetworkRuntime.
Definition: BaseLayer.cpp:88
NeuralResult setName(const char *pName) noexcept
Sets the layer name.
Definition: BaseLayer.cpp:46
TensorDimension stepping() const noexcept
Returns the internal storage stride consumed by this layer implementation.
Definition: BaseLayer.cpp:119
NeuralResult setActivationFunction(ActivationFunctionId activationFunction) noexcept
Sets the activation function attached to the layer.
Definition: BaseLayer.cpp:152
TensorDimension internalDimensions() const noexcept
Retrieves the dimensions of the layer's output tensor as allocated internally.
Definition: BaseLayer.cpp:124
size_t tensorInternalBufferSize() const noexcept
Retrieves the dimensions of the layer's output tensor as allocated internally.
Definition: BaseLayer.cpp:139
NeuralResult allocateMemoryBlock(MemoryHandle *pHandle, size_t byteCount) noexcept
Allocates a memory block of the requested size.
Definition: BaseLayer.cpp:98
bool isPermanent() const noexcept
Returns the current status of the "permanent" flag.
Definition: BaseLayer.cpp:204
NetworkBackendId backendId() const noexcept
Returns the backend ID associated with this layer implementation.
Definition: BaseLayer.cpp:458
virtual void onImplementationChanged() const
Callback for derived classes to know that the "preferred implementation" has changed.
Definition: BaseLayer.cpp:387
const void * weightsData(const char *pWeightsName) const
Returns a pointer to device-side memory containing the indicated weights data.
Definition: BaseLayer.cpp:355
NeuralResult getCpuConstData(void *pOutBuffer, size_t bufferByteCount, size_t *pBytesCopied, TensorFormat format) const noexcept
Retrieves read-only CPU-side memory for the layer's output.
Definition: BaseLayer.cpp:270
ActivationFunctionId activationFunction() const noexcept
Retrieves the activation function attached to this layer.
Definition: BaseLayer.cpp:158
NeuralResult setNetworkRuntime(INetworkRuntime *pNetworkRuntime) noexcept
Informs the layer it has been attached to a new network.
Definition: BaseLayer.cpp:67
size_t tensorBufferSize() const noexcept
Retrieve the size of the layer's output tensor buffer in bytes.
Definition: BaseLayer.cpp:131
const char * name() const noexcept
Retrieves the layer name.
Definition: BaseLayer.cpp:62
NeuralResult getConstData(const void **ppOut, TensorFormat format, const ILayer *pRequestingLayer) const noexcept
Retrieves read-only device-side memory for the layer's output.
Definition: BaseLayer.cpp:245
static LoadResult load2ElementParameter(const std::vector< std::string > &inArray, size_t &outElementX, size_t &outElementY, size_t inFill, bool inFillFirstElement=false)
Helper class that takes a vector of strings and loads 2 size_t elements.
Definition: BaseLayer.h:278
float activationCoefficient(std::size_t coefficientIndex) const noexcept
Retrieves the activation coefficient for the specified index.
Definition: BaseLayer.cpp:183
TensorFormat tensorFormat() const noexcept
Returns the tensor format consumed by this layer implementation.
Definition: BaseLayer.cpp:471
NeuralResult getInputLayers(ILayerList **ppInputLayers) const noexcept
Retrieves the inputs for this layer.
Definition: BaseLayer.cpp:220
LoadResult
This enum describes a result from the load2ElementParameter function.
Definition: BaseLayer.h:262
@ NonNumericInput
An input component contained a nondigit.
@ Success
Parsing succeeded.
@ CouldNotTranslate
An input component could not be parsed as a number.
NeuralResult setAffected(bool affected) noexcept
Sets or clears the "affected" flag on a layer's output tensor.
Definition: BaseLayer.cpp:209
NeuralResult setInputLayer(std::size_t index, ILayer *pLayer) noexcept
Sets an input layer by index.
Definition: BaseLayer.cpp:230
const ILayer * inputLayer(size_t index) const
Returns the Nth input layer attached to this layer.
Definition: BaseLayer.cpp:315
bool verifyInputConnected(Indices... indices) const noexcept
Test if inputs represented by indices are connected, and log errors if not.
Definition: BaseLayer.h:214
NeuralResult setPermanent(bool permanent) noexcept
Sets or clears the "permanent" flag on a layer's output tensor.
Definition: BaseLayer.cpp:198
TensorDimension loadedWeightsSize(const ILayer *pWeightsLayer, const char *pWeightsName) const
Returns the size of already-loaded weights data, whether using a layer or IWeightsLoader.
Definition: BaseLayer.cpp:364
size_t inputLayerCount() const
Returns the number of input layers assigned to this object.
Definition: BaseLayer.cpp:330
void registerImplementation(NetworkBackendId backendId, TensorDataType elementType, TensorDataLayout layout, int penalty)
Registers an implementation for multi-format layers.
Definition: BaseLayer.cpp:380
RefPtr< INetworkBackend > networkBackend() const
Returns the INetworkBackend object associated with the implementation that most closely matches the c...
Definition: BaseLayer.cpp:93
void requestReshape() noexcept
Marks this layer as in need of reshape.
Definition: BaseLayer.cpp:484
NeuralResult getData(void **ppOut, TensorFormat format, const ILayer *pRequestingLayer) noexcept
Retrieves device-side memory for the layer's output.
Definition: BaseLayer.cpp:261
TensorDimension weightsDimensions(const char *pWeightsName, WeightsQuery queryType) const noexcept
Retrieves the tensor dimension of a layer's named weight input.
Definition: BaseLayer.cpp:350
bool isAffected() const noexcept
Returns the current status of the "affected" flag.
Definition: BaseLayer.cpp:215
ILayer is the base class for neural network layers.
Definition: LayerTypes.h:59
ILayerList represents an immutable collection of ILayer pointers.
Definition: CoreTypes.h:1060
virtual NeuralResult logError(VerbosityLevel verbosity, const char *format,...) noexcept=0
Logs an error message.
INetworkBackend is a runtime-specific interface for CUDA, DirectX, or other system- specific operatio...
Definition: CoreTypes.h:643
INetworkRuntime is a subset of the basic network interface that is accessible from layer classes duri...
Definition: CoreTypes.h:1129
Represents a serialized parameter block in a model definition.
Definition: CoreTypes.h:1889
Intrusive pointer using IRefObject's reference counting system.
Definition: RefPtr.h:46
TensorDimension describes the dimensions of a four-dimensional image tensor.
Definition: CoreTypes.h:136
TensorFormat describes a specific tensor shape (element type and layout).
Definition: CoreTypes.h:88