device.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // ======================================================================== //
  2. // Copyright 2009-2019 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #include "device.h"
  17. #include "autoencoder.h"
  18. namespace oidn {
  19. thread_local Device::ErrorState Device::globalError;
  20. Device::Device()
  21. {
  22. if (!mayiuse(sse41))
  23. throw Exception(Error::UnsupportedHardware, "SSE4.1 support is required at minimum");
  24. }
  25. Device::~Device()
  26. {
  27. // -- GODOT start --
  28. //observer.reset();
  29. // -- GODOT end --
  30. }
  31. void Device::setError(Device* device, Error code, const std::string& message)
  32. {
  33. // Update the stored error only if the previous error was queried
  34. if (device)
  35. {
  36. ErrorState& curError = device->error.get();
  37. if (curError.code == Error::None)
  38. {
  39. curError.code = code;
  40. curError.message = message;
  41. }
  42. // Print the error message in verbose mode
  43. if (device->isVerbose())
  44. std::cerr << "Error: " << message << std::endl;
  45. // Call the error callback function
  46. ErrorFunction errorFunc;
  47. void* errorUserPtr;
  48. {
  49. std::lock_guard<std::mutex> lock(device->mutex);
  50. errorFunc = device->errorFunc;
  51. errorUserPtr = device->errorUserPtr;
  52. }
  53. if (errorFunc)
  54. errorFunc(errorUserPtr, code, (code == Error::None) ? nullptr : message.c_str());
  55. }
  56. else
  57. {
  58. if (globalError.code == Error::None)
  59. {
  60. globalError.code = code;
  61. globalError.message = message;
  62. }
  63. }
  64. }
  65. Error Device::getError(Device* device, const char** outMessage)
  66. {
  67. // Return and clear the stored error code, but keep the error message so pointers to it will
  68. // remain valid until the next getError call
  69. if (device)
  70. {
  71. ErrorState& curError = device->error.get();
  72. const Error code = curError.code;
  73. if (outMessage)
  74. *outMessage = (code == Error::None) ? nullptr : curError.message.c_str();
  75. curError.code = Error::None;
  76. return code;
  77. }
  78. else
  79. {
  80. const Error code = globalError.code;
  81. if (outMessage)
  82. *outMessage = (code == Error::None) ? nullptr : globalError.message.c_str();
  83. globalError.code = Error::None;
  84. return code;
  85. }
  86. }
  87. void Device::setErrorFunction(ErrorFunction func, void* userPtr)
  88. {
  89. errorFunc = func;
  90. errorUserPtr = userPtr;
  91. }
  92. int Device::get1i(const std::string& name)
  93. {
  94. if (name == "numThreads")
  95. return numThreads;
  96. else if (name == "setAffinity")
  97. return setAffinity;
  98. else if (name == "verbose")
  99. return verbose;
  100. else if (name == "version")
  101. return OIDN_VERSION;
  102. else if (name == "versionMajor")
  103. return OIDN_VERSION_MAJOR;
  104. else if (name == "versionMinor")
  105. return OIDN_VERSION_MINOR;
  106. else if (name == "versionPatch")
  107. return OIDN_VERSION_PATCH;
  108. else
  109. throw Exception(Error::InvalidArgument, "invalid parameter");
  110. }
  111. void Device::set1i(const std::string& name, int value)
  112. {
  113. if (name == "numThreads")
  114. numThreads = value;
  115. else if (name == "setAffinity")
  116. setAffinity = value;
  117. else if (name == "verbose")
  118. {
  119. verbose = value;
  120. error.verbose = value;
  121. }
  122. dirty = true;
  123. }
  124. void Device::commit()
  125. {
  126. if (isCommitted())
  127. throw Exception(Error::InvalidOperation, "device can be committed only once");
  128. // -- GODOT start --
  129. #if 0
  130. // -- GODOT end --
  131. // Get the optimal thread affinities
  132. if (setAffinity)
  133. {
  134. affinity = std::make_shared<ThreadAffinity>(1, verbose); // one thread per core
  135. if (affinity->getNumThreads() == 0)
  136. affinity.reset();
  137. }
  138. // Create the task arena
  139. const int maxNumThreads = affinity ? affinity->getNumThreads() : tbb::this_task_arena::max_concurrency();
  140. numThreads = (numThreads > 0) ? min(numThreads, maxNumThreads) : maxNumThreads;
  141. arena = std::make_shared<tbb::task_arena>(numThreads);
  142. // Automatically set the thread affinities
  143. if (affinity)
  144. observer = std::make_shared<PinningObserver>(affinity, *arena);
  145. // -- GODOT start --
  146. #endif
  147. numThreads = 1;
  148. // -- GODOT end --
  149. dirty = false;
  150. if (isVerbose())
  151. print();
  152. }
  153. void Device::checkCommitted()
  154. {
  155. if (dirty)
  156. throw Exception(Error::InvalidOperation, "changes to the device are not committed");
  157. }
  158. Ref<Buffer> Device::newBuffer(size_t byteSize)
  159. {
  160. checkCommitted();
  161. return makeRef<Buffer>(Ref<Device>(this), byteSize);
  162. }
  163. Ref<Buffer> Device::newBuffer(void* ptr, size_t byteSize)
  164. {
  165. checkCommitted();
  166. return makeRef<Buffer>(Ref<Device>(this), ptr, byteSize);
  167. }
  168. Ref<Filter> Device::newFilter(const std::string& type)
  169. {
  170. checkCommitted();
  171. if (isVerbose())
  172. std::cout << "Filter: " << type << std::endl;
  173. Ref<Filter> filter;
  174. // -- GODOT start --
  175. // Godot doesn't need Raytracing filters. Removing them saves space in the weights files.
  176. #if 0
  177. // -- GODOT end --
  178. if (type == "RT")
  179. filter = makeRef<RTFilter>(Ref<Device>(this));
  180. // -- GODOT start --
  181. // Godot doesn't need Raytracing filters. Removing them saves space in the weights files.
  182. #endif
  183. if (type == "RTLightmap")
  184. // -- GODOT end --
  185. filter = makeRef<RTLightmapFilter>(Ref<Device>(this));
  186. else
  187. throw Exception(Error::InvalidArgument, "unknown filter type");
  188. return filter;
  189. }
  190. void Device::print()
  191. {
  192. std::cout << std::endl;
  193. std::cout << "Intel(R) Open Image Denoise " << OIDN_VERSION_STRING << std::endl;
  194. std::cout << " Compiler: " << getCompilerName() << std::endl;
  195. std::cout << " Build : " << getBuildName() << std::endl;
  196. std::cout << " Platform: " << getPlatformName() << std::endl;
  197. // -- GODOT start --
  198. // std::cout << " Tasking :";
  199. // std::cout << " TBB" << TBB_VERSION_MAJOR << "." << TBB_VERSION_MINOR;
  200. // std::cout << " TBB_header_interface_" << TBB_INTERFACE_VERSION << " TBB_lib_interface_" << tbb::TBB_runtime_interface_version();
  201. // std::cout << std::endl;
  202. // -- GODOT end --
  203. std::cout << std::endl;
  204. }
  205. } // namespace oidn