48#define CLAMPI(a, mn, mx) ((a) < (mn) ? (mn) : ((a) > (mx) ? (mx) : (a)))
54#define CL_ALIGNMENT ((piece->dsc_in.filters != 9u) ? 4 : 1)
62static unsigned _gcd(
unsigned a,
unsigned b)
75static unsigned _lcm(
unsigned a,
unsigned b)
77 return (((
unsigned long)a * b) /
_gcd(a, b));
81static inline int _min(
int a,
int b)
86static inline int _max(
int a,
int b)
94 return n + a - (
n % a);
102 const int off =
n % a;
103 const int shift = (off > a/2) ? a - off : -off;
118 fprintf(stderr,
" {%5d %5d ->%5d %5d (%5dx%5d) %.6f } %s\n",
125_nm_constraints(
double x[],
int n)
132 if(
x[0] > 1.0)
x[0] = 1.0 -
x[0];
133 if(
x[1] > 1.0)
x[1] = 1.0 -
x[1];
134 if(
x[2] > 1.0)
x[2] = 1.0 -
x[2];
135 if(
x[3] > 1.0)
x[3] = 1.0 -
x[3];
142 void **rest = (
void **)params;
157 self->modify_roi_in(self, pipe, &piece_copy, &oroi_test, &iroi_probe);
159 double fitness = 0.0;
161 fitness += (
double)(iroi_probe.
x - iroi->
x) * (iroi_probe.
x - iroi->
x);
162 fitness += (
double)(iroi_probe.
y - iroi->
y) * (iroi_probe.
y - iroi->
y);
174 void *rest[5] = { (
void *)self, (
void *)piece, (
void *)iroi, (
void *)oroi, (
void *)pipe };
175 double start[4] = { (float)oroi->
x / piece->
iwidth, (
float)oroi->
y / piece->
iheight,
184 oroi->
x = start[0] * piece->
iwidth;
185 oroi->
y = start[1] * piece->
iheight;
189 return (iter <= maxiter);
207 self->modify_roi_in(self, pipe, &piece_copy, oroi, &iroi_probe);
208 while((abs((
int)iroi_probe.
x - (
int)iroi->
x) >
delta || abs((
int)iroi_probe.
y - (
int)iroi->
y) >
delta
215 oroi->
x += (iroi->
x - iroi_probe.
x) * oroi->
scale / iroi->
scale;
216 oroi->
y += (iroi->
y - iroi_probe.
y) * oroi->
scale / iroi->
scale;
223 self->modify_roi_in(self, pipe, &piece_copy, oroi, &iroi_probe);
227 if(iter > 0)
return TRUE;
243 const void *
const ivoid,
void *
const ovoid,
250 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_ptp] **** tiling module '%s' for image with size %dx%d --> %dx%d\n",
254 const int ipitch = roi_in->
width * in_bpp;
255 const int opitch = roi_out->
width * out_bpp;
256 const int max_bpp =
_max(in_bpp, out_bpp);
260 self->tiling_callback(self, pipe, piece, &
tiling);
268 "memory saving to be expected\n", self->
op);
277 if(available < 500.0f * 1024.0f * 1024.0f)
279 "[tiling] low memory (%.0f MiB): tiling '%s' aggressively\n",
280 available / (1024.0f * 1024.0f), self->
op);
282 available = fmaxf(available - ((
float)roi_out->
width * roi_out->
height * out_bpp)
293 const float largest_run
295 available = fminf(available, 0.9f * largest_run);
302 const float maxbuf = fmaxf(
tiling.maxbuf, 1.0f);
303 const float singlebuffer = available /
factor;
309 if((
float)
width *
height * max_bpp * maxbuf > singlebuffer)
311 const float scale = singlebuffer / ((float)
width *
height * max_bpp * maxbuf);
314 if(width < height && scale >= 0.333f)
318 else if(height <= width && scale >= 0.333f)
348 assert(xyalign != 0);
355 const int overlap =
tiling.overlap % xyalign != 0 ? (
tiling.overlap / xyalign + 1) * xyalign
359 const int tile_wd =
width - 2 * overlap > 0 ?
width - 2 * overlap : 1;
360 const int tile_ht =
height - 2 * overlap > 0 ?
height - 2 * overlap : 1;
363 const int tiles_x =
width < roi_in->
width ? ceilf(roi_in->
width / (
float)tile_wd) : 1;
364 const int tiles_y =
height < roi_in->
height ? ceilf(roi_in->
height / (
float)tile_ht) : 1;
369 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_ptp] gave up tiling for module '%s'. too many tiles: %d x %d\n",
370 self->
op, tiles_x, tiles_y);
374 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_ptp] (%dx%d) tiles with max dimensions %dx%d and overlap %d\n",
398 for(
size_t tx = 0; tx < tiles_x; tx++)
401 for(
size_t ty = 0; ty < tiles_y; ty++)
408 if((wd <= 2 * overlap && tx > 0) || (ht <= 2 * overlap && ty > 0))
continue;
411 size_t origin[] = { 0, 0, 0 };
412 size_t region[] = { wd, ht, 1 };
415 dt_iop_roi_t iroi = { roi_in->
x + tx * tile_wd, roi_in->
y + ty * tile_ht, wd, ht, roi_in->
scale };
416 dt_iop_roi_t oroi = { roi_out->
x + tx * tile_wd, roi_out->
y + ty * tile_ht, wd, ht, roi_out->
scale };
419 const size_t ioffs = (ty * tile_ht) * ipitch + (tx * tile_wd) * in_bpp;
420 size_t ooffs = (ty * tile_ht) * opitch + (tx * tile_wd) * out_bpp;
422 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_ptp] tile (%" G_GSIZE_FORMAT
",%" G_GSIZE_FORMAT
") with %" G_GSIZE_FORMAT
"x%" G_GSIZE_FORMAT
" at origin [%" G_GSIZE_FORMAT
",%" G_GSIZE_FORMAT
"]\n",
423 tx, ty, wd, ht, tx * tile_wd, ty * tile_ht);
427 for(
size_t j = 0; j < ht; j++)
428 memcpy((
char *)input + j * wd * in_bpp, (
char *)ivoid + ioffs + j * ipitch, (
size_t)wd * in_bpp);
434 int err = self->process(self, pipe, &piece_tile, input, output);
447 origin[0] += overlap;
448 region[0] -= overlap;
449 ooffs += (size_t)overlap * out_bpp;
453 origin[1] += overlap;
454 region[1] -= overlap;
455 ooffs += (size_t)overlap * opitch;
460 for(
size_t j = 0; j < region[1]; j++)
461 memcpy((
char *)
ovoid + ooffs + j * opitch,
462 (
char *)output + ((j + origin[1]) * wd + origin[0]) * out_bpp, (
size_t)region[0] * out_bpp);
481 int err = self->process(self, pipe, piece, ivoid,
ovoid);
491 const void *
const ivoid,
void *
const ovoid,
499 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_roi] **** tiling module '%s' for image input size %dx%d --> %dx%d\n",
506 const int ipitch = roi_in->
width * in_bpp;
507 const int opitch = roi_out->
width * out_bpp;
508 const int max_bpp =
_max(in_bpp, out_bpp);
510 float fullscale = fmaxf(roi_in->
scale / roi_out->
scale, sqrtf(((
float)roi_in->
width * roi_in->
height)
514 const int delta = ceilf(fullscale);
521 self->tiling_callback(self, pipe, piece, &
tiling);
527 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_roi] no need to use tiling for module '%s' as no memory saving is expected\n",
537 if(available < 500.0f * 1024.0f * 1024.0f)
539 "[tiling] low memory (%.0f MiB): tiling '%s' aggressively\n",
540 available / (1024.0f * 1024.0f), self->
op);
542 available = fmaxf(available - ((
float)roi_out->
width * roi_out->
height * out_bpp)
553 const float largest_run
555 available = fminf(available, 0.9f * largest_run);
562 const float maxbuf = fmaxf(
tiling.maxbuf, 1.0f);
563 const float singlebuffer = available /
factor;
576 assert(xyalign != 0);
579 if((
float)
width *
height * max_bpp * maxbuf > singlebuffer)
581 const float scale = singlebuffer / ((float)
width *
height * max_bpp * maxbuf);
584 if(width < height && scale >= 0.333f)
588 else if(height <= width && scale >= 0.333f)
612 const int overlap_out = ceilf((
float)overlap_in / fullscale);
614 int tiles_x = 1, tiles_y = 1;
620 ? ceilf((
float)roi_in->
width / (
float)
_max(
width - 2 * overlap_in - inacc, 1))
628 ? ceilf((
float)roi_in->
height / (
float)
_max(
height - 2 * overlap_in - inacc, 1))
638 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_roi] gave up tiling for module '%s'. too many tiles: %d x %d\n",
639 self->
op, tiles_x, tiles_y);
647 roi_out->
width % tiles_x == 0 ? roi_out->
width / tiles_x : roi_out->
width / tiles_x + 1, xyalign);
649 roi_out->
height % tiles_y == 0 ? roi_out->
height / tiles_y : roi_out->
height / tiles_y + 1, xyalign);
651 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_roi] (%dx%d) tiles with max dimensions %dx%d, good %dx%d, overlap %d->%d\n",
652 tiles_x, tiles_y,
width,
height, tile_wd, tile_ht, overlap_in, overlap_out);
655 for(
size_t tx = 0; tx < tiles_x; tx++)
656 for(
size_t ty = 0; ty < tiles_y; ty++)
661 const size_t wd = (tx + 1) * tile_wd > roi_out->
width ? (
size_t)roi_out->
width - tx * tile_wd : tile_wd;
662 const size_t ht = (ty + 1) * tile_ht > roi_out->
height ? (
size_t)roi_out->
height - ty * tile_ht : tile_ht;
666 dt_iop_roi_t iroi_good = { roi_in->
x + tx * tile_wd, roi_in->
y + ty * tile_ht, wd, ht, roi_in->
scale };
667 dt_iop_roi_t oroi_good = { roi_out->
x + tx * tile_wd, roi_out->
y + ty * tile_ht, wd, ht, roi_out->
scale };
670 self->modify_roi_in(self, pipe, &piece_copy, &oroi_good, &iroi_good);
673 iroi_good.
x =
_max(iroi_good.
x, roi_in->
x);
674 iroi_good.
y =
_max(iroi_good.
y, roi_in->
y);
685 const int x_in = iroi_good.
x;
686 const int y_in = iroi_good.
y;
687 const int width_in = iroi_good.
width;
688 const int height_in = iroi_good.
height;
691 const int new_width_in =
_min(
_align_up(width_in + overlap_in +
delta + (x_in - new_x_in), xyalign),
692 roi_in->
width + roi_in->
x - new_x_in);
693 const int new_height_in =
_min(
_align_up(height_in + overlap_in +
delta + (y_in - new_y_in), xyalign),
694 roi_in->
height + roi_in->
y - new_y_in);
698 dt_iop_roi_t iroi_full = { new_x_in, new_y_in, new_width_in, new_height_in, iroi_good.
scale };
701 _print_roi(&iroi_full,
"tile iroi_full before optimization");
702 _print_roi(&oroi_full,
"tile oroi_full before optimization");
708 "module '%s' not possible.\n",
713 _print_roi(&iroi_full,
"tile iroi_full after optimization");
714 _print_roi(&oroi_full,
"tile oroi_full after optimization");
718 oroi_full.
x =
_min(oroi_full.
x, oroi_good.
x);
719 oroi_full.
y =
_min(oroi_full.
y, oroi_good.
y);
724 oroi_full.
x =
_max(oroi_full.
x, roi_out->
x);
725 oroi_full.
y =
_max(oroi_full.
y, roi_out->
y);
731 self->modify_roi_in(self, pipe, &piece_full, &oroi_full, &iroi_full);
734 iroi_full.
x =
_max(iroi_full.
x, roi_in->
x);
735 iroi_full.
y =
_max(iroi_full.
y, roi_in->
y);
739 _print_roi(&iroi_full,
"tile iroi_full final");
740 _print_roi(&oroi_full,
"tile oroi_full final");
743 const size_t ioffs = ((size_t)iroi_full.
y - roi_in->
y) * ipitch + ((size_t)iroi_full.
x - roi_in->
x) * in_bpp;
744 size_t ooffs = ((size_t)oroi_good.
y - roi_out->
y) * opitch + ((size_t)oroi_good.
x - roi_out->
x) * out_bpp;
746 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_roi] process tile (%" G_GSIZE_FORMAT
",%" G_GSIZE_FORMAT
") size %dx%d at origin [%d,%d]\n",
747 tx, ty, iroi_full.
width, iroi_full.
height, iroi_full.
x, iroi_full.
y);
751 (
size_t)iroi_full.
width * iroi_full.
height * in_bpp,
760 (
size_t)oroi_full.
width * oroi_full.
height * out_bpp,
769 for(
size_t j = 0; j < iroi_full.
height; j++)
770 memcpy((
char *)input + j * iroi_full.
width * in_bpp, (
char *)ivoid + ioffs + j * ipitch,
771 (
size_t)iroi_full.
width * in_bpp);
775 piece_tile.
roi_in = iroi_full;
776 piece_tile.
roi_out = oroi_full;
777 int err = self->process(self, pipe, &piece_tile, input, output);
787 const int origin_x = oroi_good.
x - oroi_full.
x;
788 const int origin_y = oroi_good.
y - oroi_full.
y;
790 for(
size_t j = 0; j < oroi_good.
height; j++)
791 memcpy((
char *)
ovoid + ooffs + j * opitch,
792 (
char *)output + ((j + origin_y) * oroi_full.
width + origin_x) * out_bpp,
793 (
size_t)oroi_good.
width * out_bpp);
797 input = output = NULL;
815 int err = self->process(self, pipe, piece, ivoid,
ovoid);
828 const void *
const ivoid,
void *
const ovoid,
const int in_bpp)
844 const void *
const ivoid,
void *
const ovoid,
851 cl_mem output = NULL;
853 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_cl_ptp] **** tiling module '%s' for image with size %dx%d --> %dx%d\n",
859 const int ipitch = roi_in->
width * in_bpp;
860 const int opitch = roi_out->
width * out_bpp;
861 const int max_bpp =
_max(in_bpp, out_bpp);
865 self->tiling_callback(self, pipe, piece, &
tiling);
870 const float singlebuffer = fminf(fmaxf((available -
tiling.overhead) /
factor, 0.0f),
872 const float maxbuf = fmaxf(
tiling.maxbuf_cl, 1.0f);
873 int max_width = 0, max_height = 0;
879 if((
float)
width *
height * max_bpp * maxbuf > singlebuffer)
881 const float scale = singlebuffer / ((float)
width *
height * max_bpp * maxbuf);
883 if(width < height && scale >= 0.333f)
887 else if(height <= width && scale >= 0.333f)
921 const unsigned int halign = xyalign;
923 assert(xyalign != 0 && walign != 0 && halign != 0);
937 if(
width <= (
int)walign &&
height <= (int)halign)
break;
938 if(width < height && height > (
int)halign)
940 else if(
width > (
int)walign)
958 const int overlap =
tiling.overlap % xyalign != 0 ? (
tiling.overlap / xyalign + 1) * xyalign
963 const int tile_wd =
width - 2 * overlap > 0 ?
width - 2 * overlap : 1;
964 const int tile_ht =
height - 2 * overlap > 0 ?
height - 2 * overlap : 1;
968 const int tiles_x =
width < roi_in->
width ? ceilf(roi_in->
width / (
float)tile_wd) : 1;
969 const int tiles_y =
height < roi_in->
height ? ceilf(roi_in->
height / (
float)tile_ht) : 1;
974 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_cl_ptp] aborted tiling for module '%s'. too many tiles: %d x %d\n",
975 self->
op, tiles_x, tiles_y);
979 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_cl_ptp] (%dx%d) tiles with max dimensions %dx%d, good %dx%d and overlap %d\n",
980 tiles_x, tiles_y,
width,
height, tile_wd, tile_ht, overlap);
983 for(
size_t tx = 0; tx < tiles_x; tx++)
984 for(
size_t ty = 0; ty < tiles_y; ty++)
992 if((wd <= 2 * overlap && tx > 0) || (ht <= 2 * overlap && ty > 0))
continue;
995 size_t origin[] = { 0, 0, 0 };
996 size_t region[] = { wd, ht, 1 };
999 dt_iop_roi_t iroi = { roi_in->
x + tx * tile_wd, roi_in->
y + ty * tile_ht, wd, ht, roi_in->
scale };
1000 dt_iop_roi_t oroi = { roi_out->
x + tx * tile_wd, roi_out->
y + ty * tile_ht, wd, ht, roi_out->
scale };
1004 const size_t ioffs = (ty * tile_ht) * ipitch + (tx * tile_wd) * in_bpp;
1005 size_t ooffs = (ty * tile_ht) * opitch + (tx * tile_wd) * out_bpp;
1008 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_cl_ptp] tile (%" G_GSIZE_FORMAT
",%" G_GSIZE_FORMAT
") size %" G_GSIZE_FORMAT
"x%" G_GSIZE_FORMAT
" at origin [%" G_GSIZE_FORMAT
",%" G_GSIZE_FORMAT
"]\n",
1009 tx, ty, wd, ht, tx * tile_wd, ty * tile_ht);
1020 if(err != CL_SUCCESS)
goto error;
1024 piece_tile.
roi_in = iroi;
1026 if(!self->process_cl(self, pipe, &piece_tile, input, output))
goto error;
1032 origin[0] += overlap;
1033 region[0] -= overlap;
1034 ooffs += (size_t)overlap * out_bpp;
1038 origin[1] += overlap;
1039 region[1] -= overlap;
1040 ooffs += (size_t)overlap * opitch;
1046 if(err != CL_SUCCESS)
goto error;
1060 mutable_pipe->
tiling = 0;
1066 mutable_pipe->
tiling = 0;
1068 "[default_process_tiling_opencl_ptp] couldn't run process_cl() for module '%s' in tiling mode: %i\n",
1078 const void *
const ivoid,
void *
const ovoid,
1084 cl_mem input = NULL;
1085 cl_mem output = NULL;
1088 "[default_process_tiling_cl_roi] **** tiling module '%s' for image with input size %dx%d --> %dx%d\n",
1096 const int ipitch = roi_in->
width * in_bpp;
1097 const int opitch = roi_out->
width * out_bpp;
1098 const int max_bpp =
_max(in_bpp, out_bpp);
1100 const float fullscale = fmaxf(roi_in->
scale / roi_out->
scale, sqrtf(((
float)roi_in->
width * roi_in->
height)
1104 const int delta = ceilf(fullscale);
1111 self->tiling_callback(self, pipe, piece, &
tiling);
1116 const float singlebuffer = fminf(fmaxf((available -
tiling.overhead) /
factor, 0.0f),
1118 const float maxbuf = fmaxf(
tiling.maxbuf_cl, 1.0f);
1120 int max_width = 0, max_height = 0;
1134 assert(xyalign != 0);
1137 if((
float)
width *
height * max_bpp * maxbuf > singlebuffer)
1139 const float scale = singlebuffer / ((float)
width *
height * max_bpp * maxbuf);
1141 if(width < height && scale >= 0.333f)
1145 else if(height <= width && scale >= 0.333f)
1169 const int overlap_out = ceilf((
float)overlap_in / fullscale);
1177 if(
width <= (
int)xyalign &&
height <= (
int)xyalign)
break;
1178 if(width < height && height > (
int)xyalign)
1180 else if(
width > (
int)xyalign)
1192 int tiles_x = 1, tiles_y = 1;
1198 ? ceilf((
float)roi_in->
width / (
float)
_max(
width - 2 * overlap_in - inacc, 1))
1206 ? ceilf((
float)roi_in->
height / (
float)
_max(
height - 2 * overlap_in - inacc, 1))
1217 "[default_process_tiling_cl_roi] aborted tiling for module '%s'. too many tiles: %dx%d\n",
1218 self->
op, tiles_x, tiles_y);
1225 roi_out->
width % tiles_x == 0 ? roi_out->
width / tiles_x : roi_out->
width / tiles_x + 1, xyalign);
1227 roi_out->
height % tiles_y == 0 ? roi_out->
height / tiles_y : roi_out->
height / tiles_y + 1, xyalign);
1230 "[default_process_tiling_cl_roi] (%dx%d) tiles with max input dimensions %dx%d, good %ix%i\n",
1231 tiles_x, tiles_y,
width,
height, tile_wd, tile_ht);
1234 for(
size_t tx = 0; tx < tiles_x; tx++)
1235 for(
size_t ty = 0; ty < tiles_y; ty++)
1237 mutable_pipe->
tiling = 1;
1240 const size_t wd = (tx + 1) * tile_wd > roi_out->
width ? (
size_t)roi_out->
width - tx * tile_wd : tile_wd;
1241 const size_t ht = (ty + 1) * tile_ht > roi_out->
height ? (
size_t)roi_out->
height - ty * tile_ht : tile_ht;
1245 dt_iop_roi_t iroi_good = { roi_in->
x + tx * tile_wd, roi_in->
y + ty * tile_ht, wd, ht, roi_in->
scale };
1246 dt_iop_roi_t oroi_good = { roi_out->
x + tx * tile_wd, roi_out->
y + ty * tile_ht, wd, ht, roi_out->
scale };
1249 self->modify_roi_in(self, pipe, &piece_copy, &oroi_good, &iroi_good);
1252 iroi_good.
x =
_max(iroi_good.
x, roi_in->
x);
1253 iroi_good.
y =
_max(iroi_good.
y, roi_in->
y);
1264 const int x_in = iroi_good.
x;
1265 const int y_in = iroi_good.
y;
1266 const int width_in = iroi_good.
width;
1267 const int height_in = iroi_good.
height;
1270 const int new_width_in =
_min(
_align_up(width_in + overlap_in +
delta + (x_in - new_x_in), xyalign),
1271 roi_in->
width + roi_in->
x - new_x_in);
1272 const int new_height_in =
_min(
_align_up(height_in + overlap_in +
delta + (y_in - new_y_in), xyalign),
1273 roi_in->
height + roi_in->
y - new_y_in);
1277 dt_iop_roi_t iroi_full = { new_x_in, new_y_in, new_width_in, new_height_in, iroi_good.
scale };
1280 _print_roi(&iroi_full,
"tile iroi_full before optimization");
1281 _print_roi(&oroi_full,
"tile oroi_full before optimization");
1287 "for module '%s' not possible.\n",
1295 oroi_full.
x =
_min(oroi_full.
x, oroi_good.
x);
1296 oroi_full.
y =
_min(oroi_full.
y, oroi_good.
y);
1301 oroi_full.
x =
_max(oroi_full.
x, roi_out->
x);
1302 oroi_full.
y =
_max(oroi_full.
y, roi_out->
y);
1309 self->modify_roi_in(self, pipe, &piece_full, &oroi_full, &iroi_full);
1312 iroi_full.
x =
_max(iroi_full.
x, roi_in->
x);
1313 iroi_full.
y =
_max(iroi_full.
y, roi_in->
y);
1321 const int in_dx = iroi_full.
x - roi_in->
x;
1322 const int in_dy = iroi_full.
y - roi_in->
y;
1323 const int out_dx = oroi_good.
x - roi_out->
x;
1324 const int out_dy = oroi_good.
y - roi_out->
y;
1325 const size_t ioffs = (size_t)(in_dy * ipitch) + (size_t)(in_dx * in_bpp);
1326 const size_t ooffs = (size_t)(out_dy * opitch) + (size_t)(out_dx * out_bpp);
1329 size_t iorigin[] = { 0, 0, 0 };
1330 size_t iregion[] = { iroi_full.
width, iroi_full.
height, 1 };
1333 size_t oorigin[] = { oroi_good.
x - oroi_full.
x, oroi_good.
y - oroi_full.
y, 0 };
1334 size_t oregion[] = { oroi_good.
width, oroi_good.
height, 1 };
1336 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_cl_roi] process tile (%" G_GSIZE_FORMAT
",%" G_GSIZE_FORMAT
") size %dx%d at origin [%d,%d]\n",
1337 tx, ty, iroi_full.
width, iroi_full.
height, iroi_full.
x, iroi_full.
y);
1338 dt_vprint(
DT_DEBUG_TILING,
"[default_process_tiling_cl_roi] dest [%" G_GSIZE_FORMAT
",%" G_GSIZE_FORMAT
"] at [%" G_GSIZE_FORMAT
",%" G_GSIZE_FORMAT
"], offsets [%i,%i] -> [%i,%i], delta=%i\n\n",
1339 oregion[0], oregion[1], oorigin[0], oorigin[1], in_dx, in_dy, out_dx, out_dy,
delta);
1351 if(err != CL_SUCCESS)
goto error;
1355 piece_tile.
roi_in = iroi_full;
1356 piece_tile.
roi_out = oroi_full;
1357 if(!self->process_cl(self, pipe, &piece_tile, input, output))
goto error;
1362 if(err != CL_SUCCESS)
goto error;
1376 mutable_pipe->
tiling = 0;
1382 mutable_pipe->
tiling = 0;
1384 "[default_process_tiling_opencl_roi] couldn't run process_cl() for module '%s' in tiling mode: %i\n",
1396 const void *
const ivoid,
void *
const ovoid,
const int in_bpp)
1409 const void *
const ivoid,
void *
const ovoid,
const int in_bpp)
1432 tiling->factor = 1.0f + ioratio;
1466 const float factor,
const size_t overhead)
1478 while(!
error && (available < total || (
size_t)(0.9f * largest_run) < total))
1485 size_t cache_current = 0;
1486 size_t cache_max = 0;
1488 if(cache_max - cache_current >= total && (
size_t)(0.9f * largest_run) >= total)
break;
1495 return total <= available && total <= (size_t)(0.9f * largest_run);
static void error(char *msg)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
size_t dt_get_available_mem()
@ IOP_FLAGS_TILING_FULL_ROI
int dt_ioppr_get_iop_order(GList *iop_order_list, const char *op_name, const int multi_priority)
Return the iop_order for a given operation/instance pair.
int32_t dt_get_debug_flags(void)
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
void void void dt_vprint(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
dt_print() that additionally requires DT_DEBUG_VERBOSE to be enabled, i.e. both -d <channel> and -d v...
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static int simplex(double(*objfunc)(double[], void *params), double start[], int n, double EPSILON, double scale, int maxiter, void(*constrain)(double[], int n), void *params)
cl_ulong dt_opencl_get_device_available(const int devid)
void * dt_opencl_alloc_device(const int devid, const int width, const int height, const int bpp)
gboolean dt_opencl_get_device_max_image_size(const int devid, int *width, int *height)
Largest 2D image the device will accept, which is what bounds tile size.
int dt_opencl_read_host_from_device_raw(const int devid, void *host, void *device, const size_t *origin, const size_t *region, const int rowpitch, const int blocking)
cl_ulong dt_opencl_get_device_memalloc(const int devid)
gboolean dt_opencl_finish(const int devid)
int dt_opencl_write_host_to_device_raw(const int devid, const void *host, void *device, const size_t *origin, const size_t *region, const int rowpitch, const int blocking)
void dt_opencl_release_mem_object(cl_mem mem)
#define __OMP_PARALLEL_FOR__(...)
void dt_pipeline_message(const char *format,...)
Everything the pixel pipeline says to whoever is watching: messages for the user, and the busy banner...
int dt_dev_pixel_pipe_cache_remove_lru(void)
size_t dt_pixelpipe_cache_get_largest_free_run(void)
void dt_dev_pixelpipe_cache_get_usage(size_t *current, size_t *max)
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
#define dt_pixelpipe_cache_free_align(mem)
dt_iop_buffer_dsc_t dsc_out
dt_iop_buffer_dsc_t dsc_in
dt_dev_pixelpipe_type_t type
Region of interest passed through the pixelpipe.
typedef double((*spd)(unsigned long int wavelength, double TempK))
static double _nm_fitness(double x[], void *params)
int default_process_tiling(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const int in_bpp)
static int _fit_output_to_input_roi(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *iroi, dt_iop_roi_t *oroi, int delta, int iter)
static int _nm_fit_output_to_input_roi(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *iroi, dt_iop_roi_t *oroi, int delta)
void default_tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
static int _default_process_tiling_roi(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out, const int in_bpp)
static int _align_up(int n, int a)
static int _default_process_tiling_ptp(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out, const int in_bpp)
static void _print_roi(const dt_iop_roi_t *roi, const char *label)
int dt_tiling_piece_fits_host_memory(const size_t width, const size_t height, const unsigned bpp, const float factor, const size_t overhead)
static int _max(int a, int b)
static int _default_process_tiling_cl_ptp(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out, const int in_bpp)
static int _align_close(int n, int a)
static unsigned _lcm(unsigned a, unsigned b)
static int _default_process_tiling_cl_roi(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out, const int in_bpp)
static int _min(int a, int b)
int default_process_tiling_cl(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const int in_bpp)
static int _align_down(int n, int a)
static int _maximum_number_tiles()
static unsigned _gcd(unsigned a, unsigned b)