PSkel
|
00001 //------------------------------------------------------------------------------- 00002 // Copyright (c) 2015, ICEI - PUC Minas 00003 // All rights reserved. 00004 // 00005 // Redistribution and use in source and binary forms, with or without 00006 // modification, are permitted provided that the following conditions are met: 00007 // 00008 // 1. Redistributions of source code must retain the above copyright notice, this 00009 // list of conditions and the following disclaimer. 00010 // 00011 // 2. Redistributions in binary form must reproduce the above copyright notice, 00012 // this list of conditions and the following disclaimer in the documentation 00013 // and/or other materials provided with the distribution. 00014 // 00015 // 3. Neither the name of the copyright holder nor the names of its contributors 00016 // may be used to endorse or promote products derived from this software without 00017 // specific prior written permission. 00018 // 00019 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00023 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00024 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00025 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00026 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00027 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 //------------------------------------------------------------------------------- 00030 00031 #ifndef PSKEL_MASK_HPP 00032 #define PSKEL_MASK_HPP 00033 00034 #include <cstring> 00035 00036 #include "PSkelDefs.h" 00037 00038 namespace PSkel{ 00039 //******************************************************************************************* 00040 // MASKBASE 00041 //******************************************************************************************* 00042 template<typename T> 00043 MaskBase<T>::MaskBase(size_t size, size_t dimension, T haloVal, size_t range){ 00044 this->size = size; 00045 this->dimension = dimension; 00046 this->range = range; 00047 this->haloValue = haloVal; 00048 this->hostMask = NULL; 00049 this->hostWeight = NULL; 00050 this->deviceMask = NULL; 00051 this->deviceWeight = NULL; 00052 if(size>0) this->hostAlloc(); 00053 } 00054 00055 template<typename T> 00056 size_t MaskBase<T>::memSize() const{ 00057 return (dimension*size*sizeof(int)+size*sizeof(T)); 00058 } 00059 00060 template<typename T> 00061 void MaskBase<T>::deviceAlloc(){ 00062 gpuErrchk( cudaMalloc((void **) &deviceMask, dimension * size * sizeof (int)) ); 00063 gpuErrchk( cudaMalloc((void **) &deviceWeight, size * sizeof (T)) ); 00064 } 00065 00066 template<typename T> 00067 void MaskBase<T>::hostAlloc(){ 00068 if(this->hostMask==NULL && this->hostWeight==NULL){ 00069 hostMask = (int*) malloc (dimension * size * sizeof (int)); 00070 hostWeight = (T*) malloc (size * sizeof (T)); 00071 //memset(hostWeight,1,size); 00072 } 00073 } 00074 00075 template<typename T> 00076 void MaskBase<T>::hostFree(){ 00077 free(hostMask); 00078 free(hostWeight); 00079 hostMask = NULL; 00080 hostWeight = NULL; 00081 } 00082 00083 template<typename T> 00084 void MaskBase<T>::copyToDevice(){ 00085 gpuErrchk ( cudaMemcpy(deviceMask, hostMask, dimension * size * sizeof(int),cudaMemcpyHostToDevice) ); 00086 gpuErrchk ( cudaMemcpy(deviceWeight, hostWeight, size * sizeof(T),cudaMemcpyHostToDevice) ); 00087 } 00088 00089 template<typename T> 00090 void MaskBase<T>::deviceFree(){ 00091 //if(deviceMask!=NULL && deviceWeight!=NULL){ 00092 cudaFree(deviceMask); 00093 cudaFree(deviceWeight); 00094 this->deviceMask = NULL; 00095 this->deviceWeight = NULL; 00096 //} 00097 } 00098 /* 00099 template<typename T> 00100 __host__ __device__ size_t MaskBase<T>::size() const{ 00101 return this->size; 00102 } 00103 */ 00104 template<typename T> 00105 T MaskBase<T>::getWeight(size_t n){ 00106 #ifdef __CUDA_ARCH__ 00107 return deviceWeight[n]; 00108 #else 00109 return hostWeight[n]; 00110 #endif 00111 } 00112 00113 //******************************************************************************************* 00114 // MASK3D 00115 //******************************************************************************************* 00116 00117 template<typename T> 00118 Mask3D<T>::Mask3D(size_t size, T haloVal, size_t range) : MaskBase<T>(size,3, haloVal, range){} 00119 00120 template<typename T> 00121 void Mask3D<T>::set(size_t n, int h, int w, int d, T weight){ 00122 #ifdef __CUDA_ARCH__ 00123 this->deviceMask[this->dimension*n] = h; 00124 this->deviceMask[this->dimension*n+1] = w; 00125 this->deviceMask[this->dimension*n+2] = d; 00126 this->deviceWeight[n] = weight; 00127 #else 00128 this->hostMask[this->dimension*n] = h; 00129 this->hostMask[this->dimension*n+1] = w; 00130 this->hostMask[this->dimension*n+2] = d; 00131 this->hostWeight[n] = weight; 00132 #endif 00133 } 00134 /* 00135 template<typename T> 00136 void Mask3D<T>::set(size_t n,int h,int w,int d){ 00137 #ifdef __CUDA_ARCH__ 00138 this->deviceMask[this->dimension*n] = h; 00139 this->deviceMask[this->dimension*n+1] = w; 00140 this->deviceMask[this->dimension*n+2] = d; 00141 this->deviceWeight[n] = 1; 00142 #else 00143 this->hostMask[this->dimension*n] = h; 00144 this->hostMask[this->dimension*n+1] = w; 00145 this->hostMask[this->dimension*n+2] = d; 00146 this->hostWeight[n] = 1; 00147 #endif 00148 } 00149 */ 00150 00151 template<typename T> template<typename V> 00152 T Mask3D<T>::get(size_t n, Array3D<V> array, size_t h, size_t w, size_t d){ 00153 #ifdef __CUDA_ARCH__ 00154 h += this->deviceMask[this->dimension*n]; 00155 w += this->deviceMask[this->dimension*n+1]; 00156 d += this->deviceMask[this->dimension*n+2]; 00157 return (w<array.getWidth() && h<array.getHeight() && d<array.getDepth())?array(h,w,d):this->haloValue; 00158 #else 00159 h += this->hostMask[this->dimension*n]; 00160 w += this->hostMask[this->dimension*n+1]; 00161 d += this->hostMask[this->dimension*n+2]; 00162 return (w<array.getWidth() && h<array.getHeight() && d<array.getDepth())?array(h,w,d):this->haloValue; 00163 #endif 00164 } 00165 00166 template<typename T> 00167 size_t Mask3D<T>::getRange(){ 00168 if(this->range>0) return this->range; 00169 int *ptr; 00170 #ifdef __CUDA_ARCH__ 00171 ptr = this->deviceMask; 00172 #else 00173 ptr = this->hostMask; 00174 #endif 00175 00176 size_t max_h = abs(ptr[0]); 00177 size_t max_w = abs(ptr[1]); 00178 size_t max_d = abs(ptr[2]); 00179 //size_t range = std::max(std::max(max_h, max_w), max_d); 00180 this->range = ((max_h>max_w)?max_h:max_w); 00181 this->range = ((this->range>max_d)?this->range:max_d); 00182 for(size_t i=1; i < this->size; i++){ 00183 max_h = abs(ptr[this->dimension*i]); 00184 max_w = abs(ptr[this->dimension*i+1]); 00185 max_d = abs(ptr[this->dimension*i+2]); 00186 //size_t value = std::max(std::max(max_h, max_w), max_d); 00187 size_t value = ((max_h>max_w)?max_h:max_w); 00188 value = ((value>max_d)?value:max_d); 00189 if(value > this->range){ 00190 this->range = value; 00191 } 00192 } 00193 return this->range; 00194 } 00195 /* 00196 template<typename T> template<typename Arrays> 00197 int Mask3D<T>::setMaskRadius(Arrays array){ 00198 int max_h = abs(this->hostMask[0]); 00199 int max_w = abs(this->hostMask[1]); 00200 int max_d = abs(this->hostMask[2]); 00201 //this->maskRadius = (max_h*array.getWidth() + max_w)*array.getDepth() + max_d; 00202 this->maskRadius = std::max(std::max(max_h, max_w), max_d); 00203 for(int i=1; i < this->size; i++){ 00204 max_h = abs(this->hostMask[this->dimension*i]); 00205 max_w = abs(this->hostMask[this->dimension*i+1]); 00206 max_d = abs(this->hostMask[this->dimension*i+2]); 00207 int value = std::max(std::max(max_h, max_w), max_d); 00208 //int value = (max_h*array.getWidth() + max_w)*array.getDepth() + max_d; 00209 if(value > this->maskRadius){ 00210 this->maskRadius = value; 00211 } 00212 } 00213 return this->maskRadius; 00214 } 00215 */ 00216 //******************************************************************************************* 00217 // MASK2D 00218 //******************************************************************************************* 00219 00220 template<typename T> 00221 Mask2D<T>::Mask2D(size_t size, T haloVal, size_t range) : MaskBase<T>(size,2,haloVal, range) {} 00222 00223 00224 template<typename T> 00225 void Mask2D<T>::set(size_t n, int h, int w, T weight){ 00226 #ifdef __CUDA_ARCH__ 00227 this->deviceMask[this->dimension*n] = h; 00228 this->deviceMask[this->dimension*n+1] = w; 00229 this->deviceWeight[n] = weight; 00230 #else 00231 this->hostMask[this->dimension*n] = h; 00232 this->hostMask[this->dimension*n+1] = w; 00233 this->hostWeight[n] = weight; 00234 #endif 00235 } 00236 /* 00237 template<typename T> 00238 void Mask2D<T>::set(size_t n, int h,int w){ 00239 #ifdef __CUDA_ARCH__ 00240 this->deviceMask[this->dimension*n] = h; 00241 this->deviceMask[this->dimension*n+1] = w; 00242 this->deviceWeight[n] = 1; 00243 #else 00244 this->hostMask[this->dimension*n] = h; 00245 this->hostMask[this->dimension*n+1] = w; 00246 this->hostWeight[n] = 1; 00247 #endif 00248 } 00249 */ 00250 template<typename T> template<typename V> 00251 T Mask2D<T>::get(size_t n, Array2D<V> array, size_t h, size_t w){ 00252 #ifdef __CUDA_ARCH__ 00253 h += this->deviceMask[this->dimension*n]; 00254 w += this->deviceMask[this->dimension*n+1]; 00255 return (w<array.getWidth() && h<array.getHeight())?array(h,w):this->haloValue; 00256 #else 00257 h += this->hostMask[this->dimension*n]; 00258 w += this->hostMask[this->dimension*n+1]; 00259 return (w<array.getWidth() && h<array.getHeight())?array(h,w):this->haloValue; 00260 #endif 00261 } 00262 00263 template<typename T> 00264 size_t Mask2D<T>::getRange(){ 00265 if(this->range>0) return this->range; 00266 int *ptr; 00267 #ifdef __CUDA_ARCH__ 00268 ptr = this->deviceMask; 00269 #else 00270 ptr = this->hostMask; 00271 #endif 00272 //size_t range; 00273 //if(this->maskRadius == 0){ 00274 size_t max_h = abs(ptr[0]); 00275 size_t max_w = abs(ptr[1]); 00276 //range = std::max(max_h, max_w); 00277 this->range = ((max_h>max_w)?max_h:max_w); 00278 00279 for(size_t i=1; i < this->size; i++){ 00280 max_h = abs(ptr[this->dimension*i]); 00281 max_w = abs(ptr[this->dimension*i+1]); 00282 //size_t value = std::max(max_h, max_w); 00283 size_t value = ((max_h>max_w)?max_h:max_w); 00284 if(value > this->range){ 00285 this->range = value; 00286 } 00287 } 00288 //} 00289 return this->range; 00290 } 00291 /* 00292 template<typename T> template<typename Arrays> 00293 int Mask2D<T>::setMaskRadius(Arrays array){ 00294 if(this->maskRadius == 0){ 00295 int max_h = abs(this->hostMask[0]); 00296 int max_w = abs(this->hostMask[1]); 00297 this->maskRadius = std::max(max_h, max_w); 00298 //this->maskRadius = max_h*array.getWidth() + max_w; 00299 00300 for(int i=1; i < this->size; i++){ 00301 max_h = abs(this->hostMask[this->dimension*i]); 00302 max_w = abs(this->hostMask[this->dimension*i+1]); 00303 int value = std::max(max_h, max_w); 00304 //int value = max_h*array.getWidth() + max_w; 00305 if(value > this->maskRadius){ 00306 this->maskRadius = value; 00307 } 00308 } 00309 } 00310 return this->maskRadius; 00311 } 00312 */ 00313 //******************************************************************************************* 00314 // MASK 00315 //******************************************************************************************* 00316 00317 template<typename T> 00318 Mask<T>::Mask(size_t size, T haloVal, size_t range) : MaskBase<T>(size,1,haloVal,range) {} 00319 /* 00320 template<typename T> 00321 void Mask<T>::set(size_t n,int x, )){ 00322 #ifdef __CUDA_ARCH__ 00323 this->deviceMask[n] = x; 00324 this->deviceWeight[n] = 1; 00325 #else 00326 this->hostMask[n] = x; 00327 this->hostWeight[n] = 1; 00328 #endif 00329 } 00330 */ 00331 template<typename T> 00332 void Mask<T>::set(size_t n, int i, T weight){ 00333 #ifdef __CUDA_ARCH__ 00334 this->deviceMask[n] = i; 00335 this->deviceWeight[n] = weight; 00336 #else 00337 this->hostMask[n] = i; 00338 this->hostWeight[n] = weight; 00339 #endif 00340 } 00341 00342 template<typename T> template<typename V> 00343 T Mask<T>::get(size_t n, Array<V> array, size_t i){ 00344 #ifdef __CUDA_ARCH__ 00345 i += this->deviceMask[n]; 00346 return (i<array.getWidth())?array(i):this->haloValue; 00347 #else 00348 i += this->hostMask[n]; 00349 return (i<array.getWidth())?array(i):this->haloValue; 00350 #endif 00351 } 00352 00353 template<typename T> 00354 size_t Mask<T>::getRange(){ 00355 if(this->range>0) return this->range; 00356 int *ptr; 00357 #ifdef __CUDA_ARCH__ 00358 ptr = this->deviceMask; 00359 #else 00360 ptr = this->hostMask; 00361 #endif 00362 this->range = abs(ptr[0]); 00363 for(size_t i=1; i < this->size; i++){ 00364 size_t value = abs(ptr[i]); 00365 if(value > this->range){ 00366 this->range = value; 00367 } 00368 } 00369 return this->range; 00370 } 00371 /* 00372 template<typename T> template<typename Arrays> 00373 int Mask<T>::setMaskRadius(Arrays array){ 00374 this->maskRadius = abs(this->hostMask[0]); 00375 for(int i=1; i < this->size; i++){ 00376 int value = abs(this->hostMask[i]); 00377 if(value > this->maskRadius){ 00378 this->maskRadius = value; 00379 } 00380 } 00381 return this->maskRadius; 00382 } 00383 */ 00384 }//end namespace 00385 00386 #endif