PSkel
src/PSkelMask.hpp
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
 All Classes Files Functions