50#define CLAMPI(a, mn, mx) ((a) < (mn) ? (mn) : ((a) > (mx) ? (mx) : (a)))
56#define CL_ALIGNMENT ((piece->dsc_in.filters != 9u) ? 4 : 1)
64static unsigned _gcd(
unsigned a,
unsigned b)
77static unsigned _lcm(
unsigned a,
unsigned b)
79 return (((
unsigned long)a * b) /
_gcd(a, b));
83static inline int _min(
int a,
int b)
88static inline int _max(
int a,
int b)
96 return n + a - (
n % a);
104 const int off =
n % a;
105 const int shift = (off > a/2) ? a - off : -off;
135 if(available < 500.0f * 1024.0f * 1024.0f)
137 "[tiling] low memory (%.0f MiB): tiling '%s' aggressively\n",
138 available / (1024.0f * 1024.0f), op);
139 available = fmaxf(available - (
float)io_bytes -
tiling->overhead, 0);
148 const float largest_run
150 available = fminf(available, 0.9f * largest_run);
156 return available / fmaxf(
tiling->factor, 1.0f);
162 fprintf(stderr,
" {%5d %5d ->%5d %5d (%5dx%5d) %.6f } %s\n",
169_nm_constraints(
double x[],
int n)
176 if(
x[0] > 1.0)
x[0] = 1.0 -
x[0];
177 if(
x[1] > 1.0)
x[1] = 1.0 -
x[1];
178 if(
x[2] > 1.0)
x[2] = 1.0 -
x[2];
179 if(
x[3] > 1.0)
x[3] = 1.0 -
x[3];
186 void **rest = (
void **)
params;
201 self->modify_roi_in(self,
pipe, &piece_copy, &oroi_test, &iroi_probe);
203 double fitness = 0.0;
205 fitness += (
double)(iroi_probe.
x - iroi->
x) * (iroi_probe.
x - iroi->
x);
206 fitness += (
double)(iroi_probe.
y - iroi->
y) * (iroi_probe.
y - iroi->
y);
218 void *rest[5] = { (
void *)self, (
void *)
piece, (
void *)iroi, (
void *)oroi, (
void *)
pipe };
233 return (iter <= maxiter);
251 self->modify_roi_in(self,
pipe, &piece_copy, oroi, &iroi_probe);
252 while((abs((
int)iroi_probe.
x - (
int)iroi->
x) >
delta || abs((
int)iroi_probe.
y - (
int)iroi->
y) >
delta
259 oroi->
x += (iroi->
x - iroi_probe.
x) * oroi->
scale / iroi->
scale;
260 oroi->
y += (iroi->
y - iroi_probe.
y) * oroi->
scale / iroi->
scale;
267 self->modify_roi_in(self,
pipe, &piece_copy, oroi, &iroi_probe);
271 if(iter > 0)
return TRUE;
287 const void *
const ivoid,
void *
const ovoid,
294 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_ptp] **** tiling module '%s' for image with size %dx%d --> %dx%d\n",
296 const int out_bpp =
piece->dsc_out.bpp;
298 const int ipitch = roi_in->
width * in_bpp;
299 const int opitch = roi_out->
width * out_bpp;
300 const int max_bpp =
_max(in_bpp, out_bpp);
309 "memory saving to be expected\n", self->
op);
316 const float maxbuf = fmaxf(
tiling.maxbuf, 1.0f);
322 if((
float)
width *
height * max_bpp * maxbuf > singlebuffer)
324 const float scale = singlebuffer / ((float)
width *
height * max_bpp * maxbuf);
327 if(width < height && scale >= 0.333f)
331 else if(height <= width && scale >= 0.333f)
361 assert(xyalign != 0);
368 const int overlap =
tiling.overlap % xyalign != 0 ? (
tiling.overlap / xyalign + 1) * xyalign
372 const int tile_wd =
width - 2 * overlap > 0 ?
width - 2 * overlap : 1;
373 const int tile_ht =
height - 2 * overlap > 0 ?
height - 2 * overlap : 1;
376 const int tiles_x =
width < roi_in->
width ? ceilf(roi_in->
width / (
float)tile_wd) : 1;
377 const int tiles_y =
height < roi_in->
height ? ceilf(roi_in->
height / (
float)tile_ht) : 1;
382 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_ptp] gave up tiling for module '%s'. too many tiles: %d x %d\n",
383 self->
op, tiles_x, tiles_y);
387 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_ptp] (%dx%d) tiles with max dimensions %dx%d and overlap %d\n",
411 for(
size_t tx = 0; tx < tiles_x; tx++)
414 for(
size_t ty = 0; ty < tiles_y; ty++)
421 if((wd <= 2 * overlap && tx > 0) || (ht <= 2 * overlap && ty > 0))
continue;
424 size_t origin[] = { 0, 0, 0 };
425 size_t region[] = { wd, ht, 1 };
428 dt_iop_roi_t iroi = { roi_in->
x + tx * tile_wd, roi_in->
y + ty * tile_ht, wd, ht, roi_in->
scale };
429 dt_iop_roi_t oroi = { roi_out->
x + tx * tile_wd, roi_out->
y + ty * tile_ht, wd, ht, roi_out->
scale };
432 const size_t ioffs = (ty * tile_ht) * ipitch + (tx * tile_wd) * in_bpp;
433 size_t ooffs = (ty * tile_ht) * opitch + (tx * tile_wd) * out_bpp;
435 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",
436 tx, ty, wd, ht, tx * tile_wd, ty * tile_ht);
440 for(
size_t j = 0; j < ht; j++)
441 memcpy((
char *)input + j * wd * in_bpp, (
char *)ivoid + ioffs + j * ipitch, (
size_t)wd * in_bpp);
447 int err = self->process(self,
pipe, &piece_tile, input, output);
460 origin[0] += overlap;
461 region[0] -= overlap;
462 ooffs += (size_t)overlap * out_bpp;
466 origin[1] += overlap;
467 region[1] -= overlap;
468 ooffs += (size_t)overlap * opitch;
473 for(
size_t j = 0; j < region[1]; j++)
474 memcpy((
char *)
ovoid + ooffs + j * opitch,
475 (
char *)output + ((j + origin[1]) * wd + origin[0]) * out_bpp, (
size_t)region[0] * out_bpp);
487 dt_control_alert(_(
"Module failed"), _(
"tiling failed. output might be garbled."), item);
508 const void *
const ivoid,
void *
const ovoid,
516 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_roi] **** tiling module '%s' for image input size %dx%d --> %dx%d\n",
521 const int out_bpp =
piece->dsc_out.bpp;
523 const int ipitch = roi_in->
width * in_bpp;
524 const int opitch = roi_out->
width * out_bpp;
525 const int max_bpp =
_max(in_bpp, out_bpp);
527 float fullscale = fmaxf(roi_in->
scale / roi_out->
scale, sqrtf(((
float)roi_in->
width * roi_in->
height)
531 const int delta = ceilf(fullscale);
542 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_roi] no need to use tiling for module '%s' as no memory saving is expected\n",
550 const float maxbuf = fmaxf(
tiling.maxbuf, 1.0f);
563 assert(xyalign != 0);
566 if((
float)
width *
height * max_bpp * maxbuf > singlebuffer)
568 const float scale = singlebuffer / ((float)
width *
height * max_bpp * maxbuf);
571 if(width < height && scale >= 0.333f)
575 else if(height <= width && scale >= 0.333f)
599 const int overlap_out = ceilf((
float)overlap_in / fullscale);
601 int tiles_x = 1, tiles_y = 1;
607 ? ceilf((
float)roi_in->
width / (
float)
_max(
width - 2 * overlap_in - inacc, 1))
615 ? ceilf((
float)roi_in->
height / (
float)
_max(
height - 2 * overlap_in - inacc, 1))
625 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_roi] gave up tiling for module '%s'. too many tiles: %d x %d\n",
626 self->
op, tiles_x, tiles_y);
634 roi_out->
width % tiles_x == 0 ? roi_out->
width / tiles_x : roi_out->
width / tiles_x + 1, xyalign);
636 roi_out->
height % tiles_y == 0 ? roi_out->
height / tiles_y : roi_out->
height / tiles_y + 1, xyalign);
638 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_roi] (%dx%d) tiles with max dimensions %dx%d, good %dx%d, overlap %d->%d\n",
639 tiles_x, tiles_y,
width,
height, tile_wd, tile_ht, overlap_in, overlap_out);
642 for(
size_t tx = 0; tx < tiles_x; tx++)
643 for(
size_t ty = 0; ty < tiles_y; ty++)
648 const size_t wd = (tx + 1) * tile_wd > roi_out->
width ? (
size_t)roi_out->
width - tx * tile_wd : tile_wd;
649 const size_t ht = (ty + 1) * tile_ht > roi_out->
height ? (
size_t)roi_out->
height - ty * tile_ht : tile_ht;
653 dt_iop_roi_t iroi_good = { roi_in->
x + tx * tile_wd, roi_in->
y + ty * tile_ht, wd, ht, roi_in->
scale };
654 dt_iop_roi_t oroi_good = { roi_out->
x + tx * tile_wd, roi_out->
y + ty * tile_ht, wd, ht, roi_out->
scale };
657 self->modify_roi_in(self,
pipe, &piece_copy, &oroi_good, &iroi_good);
660 iroi_good.
x =
_max(iroi_good.
x, roi_in->
x);
661 iroi_good.
y =
_max(iroi_good.
y, roi_in->
y);
672 const int x_in = iroi_good.
x;
673 const int y_in = iroi_good.
y;
674 const int width_in = iroi_good.
width;
675 const int height_in = iroi_good.
height;
678 const int new_width_in =
_min(
_align_up(width_in + overlap_in +
delta + (x_in - new_x_in), xyalign),
679 roi_in->
width + roi_in->
x - new_x_in);
680 const int new_height_in =
_min(
_align_up(height_in + overlap_in +
delta + (y_in - new_y_in), xyalign),
681 roi_in->
height + roi_in->
y - new_y_in);
685 dt_iop_roi_t iroi_full = { new_x_in, new_y_in, new_width_in, new_height_in, iroi_good.
scale };
688 _print_roi(&iroi_full,
"tile iroi_full before optimization");
689 _print_roi(&oroi_full,
"tile oroi_full before optimization");
695 "module '%s' not possible.\n",
700 _print_roi(&iroi_full,
"tile iroi_full after optimization");
701 _print_roi(&oroi_full,
"tile oroi_full after optimization");
705 oroi_full.
x =
_min(oroi_full.
x, oroi_good.
x);
706 oroi_full.
y =
_min(oroi_full.
y, oroi_good.
y);
711 oroi_full.
x =
_max(oroi_full.
x, roi_out->
x);
712 oroi_full.
y =
_max(oroi_full.
y, roi_out->
y);
718 self->modify_roi_in(self,
pipe, &piece_full, &oroi_full, &iroi_full);
721 iroi_full.
x =
_max(iroi_full.
x, roi_in->
x);
722 iroi_full.
y =
_max(iroi_full.
y, roi_in->
y);
726 _print_roi(&iroi_full,
"tile iroi_full final");
727 _print_roi(&oroi_full,
"tile oroi_full final");
730 const size_t ioffs = ((size_t)iroi_full.
y - roi_in->
y) * ipitch + ((size_t)iroi_full.
x - roi_in->
x) * in_bpp;
731 size_t ooffs = ((size_t)oroi_good.
y - roi_out->
y) * opitch + ((size_t)oroi_good.
x - roi_out->
x) * out_bpp;
733 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",
734 tx, ty, iroi_full.
width, iroi_full.
height, iroi_full.
x, iroi_full.
y);
738 (
size_t)iroi_full.
width * iroi_full.
height * in_bpp,
747 (
size_t)oroi_full.
width * oroi_full.
height * out_bpp,
756 for(
size_t j = 0; j < iroi_full.
height; j++)
757 memcpy((
char *)input + j * iroi_full.
width * in_bpp, (
char *)ivoid + ioffs + j * ipitch,
758 (
size_t)iroi_full.
width * in_bpp);
762 piece_tile.
roi_in = iroi_full;
763 piece_tile.
roi_out = oroi_full;
764 int err = self->process(self,
pipe, &piece_tile, input, output);
774 const int origin_x = oroi_good.
x - oroi_full.
x;
775 const int origin_y = oroi_good.
y - oroi_full.
y;
777 for(
size_t j = 0; j < oroi_good.
height; j++)
778 memcpy((
char *)
ovoid + ooffs + j * opitch,
780 (
size_t)oroi_good.
width * out_bpp);
784 input = output = NULL;
795 dt_control_alert(_(
"Module failed"), _(
"tiling failed. output might be garbled."), item);
819 const void *
const ivoid,
void *
const ovoid,
const int in_bpp)
835 const void *
const ivoid,
void *
const ovoid,
842 cl_mem output = NULL;
844 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_cl_ptp] **** tiling module '%s' for image with size %dx%d --> %dx%d\n",
847 const int out_bpp =
piece->dsc_out.bpp;
850 const int ipitch = roi_in->
width * in_bpp;
851 const int opitch = roi_out->
width * out_bpp;
852 const int max_bpp =
_max(in_bpp, out_bpp);
861 const float singlebuffer = fminf(fmaxf((available -
tiling.overhead) /
factor, 0.0f),
863 const float maxbuf = fmaxf(
tiling.maxbuf_cl, 1.0f);
864 int max_width = 0, max_height = 0;
870 if((
float)
width *
height * max_bpp * maxbuf > singlebuffer)
872 const float scale = singlebuffer / ((float)
width *
height * max_bpp * maxbuf);
874 if(width < height && scale >= 0.333f)
878 else if(height <= width && scale >= 0.333f)
912 const unsigned int halign = xyalign;
914 assert(xyalign != 0 && walign != 0 && halign != 0);
928 if(
width <= (
int)walign &&
height <= (int)halign)
break;
929 if(width < height && height > (
int)halign)
931 else if(
width > (
int)walign)
949 const int overlap =
tiling.overlap % xyalign != 0 ? (
tiling.overlap / xyalign + 1) * xyalign
954 const int tile_wd =
width - 2 * overlap > 0 ?
width - 2 * overlap : 1;
955 const int tile_ht =
height - 2 * overlap > 0 ?
height - 2 * overlap : 1;
959 const int tiles_x =
width < roi_in->
width ? ceilf(roi_in->
width / (
float)tile_wd) : 1;
960 const int tiles_y =
height < roi_in->
height ? ceilf(roi_in->
height / (
float)tile_ht) : 1;
965 dt_print(
DT_DEBUG_TILING,
"[default_process_tiling_cl_ptp] aborted tiling for module '%s'. too many tiles: %d x %d\n",
966 self->
op, tiles_x, tiles_y);
970 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",
971 tiles_x, tiles_y,
width,
height, tile_wd, tile_ht, overlap);
974 for(
size_t tx = 0; tx < tiles_x; tx++)
975 for(
size_t ty = 0; ty < tiles_y; ty++)
983 if((wd <= 2 * overlap && tx > 0) || (ht <= 2 * overlap && ty > 0))
continue;
986 size_t origin[] = { 0, 0, 0 };
987 size_t region[] = { wd, ht, 1 };
990 dt_iop_roi_t iroi = { roi_in->
x + tx * tile_wd, roi_in->
y + ty * tile_ht, wd, ht, roi_in->
scale };
991 dt_iop_roi_t oroi = { roi_out->
x + tx * tile_wd, roi_out->
y + ty * tile_ht, wd, ht, roi_out->
scale };
995 const size_t ioffs = (ty * tile_ht) * ipitch + (tx * tile_wd) * in_bpp;
996 size_t ooffs = (ty * tile_ht) * opitch + (tx * tile_wd) * out_bpp;
999 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",
1000 tx, ty, wd, ht, tx * tile_wd, ty * tile_ht);
1011 if(err != CL_SUCCESS)
goto error;
1015 piece_tile.
roi_in = iroi;
1017 if(!self->process_cl(self,
pipe, &piece_tile, input, output))
goto error;
1023 origin[0] += overlap;
1024 region[0] -= overlap;
1025 ooffs += (size_t)overlap * out_bpp;
1029 origin[1] += overlap;
1030 region[1] -= overlap;
1031 ooffs += (size_t)overlap * opitch;
1037 if(err != CL_SUCCESS)
goto error;
1051 mutable_pipe->
tiling = 0;
1057 mutable_pipe->
tiling = 0;
1059 "[default_process_tiling_opencl_ptp] couldn't run process_cl() for module '%s' in tiling mode: %i\n",
1069 const void *
const ivoid,
void *
const ovoid,
1075 cl_mem input = NULL;
1076 cl_mem output = NULL;
1079 "[default_process_tiling_cl_roi] **** tiling module '%s' for image with input size %dx%d --> %dx%d\n",
1084 const int out_bpp =
piece->dsc_out.bpp;
1087 const int ipitch = roi_in->
width * in_bpp;
1088 const int opitch = roi_out->
width * out_bpp;
1089 const int max_bpp =
_max(in_bpp, out_bpp);
1091 const float fullscale = fmaxf(roi_in->
scale / roi_out->
scale, sqrtf(((
float)roi_in->
width * roi_in->
height)
1095 const int delta = ceilf(fullscale);
1107 const float singlebuffer = fminf(fmaxf((available -
tiling.overhead) /
factor, 0.0f),
1109 const float maxbuf = fmaxf(
tiling.maxbuf_cl, 1.0f);
1111 int max_width = 0, max_height = 0;
1125 assert(xyalign != 0);
1128 if((
float)
width *
height * max_bpp * maxbuf > singlebuffer)
1130 const float scale = singlebuffer / ((float)
width *
height * max_bpp * maxbuf);
1132 if(width < height && scale >= 0.333f)
1136 else if(height <= width && scale >= 0.333f)
1160 const int overlap_out = ceilf((
float)overlap_in / fullscale);
1168 if(
width <= (
int)xyalign &&
height <= (
int)xyalign)
break;
1169 if(width < height && height > (
int)xyalign)
1171 else if(
width > (
int)xyalign)
1183 int tiles_x = 1, tiles_y = 1;
1189 ? ceilf((
float)roi_in->
width / (
float)
_max(
width - 2 * overlap_in - inacc, 1))
1197 ? ceilf((
float)roi_in->
height / (
float)
_max(
height - 2 * overlap_in - inacc, 1))
1208 "[default_process_tiling_cl_roi] aborted tiling for module '%s'. too many tiles: %dx%d\n",
1209 self->
op, tiles_x, tiles_y);
1216 roi_out->
width % tiles_x == 0 ? roi_out->
width / tiles_x : roi_out->
width / tiles_x + 1, xyalign);
1218 roi_out->
height % tiles_y == 0 ? roi_out->
height / tiles_y : roi_out->
height / tiles_y + 1, xyalign);
1221 "[default_process_tiling_cl_roi] (%dx%d) tiles with max input dimensions %dx%d, good %ix%i\n",
1222 tiles_x, tiles_y,
width,
height, tile_wd, tile_ht);
1225 for(
size_t tx = 0; tx < tiles_x; tx++)
1226 for(
size_t ty = 0; ty < tiles_y; ty++)
1228 mutable_pipe->
tiling = 1;
1231 const size_t wd = (tx + 1) * tile_wd > roi_out->
width ? (
size_t)roi_out->
width - tx * tile_wd : tile_wd;
1232 const size_t ht = (ty + 1) * tile_ht > roi_out->
height ? (
size_t)roi_out->
height - ty * tile_ht : tile_ht;
1236 dt_iop_roi_t iroi_good = { roi_in->
x + tx * tile_wd, roi_in->
y + ty * tile_ht, wd, ht, roi_in->
scale };
1237 dt_iop_roi_t oroi_good = { roi_out->
x + tx * tile_wd, roi_out->
y + ty * tile_ht, wd, ht, roi_out->
scale };
1240 self->modify_roi_in(self,
pipe, &piece_copy, &oroi_good, &iroi_good);
1243 iroi_good.
x =
_max(iroi_good.
x, roi_in->
x);
1244 iroi_good.
y =
_max(iroi_good.
y, roi_in->
y);
1255 const int x_in = iroi_good.
x;
1256 const int y_in = iroi_good.
y;
1257 const int width_in = iroi_good.
width;
1258 const int height_in = iroi_good.
height;
1261 const int new_width_in =
_min(
_align_up(width_in + overlap_in +
delta + (x_in - new_x_in), xyalign),
1262 roi_in->
width + roi_in->
x - new_x_in);
1263 const int new_height_in =
_min(
_align_up(height_in + overlap_in +
delta + (y_in - new_y_in), xyalign),
1264 roi_in->
height + roi_in->
y - new_y_in);
1268 dt_iop_roi_t iroi_full = { new_x_in, new_y_in, new_width_in, new_height_in, iroi_good.
scale };
1271 _print_roi(&iroi_full,
"tile iroi_full before optimization");
1272 _print_roi(&oroi_full,
"tile oroi_full before optimization");
1278 "for module '%s' not possible.\n",
1286 oroi_full.
x =
_min(oroi_full.
x, oroi_good.
x);
1287 oroi_full.
y =
_min(oroi_full.
y, oroi_good.
y);
1292 oroi_full.
x =
_max(oroi_full.
x, roi_out->
x);
1293 oroi_full.
y =
_max(oroi_full.
y, roi_out->
y);
1300 self->modify_roi_in(self,
pipe, &piece_full, &oroi_full, &iroi_full);
1303 iroi_full.
x =
_max(iroi_full.
x, roi_in->
x);
1304 iroi_full.
y =
_max(iroi_full.
y, roi_in->
y);
1312 const int in_dx = iroi_full.
x - roi_in->
x;
1313 const int in_dy = iroi_full.
y - roi_in->
y;
1314 const int out_dx = oroi_good.
x - roi_out->
x;
1315 const int out_dy = oroi_good.
y - roi_out->
y;
1316 const size_t ioffs = (size_t)(in_dy * ipitch) + (size_t)(in_dx * in_bpp);
1317 const size_t ooffs = (size_t)(out_dy * opitch) + (size_t)(out_dx * out_bpp);
1320 size_t iorigin[] = { 0, 0, 0 };
1321 size_t iregion[] = { iroi_full.
width, iroi_full.
height, 1 };
1324 size_t oorigin[] = { oroi_good.
x - oroi_full.
x, oroi_good.
y - oroi_full.
y, 0 };
1325 size_t oregion[] = { oroi_good.
width, oroi_good.
height, 1 };
1327 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",
1328 tx, ty, iroi_full.
width, iroi_full.
height, iroi_full.
x, iroi_full.
y);
1329 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",
1330 oregion[0], oregion[1], oorigin[0], oorigin[1], in_dx, in_dy, out_dx, out_dy,
delta);
1342 if(err != CL_SUCCESS)
goto error;
1346 piece_tile.
roi_in = iroi_full;
1347 piece_tile.
roi_out = oroi_full;
1348 if(!self->process_cl(self,
pipe, &piece_tile, input, output))
goto error;
1353 if(err != CL_SUCCESS)
goto error;
1367 mutable_pipe->
tiling = 0;
1373 mutable_pipe->
tiling = 0;
1375 "[default_process_tiling_opencl_roi] couldn't run process_cl() for module '%s' in tiling mode: %i\n",
1387 const void *
const ivoid,
void *
const ovoid,
const int in_bpp)
1400 const void *
const ivoid,
void *
const ovoid,
const int in_bpp)
1423 tiling->factor = 1.0f + ioratio;
1438 if(!
piece->dsc_in.filters)
return;
1440 if(
piece->dsc_in.filters == 9u)
1470 const float factor,
const size_t overhead)
1482 while((
size_t)(0.9f * largest_run) < total)
static void error(char *msg)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_control_alert(const char *title, const char *message, const char *item)
Tell the user something that must not go unseen: what it says stays true after a toast would have fad...
@ 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.
static const dt_dev_pixelpipe_t * pipe
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t * piece
static const dt_iop_drawlayer_params_t * params
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t int int int int * origin_y
static const dt_dev_pixelpipe_t const dt_dev_pixelpipe_iop_t int int int * origin_x
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...
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
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__(...)
size_t dt_dev_pixelpipe_cache_get_available(void)
int dt_dev_pixel_pipe_cache_remove_lru(void)
size_t dt_pixelpipe_cache_get_largest_free_run(void)
Pixelpipe cache for storing intermediate results in the pixelpipe.
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
#define dt_pixelpipe_cache_free_align(mem)
dt_dev_pixelpipe_type_t type
struct dt_develop_t * dev
char fullpath[DT_PATH_MAX]
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)
gboolean dt_tiling_piece_can_save_memory(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, const int in_bpp)
Whether process_tiling() can run this piece in less memory than process() would.
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)
static float _host_tile_buffer_size(const char *op, const dt_develop_tiling_t *tiling, const size_t io_bytes)
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 gboolean _tiling_saves_memory(const dt_develop_tiling_t *tiling, const dt_iop_roi_t *roi_in, const int max_bpp)
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)
Telling the user something happened.