#include #ifdef USE_CAFFE #include #endif #include namespace op { template struct ArrayCpuGpu::ImplArrayCpuGpu { #ifdef USE_CAFFE #ifdef NV_CAFFE std::unique_ptr> upCaffeBlobT; caffe::TBlob* pCaffeBlobT; #else std::unique_ptr> upCaffeBlobT; caffe::Blob* pCaffeBlobT; #endif #endif }; const std::string constructorErrorMessage = "ArrayCpuGpu class only implemented for Caffe DL framework (enable" " `USE_CAFFE` in CMake-GUI)."; template ArrayCpuGpu::ArrayCpuGpu() { try { #ifdef USE_CAFFE // Construct spImpl spImpl.reset(new ImplArrayCpuGpu{}); #ifdef NV_CAFFE spImpl->upCaffeBlobT.reset(new caffe::TBlob{}); #else spImpl->upCaffeBlobT.reset(new caffe::Blob{}); #endif spImpl->pCaffeBlobT = spImpl->upCaffeBlobT.get(); #else error(constructorErrorMessage, __LINE__, __FUNCTION__, __FILE__); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } template ArrayCpuGpu::ArrayCpuGpu(const void* caffeBlobTPtr) { try { #ifdef USE_CAFFE // Construct spImpl spImpl.reset(new ImplArrayCpuGpu{}); #ifdef NV_CAFFE spImpl->pCaffeBlobT = (caffe::TBlob*)caffeBlobTPtr; #else spImpl->pCaffeBlobT = (caffe::Blob*)caffeBlobTPtr; #endif #else UNUSED(caffeBlobTPtr); error(constructorErrorMessage, __LINE__, __FUNCTION__, __FILE__); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } template ArrayCpuGpu::ArrayCpuGpu(const Array& array, const bool copyFromGpu) { try { #ifdef USE_CAFFE // Get updated size std::vector arraySize; // If batch size = 1 --> E.g., array.getSize() == {78, 368, 368} if (array.getNumberDimensions() == 3) // Add 1: arraySize = {1} arraySize.emplace_back(1); // Add {78, 368, 368}: arraySize = {1, 78, 368, 368} for (const auto& sizeI : array.getSize()) arraySize.emplace_back(sizeI); // Construct spImpl spImpl.reset(new ImplArrayCpuGpu{}); #ifdef NV_CAFFE spImpl->upCaffeBlobT.reset(new caffe::TBlob{arraySize}); #else spImpl->upCaffeBlobT.reset(new caffe::Blob{arraySize}); #endif spImpl->pCaffeBlobT = spImpl->upCaffeBlobT.get(); // Copy data // CPU copy if (!copyFromGpu) { const auto* const arrayPtr = array.getConstPtr(); std::copy(arrayPtr, arrayPtr + array.getVolume(), spImpl->pCaffeBlobT->mutable_cpu_data()); } // GPU copy else error("Not implemented yet. Let us know you are interested on this function.", __LINE__, __FUNCTION__, __FILE__); #else UNUSED(array); UNUSED(copyFromGpu); error(constructorErrorMessage, __LINE__, __FUNCTION__, __FILE__); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } template ArrayCpuGpu::ArrayCpuGpu(const int num, const int channels, const int height, const int width) { try { #ifdef USE_CAFFE // Construct spImpl spImpl.reset(new ImplArrayCpuGpu{}); #ifdef NV_CAFFE spImpl->upCaffeBlobT.reset(new caffe::TBlob{num, channels, height, width}); #else spImpl->upCaffeBlobT.reset(new caffe::Blob{num, channels, height, width}); #endif spImpl->pCaffeBlobT = spImpl->upCaffeBlobT.get(); #else UNUSED(num); UNUSED(channels); UNUSED(height); UNUSED(width); error(constructorErrorMessage, __LINE__, __FUNCTION__, __FILE__); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } // template // ArrayCpuGpu::ArrayCpuGpu(const std::vector& shape) // { // try // { // #ifdef USE_CAFFE // spImpl.reset(new ImplArrayCpuGpu{}); // spImpl->upCaffeBlobT.reset(new caffe::Blob{shape}); // spImpl->pCaffeBlobT = spImpl->upCaffeBlobT.get(); // #else // error(constructorErrorMessage, __LINE__, __FUNCTION__, __FILE__); // #endif // } // catch (const std::exception& e) // { // error(e.what(), __LINE__, __FUNCTION__, __FILE__); // } // } template void ArrayCpuGpu::Reshape(const int num, const int channels, const int height, const int width) { try { #ifdef USE_CAFFE spImpl->pCaffeBlobT->Reshape(num, channels, height, width); #else UNUSED(num); UNUSED(channels); UNUSED(height); UNUSED(width); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } template void ArrayCpuGpu::Reshape(const std::vector& shape) { try { #ifdef USE_CAFFE spImpl->pCaffeBlobT->Reshape(shape); #else UNUSED(shape); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } template std::string ArrayCpuGpu::shape_string() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->shape_string(); #else return ""; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return ""; } } std::vector DUMB_VECTOR; template const std::vector& ArrayCpuGpu::shape() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->shape(); #else return DUMB_VECTOR; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return DUMB_VECTOR; } } template int ArrayCpuGpu::shape(const int index) const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->shape(index); #else UNUSED(index); return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::num_axes() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->num_axes(); #else return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::count() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->count(); #else return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::count(const int start_axis, const int end_axis) const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->count(start_axis, end_axis); #else UNUSED(start_axis); UNUSED(end_axis); return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::count(const int start_axis) const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->count(start_axis); #else UNUSED(start_axis); return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::CanonicalAxisIndex(const int axis_index) const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->CanonicalAxisIndex(axis_index); #else UNUSED(axis_index); return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::num() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->num(); #else return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::channels() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->channels(); #else return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::height() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->height(); #else return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::width() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->width(); #else return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::LegacyShape(const int index) const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->LegacyShape(index); #else UNUSED(index); return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } template int ArrayCpuGpu::offset(const int n, const int c, const int h, const int w) const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->offset(n, c, h, w); #else UNUSED(n); UNUSED(c); UNUSED(h); UNUSED(w); return -1; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return -1; } } // template // int ArrayCpuGpu::offset(const std::vector& indices) const // { // try // { // #ifdef USE_CAFFE // return spImpl->pCaffeBlobT->offset(indices); // #else // UNUSED(indices); // return -1; // #endif // } // catch (const std::exception& e) // { // error(e.what(), __LINE__, __FUNCTION__, __FILE__); // return -1; // } // } template T ArrayCpuGpu::data_at(const int n, const int c, const int h, const int w) const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->data_at(n, c, h, w); #else UNUSED(n); UNUSED(c); UNUSED(h); UNUSED(w); return T{0}; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return T{0}; } } template T ArrayCpuGpu::diff_at(const int n, const int c, const int h, const int w) const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->diff_at(n, c, h, w); #else UNUSED(n); UNUSED(c); UNUSED(h); UNUSED(w); return T{0}; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return T{0}; } } // template // T ArrayCpuGpu::data_at(const std::vector& index) const // { // try // { // #ifdef USE_CAFFE // return spImpl->pCaffeBlobT->data_at(index); // #else // UNUSED(index); // return T{0}; // #endif // } // catch (const std::exception& e) // { // error(e.what(), __LINE__, __FUNCTION__, __FILE__); // return T{0}; // } // } // template // T ArrayCpuGpu::diff_at(const std::vector& index) const // { // try // { // #ifdef USE_CAFFE // return spImpl->pCaffeBlobT->diff_at(index); // #else // UNUSED(index); // return T{0}; // #endif // } // catch (const std::exception& e) // { // error(e.what(), __LINE__, __FUNCTION__, __FILE__); // return T{0}; // } // } template const T* ArrayCpuGpu::cpu_data() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->cpu_data(); #else return nullptr; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return nullptr; } } template void ArrayCpuGpu::set_cpu_data(T* data) { try { #ifdef USE_CAFFE spImpl->pCaffeBlobT->set_cpu_data(data); #else UNUSED(data); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } template const int* ArrayCpuGpu::gpu_shape() const { try { #if defined(USE_CAFFE) && (defined(USE_CUDA) || defined(USE_OPENCL)) return spImpl->pCaffeBlobT->gpu_shape(); #else error("Required `USE_CAFFE` and `USE_CUDA` flags enabled.", __LINE__, __FUNCTION__, __FILE__); return nullptr; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return nullptr; } } template const T* ArrayCpuGpu::gpu_data() const { try { #if defined(USE_CAFFE) && (defined(USE_CUDA) || defined(USE_OPENCL)) return spImpl->pCaffeBlobT->gpu_data(); #else error("Required `USE_CAFFE` and `USE_CUDA` flags enabled.", __LINE__, __FUNCTION__, __FILE__); return nullptr; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return nullptr; } } template void ArrayCpuGpu::set_gpu_data(T* data) { try { #if defined(USE_CAFFE) && (defined(USE_CUDA) || defined(USE_OPENCL)) spImpl->pCaffeBlobT->set_gpu_data(data); #else UNUSED(data); error("Required `USE_CAFFE` and `USE_CUDA` flags enabled.", __LINE__, __FUNCTION__, __FILE__); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } template const T* ArrayCpuGpu::cpu_diff() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->cpu_diff(); #else return nullptr; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return nullptr; } } template const T* ArrayCpuGpu::gpu_diff() const { try { #if defined(USE_CAFFE) && (defined(USE_CUDA) || defined(USE_OPENCL)) return spImpl->pCaffeBlobT->gpu_diff(); #else error("Required `USE_CAFFE` and `USE_CUDA` flags enabled.", __LINE__, __FUNCTION__, __FILE__); return nullptr; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return nullptr; } } template T* ArrayCpuGpu::mutable_cpu_data() { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->mutable_cpu_data(); #else return nullptr; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return nullptr; } } template T* ArrayCpuGpu::mutable_gpu_data() { try { #if defined(USE_CAFFE) && (defined(USE_CUDA) || defined(USE_OPENCL)) return spImpl->pCaffeBlobT->mutable_gpu_data(); #else error("Required `USE_CAFFE` and `USE_CUDA` flags enabled.", __LINE__, __FUNCTION__, __FILE__); return nullptr; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return nullptr; } } template T* ArrayCpuGpu::mutable_cpu_diff() { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->mutable_cpu_diff(); #else return nullptr; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return nullptr; } } template T* ArrayCpuGpu::mutable_gpu_diff() { try { #if defined(USE_CAFFE) && (defined(USE_CUDA) || defined(USE_OPENCL)) return spImpl->pCaffeBlobT->mutable_gpu_diff(); #else error("Required `USE_CAFFE` and `USE_CUDA` flags enabled.", __LINE__, __FUNCTION__, __FILE__); return nullptr; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return nullptr; } } template void ArrayCpuGpu::Update() { try { #ifdef USE_CAFFE spImpl->pCaffeBlobT->Update(); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } template T ArrayCpuGpu::asum_data() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->asum_data(); #else return T{0}; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return T{0}; } } template T ArrayCpuGpu::asum_diff() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->asum_diff(); #else return T{0}; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return T{0}; } } template T ArrayCpuGpu::sumsq_data() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->sumsq_data(); #else return T{0}; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return T{0}; } } template T ArrayCpuGpu::sumsq_diff() const { try { #ifdef USE_CAFFE return spImpl->pCaffeBlobT->sumsq_diff(); #else return T{0}; #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); return T{0}; } } template void ArrayCpuGpu::scale_data(const T scale_factor) { try { #ifdef USE_CAFFE spImpl->pCaffeBlobT->scale_data(scale_factor); #else UNUSED(scale_factor); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } template void ArrayCpuGpu::scale_diff(const T scale_factor) { try { #ifdef USE_CAFFE spImpl->pCaffeBlobT->scale_diff(scale_factor); #else UNUSED(scale_factor); #endif } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } COMPILE_TEMPLATE_FLOATING_INT_TYPES_CLASS(ArrayCpuGpu); }