@@ -93,28 +93,72 @@ test_image_span()
9393
9494
9595
96+ template <typename T>
97+ T
98+ testvalue (int x, int y, int z, int c)
99+ {
100+ return T (x + y + z + c);
101+ }
102+
103+
104+ // Fill an image span in a characteristic way
105+ template <typename T>
106+ void
107+ fill_image_span (image_span<T> img)
108+ {
109+ // Fill the image with a constant value
110+ for (uint32_t z = 0 ; z < img.depth (); ++z) {
111+ for (uint32_t y = 0 ; y < img.height (); ++y) {
112+ for (uint32_t x = 0 ; x < img.width (); ++x) {
113+ for (uint32_t c = 0 ; c < img.nchannels (); ++c) {
114+ img (x, y, z)[c] = testvalue<T>(x, y, z, c);
115+ }
116+ }
117+ }
118+ }
119+ }
120+
121+
122+ // Check that an image span in the characteristic way
123+ template <typename T>
124+ bool
125+ check_image_span (image_span<T> img, int xoff = 0 , int yoff = 0 , int zoff = 0 )
126+ {
127+ // Fill the image with a constant value
128+ for (uint32_t z = 0 ; z < img.depth (); ++z) {
129+ for (uint32_t y = 0 ; y < img.height (); ++y) {
130+ for (uint32_t x = 0 ; x < img.width (); ++x) {
131+ for (uint32_t c = 0 ; c < img.nchannels (); ++c) {
132+ auto v = testvalue<T>(x + xoff, y + yoff, z + zoff, c);
133+ OIIO_CHECK_EQUAL (img (x, y, z)[c], v);
134+ if (img (x, y, z)[c] != v) {
135+ print (" \t Error at ({}, {}, {})[{}]\n " , x, y, z, c);
136+ return false ;
137+ }
138+ }
139+ }
140+ }
141+ }
142+ return true ;
143+ }
144+
145+
146+
96147template <typename T = float >
97148void
98- benchmark_image_span_copy_image ()
149+ test_image_span_copy_image ()
99150{
100- // Benchmark old (ptr) versus new (span) copy_image functions
101- Benchmarker bench;
102- bench.units (Benchmarker::Unit::us);
103151 const int xres = 2048 , yres = 1536 , nchans = 4 ;
104- std::vector<T> sbuf (xres * yres * nchans);
105- std::vector<T> dbuf (xres * yres * nchans);
106152 const size_t chansize = sizeof (T);
107-
108- print (" Benchmarking copy_image {} (total {} MB):\n " ,
109- TypeDescFromC<T>::value (),
153+ print (" \n Testing copy_image {} (total {} MB):\n " , TypeDescFromC<T>::value (),
110154 xres * yres * nchans * chansize * 3 / 4 / 1024 / 1024 );
111155
112156 // We test different amounts of contiguity. Each test copies 3/4 of the
113157 // total image, to keep the total number of bytes copied identical.
114158 const stride_t src_xstride (chansize * nchans);
115159 const stride_t src_ystride (src_xstride * xres);
116160 for (int i = 0 ; i < 3 ; ++i) {
117- size_t nc (nchans), pixsize (chansize * nchans), w (xres), h (yres);
161+ size_t nc (nchans), w (xres), h (yres);
118162 std::string label;
119163 if (i == 0 ) {
120164 // Fully contiguous region -- copy 3/4 of the image.
@@ -129,14 +173,31 @@ benchmark_image_span_copy_image()
129173 label = " contig pixels" ;
130174 nc = nc * 3 / 4 ;
131175 }
132- bench (Strutil::format (" copy_image image_span {}" , label), [&]() {
133- copy_image (image_span<T>(dbuf.data (), nc, w, h, 1 , chansize,
134- src_xstride, src_ystride, AutoStride,
135- chansize),
136- image_span<const T>(sbuf.data (), nc, w, h, 1 ));
137- });
138- bench (Strutil::format (" copy_image raw ptrs {}" , label), [&]() {
139- copy_image (nc, w, h, 1 , sbuf.data (), pixsize, src_xstride,
176+
177+ print (" test image_span copy_image {}\n " , label);
178+ std::vector<T> sbuf (xres * yres * nchans);
179+ std::vector<T> dbuf (w * h * nc);
180+
181+ // Spans for src and dst -- src has the "original" strides, dst
182+ // has contiguous strides.
183+ image_span<T> sispan (sbuf.data (), nc, w, h, 1 , chansize, src_xstride,
184+ src_ystride, AutoStride);
185+ image_span<T> dispan (dbuf.data (), nc, w, h, 1 );
186+
187+ // Test correctness
188+ fill_image_span (sispan);
189+ copy_image (dispan, sispan);
190+ OIIO_CHECK_ASSERT (check_image_span (dispan));
191+
192+ // Benchmark old (ptr) versus new (span) copy_image functions
193+ Benchmarker bench;
194+ bench.units (Benchmarker::Unit::us);
195+
196+ bench (Strutil::format (" copy_image image_span {}" , label),
197+ [&]() { copy_image (dispan, sispan); });
198+ // Test equivalent version with pointers
199+ bench (Strutil::format (" copy_image raw ptrs {}" , label), [&]() {
200+ copy_image (nc, w, h, 1 , sbuf.data (), nc * chansize, src_xstride,
140201 src_ystride, AutoStride, dbuf.data (), AutoStride,
141202 AutoStride, AutoStride);
142203 });
@@ -147,23 +208,19 @@ benchmark_image_span_copy_image()
147208
148209template <typename T = float >
149210void
150- benchmark_image_span_contiguize ()
211+ test_image_span_contiguize ()
151212{
152213 // Benchmark old (ptr) versus new (span) contiguize functions
153214 using pvt::contiguize;
154215
155- // Benchmark old (ptr) versus new (span) contiguize functions
156- Benchmarker bench;
157- bench.units (Benchmarker::Unit::us);
158216 const int xres = 2048 , yres = 1536 , nchans = 4 ;
159- std::vector<T> sbuf (xres * yres * nchans);
160- std::vector<T> dbuf (xres * yres * nchans);
161217 const size_t chansize = sizeof (T);
162-
163- print (" Benchmarking contiguize {} (total {} MB):\n " ,
164- TypeDescFromC<T>::value (),
218+ print (" \n Testing contiguize {} (total {} MB):\n " , TypeDescFromC<T>::value (),
165219 xres * yres * nchans * chansize * 3 / 4 / 1024 / 1024 );
166220
221+ // std::vector<T> sbuf(xres * yres * nchans);
222+ // std::vector<T> dbuf(xres * yres * nchans);
223+
167224 // We test different amounts of contiguity. Each test copies 3/4 of the
168225 // total image, to keep the total number of bytes copied identical.
169226 const stride_t src_xstride (chansize * nchans);
@@ -184,15 +241,35 @@ benchmark_image_span_contiguize()
184241 label = " contig pixels" ;
185242 nc = nc * 3 / 4 ;
186243 }
187- bench (Strutil::format (" contiguize image_span {}" , label), [&]() {
188- auto r = contiguize (image_span (reinterpret_cast <const std::byte*>(
189- sbuf.data ()),
190- nc, w, h, 1 , chansize, src_xstride,
191- src_ystride, AutoStride, chansize),
244+
245+ print (" test image_span contiguize {}\n " , label);
246+ std::vector<T> sbuf (xres * yres * nchans, T (100 ));
247+ std::vector<T> dbuf (w * h * nc, T (100 ));
248+
249+ // Spans for src and dst -- src has the "original" strides, dst
250+ // has contiguous strides.
251+ image_span<T> sispan (sbuf.data (), nc, w, h, 1 , chansize, src_xstride,
252+ src_ystride, AutoStride);
253+ image_span<T> dispan (dbuf.data (), nc, w, h, 1 );
254+
255+ // Test correctness
256+ fill_image_span (sispan);
257+ auto rspan = contiguize (sispan.as_bytes_image_span (),
258+ as_writable_bytes (make_span (dbuf)));
259+ OIIO_CHECK_ASSERT (check_image_span (
260+ image_span<const T>(reinterpret_cast <const T*>(rspan.data ()), nc, w,
261+ h, 1 )));
262+
263+ // Benchmark old (ptr) versus new (span) contiguize functions
264+ Benchmarker bench;
265+ bench.units (Benchmarker::Unit::us);
266+
267+ bench (Strutil::format (" contiguize image_span {}" , label), [&]() {
268+ auto r = contiguize (sispan.as_writable_bytes_image_span (),
192269 as_writable_bytes (make_span (dbuf)));
193270 OIIO_ASSERT (r.size_bytes () == nc * w * h * sizeof (T));
194271 });
195- bench (Strutil::format (" contiguize raw ptrs {}" , label), [&]() {
272+ bench (Strutil::format (" contiguize raw ptrs {}" , label), [&]() {
196273 contiguize (sbuf.data (), nc, src_xstride, src_ystride,
197274 src_ystride * h, dbuf.data (), w, h, 1 ,
198275 TypeDescFromC<T>::value ());
@@ -212,13 +289,13 @@ main(int /*argc*/, char* /*argv*/[])
212289 test_image_span<uint8_t >();
213290 test_image_span<const uint8_t >();
214291
215- benchmark_image_span_copy_image <float >();
216- benchmark_image_span_copy_image <uint16_t >();
217- benchmark_image_span_copy_image <uint8_t >();
292+ test_image_span_copy_image <float >();
293+ test_image_span_copy_image <uint16_t >();
294+ test_image_span_copy_image <uint8_t >();
218295
219- benchmark_image_span_contiguize <float >();
220- benchmark_image_span_contiguize <uint16_t >();
221- benchmark_image_span_contiguize <uint8_t >();
296+ test_image_span_contiguize <float >();
297+ test_image_span_contiguize <uint16_t >();
298+ test_image_span_contiguize <uint8_t >();
222299
223300 return unit_test_failures;
224301}
0 commit comments