1 ////////////////////////////////////////////////////////////////////////////
2 // File: CuTexImage.cpp
3 // Author: Changchang Wu
4 // Description : implementation of the CuTexImage class.
5 //
6 // Copyright (c) 2011 Changchang Wu (ccwu@cs.washington.edu)
7 // and the University of Washington at Seattle
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public
11 // License as published by the Free Software Foundation; either
12 // Version 3 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // General Public License for more details.
18 //
19 ////////////////////////////////////////////////////////////////////////////////
20
21 #include <iostream>
22 #include <algorithm>
23 #include <stdlib.h>
24 #include <vector>
25 #include <fstream>
26 using namespace std;
27
28 #include <cuda.h>
29 #include <cuda_runtime_api.h>
30 #include "CuTexImage.h"
31
32 #if CUDA_VERSION <= 2010
33 #error "Require CUDA 2.2 or higher"
34 #endif
35
36 namespace pba {
37
CuTexImage()38 CuTexImage::CuTexImage() {
39 _owner = true;
40 _cuData = NULL;
41 _numBytes = _numChannel = 0;
42 _imgWidth = _imgHeight = 0;
43 }
44
~CuTexImage()45 CuTexImage::~CuTexImage() {
46 if (_cuData && _owner) cudaFree(_cuData);
47 }
48
ReleaseData()49 void CuTexImage::ReleaseData() {
50 if (_cuData && _owner) cudaFree(_cuData);
51 _cuData = NULL;
52 _numBytes = 0;
53 }
54
SwapData(CuTexImage & src)55 void CuTexImage::SwapData(CuTexImage& src) {
56 if (_cuData == src._cuData) return;
57
58 void* cuData = _cuData;
59 unsigned int numChannel = _numChannel;
60 unsigned int imgWidth = _imgWidth;
61 unsigned int imgHeight = _imgHeight;
62 bool owner = _owner;
63 size_t numBytes = _numBytes;
64
65 _cuData = src._cuData;
66 _numChannel = src._numChannel;
67 _numBytes = src._numBytes;
68 _imgWidth = src._imgWidth;
69 _imgHeight = src._imgHeight;
70 _owner = src._owner;
71
72 src._cuData = cuData;
73 src._numChannel = numChannel;
74 src._numBytes = numBytes;
75 src._imgWidth = imgWidth;
76 src._imgHeight = imgHeight;
77 src._owner = owner;
78 }
79
InitTexture(unsigned int width,unsigned int height,unsigned int nchannel)80 bool CuTexImage::InitTexture(unsigned int width, unsigned int height,
81 unsigned int nchannel) {
82 size_t size = sizeof(float) * width * height * nchannel;
83 _imgWidth = width;
84 _imgHeight = height;
85 _numChannel = nchannel;
86
87 if (size <= _numBytes) return true;
88
89 if (_cuData && _owner) cudaFree(_cuData);
90
91 // allocate the array data
92 cudaError_t e = cudaMalloc(&_cuData, size);
93 _numBytes = e == cudaSuccess ? size : 0;
94 _owner = true;
95 return e == cudaSuccess;
96 }
97
SetTexture(void * data,unsigned int width,unsigned int nchannel)98 void CuTexImage::SetTexture(void* data, unsigned int width,
99 unsigned int nchannel) {
100 if (_cuData && _owner) cudaFree(_cuData);
101 _imgWidth = width;
102 _imgHeight = 1;
103 _numChannel = nchannel;
104 _numBytes = sizeof(float) * width * _imgHeight * _numChannel;
105 _cuData = data;
106 _owner = false;
107 }
108
CopyFromHost(const void * buf)109 void CuTexImage::CopyFromHost(const void* buf) {
110 if (_cuData == NULL || buf == NULL || GetDataSize() == 0) return;
111 cudaMemcpy(_cuData, buf, _imgWidth * _imgHeight * _numChannel * sizeof(float),
112 cudaMemcpyHostToDevice);
113 }
114
CopyFromDevice(const void * buf)115 void CuTexImage::CopyFromDevice(const void* buf) {
116 if (_cuData == NULL) return;
117 cudaMemcpy((char*)_cuData, buf,
118 _imgWidth * _imgHeight * _numChannel * sizeof(float),
119 cudaMemcpyDeviceToDevice);
120 }
121
CopyToHost(void * buf)122 void CuTexImage::CopyToHost(void* buf) {
123 if (_cuData == NULL) return;
124 size_t sz = _imgWidth * _imgHeight * _numChannel * sizeof(float);
125 // cudaThreadSynchronize();
126 cudaMemcpy(buf, _cuData, sz, cudaMemcpyDeviceToHost);
127 cudaThreadSynchronize();
128 }
129
SaveToFile(const char * name)130 void CuTexImage::SaveToFile(const char* name) {
131 ofstream out(name);
132 vector<float> value(GetLength());
133 CopyToHost(&value[0]);
134 for (size_t i = 0; i < value.size(); ++i) out << value[i] << '\n';
135 }
136
137 } // namespace pba
138