Skip to content

Commit b7288e1

Browse files
authored
Merge pull request #17718 from jenshannoschwalm/pixelpipe_memory
Pixelpipe safety improvements and maintenance
2 parents 0b2dcda + bce9301 commit b7288e1

File tree

8 files changed

+127
-122
lines changed

8 files changed

+127
-122
lines changed

src/common/darktable.c

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,8 +1372,7 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load
13721372
cachedir_from_command,
13731373
tmpdir_from_command);
13741374

1375-
dt_print(DT_DEBUG_MEMORY, "[memory] at startup");
1376-
dt_print_mem_usage();
1375+
dt_print_mem_usage("at startup");
13771376

13781377
char sharedir[PATH_MAX] = { 0 };
13791378
dt_loc_get_sharedir(sharedir, sizeof(sharedir));
@@ -1827,9 +1826,6 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load
18271826
dt_gui_process_events();
18281827
}
18291828

1830-
dt_print(DT_DEBUG_MEMORY, "[memory] after successful startup");
1831-
dt_print_mem_usage();
1832-
18331829
/* init lua last, since it's user made stuff it must be in the real environment */
18341830
#ifdef USE_LUA
18351831
darktable_splash_screen_set_progress(_("initializing Lua"));
@@ -1916,6 +1912,9 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load
19161912

19171913
dt_print(DT_DEBUG_CONTROL,
19181914
"[dt_init] startup took %f seconds", dt_get_wtime() - start_wtime);
1915+
1916+
dt_print_mem_usage("after successful startup");
1917+
19191918
return 0;
19201919
}
19211920

@@ -2482,7 +2481,7 @@ void dt_capabilities_cleanup()
24822481
}
24832482

24842483

2485-
void dt_print_mem_usage()
2484+
void dt_print_mem_usage(char *info)
24862485
{
24872486
if(!(darktable.unmuted & DT_DEBUG_MEMORY))
24882487
return;
@@ -2517,29 +2516,31 @@ void dt_print_mem_usage()
25172516
fclose(f);
25182517

25192518
dt_print(DT_DEBUG_ALWAYS,
2520-
"[memory] max address space (vmpeak): %15s"
2521-
" [memory] cur address space (vmsize): %15s"
2522-
" [memory] max used memory (vmhwm ): %15s"
2523-
" [memory] cur used memory (vmrss ): %15s",
2524-
vmpeak, vmsize, vmhwm, vmrss);
2519+
"[memory] %s\n"
2520+
" max address space (vmpeak): %15s"
2521+
" cur address space (vmsize): %15s"
2522+
" max used memory (vmhwm ): %15s"
2523+
" cur used memory (vmrss ): %15s",
2524+
info, vmpeak, vmsize, vmhwm, vmrss);
25252525

25262526
#elif defined(__APPLE__)
25272527
struct task_basic_info t_info;
25282528
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
25292529

25302530
if(KERN_SUCCESS != task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count))
25312531
{
2532-
dt_print(DT_DEBUG_ALWAYS, "[memory] task memory info unknown.");
2532+
dt_print(DT_DEBUG_ALWAYS, "[memory] task memory info unknown");
25332533
return;
25342534
}
25352535

25362536
// Report in kB, to match output of /proc on Linux.
25372537
dt_print(DT_DEBUG_ALWAYS,
2538-
"[memory] max address space (vmpeak): %15s\n"
2539-
" [memory] cur address space (vmsize): %12llu kB\n"
2540-
" [memory] max used memory (vmhwm ): %15s\n"
2541-
" [memory] cur used memory (vmrss ): %12llu kB",
2542-
"unknown", (uint64_t)t_info.virtual_size / 1024, "unknown", (uint64_t)t_info.resident_size / 1024);
2538+
"[memory] %s\n"
2539+
" max address space (vmpeak): %15s\n"
2540+
" cur address space (vmsize): %12llu kB\n"
2541+
" max used memory (vmhwm ): %15s\n"
2542+
" cur used memory (vmrss ): %12llu kB",
2543+
info, "unknown", (uint64_t)t_info.virtual_size / 1024, "unknown", (uint64_t)t_info.resident_size / 1024);
25432544
#elif defined (_WIN32)
25442545
//Based on: http://stackoverflow.com/questions/63166/how-to-determine-cpu-and-memory-consumption-from-inside-a-process
25452546
MEMORYSTATUSEX memInfo;
@@ -2561,11 +2562,12 @@ void dt_print_mem_usage()
25612562

25622563

25632564
dt_print(DT_DEBUG_ALWAYS,
2564-
"[memory] max address space (vmpeak): %12llu kB\n"
2565-
" [memory] cur address space (vmsize): %12llu kB\n"
2566-
" [memory] max used memory (vmhwm ): %12llu kB\n"
2567-
" [memory] cur used memory (vmrss ): %12llu Kb",
2568-
virtualMemUsedByMeMax / 1024, virtualMemUsedByMe / 1024, physMemUsedByMeMax / 1024,
2565+
"[memory] %s\n"
2566+
" max address space (vmpeak): %12llu kB\n"
2567+
" cur address space (vmsize): %12llu kB\n"
2568+
" max used memory (vmhwm ): %12llu kB\n"
2569+
" cur used memory (vmrss ): %12llu Kb",
2570+
info, virtualMemUsedByMeMax / 1024, virtualMemUsedByMe / 1024, physMemUsedByMeMax / 1024,
25692571
physMemUsedByMe / 1024);
25702572

25712573
#else

src/common/darktable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ static inline gboolean dt_slist_length_equal(GSList *l1, GSList *l2)
884884
}
885885

886886
// checks internally for DT_DEBUG_MEMORY
887-
void dt_print_mem_usage();
887+
void dt_print_mem_usage(char *info);
888888

889889
// try to start the backthumbs crawler
890890
void dt_start_backtumbs_crawler();

src/develop/pixelpipe_cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ void dt_dev_pixelpipe_cache_checkmem(dt_dev_pixelpipe_t *pipe)
459459
}
460460

461461
_cline_stats(cache);
462-
dt_print_pipe(DT_DEBUG_PIPE, "pipe cache check", pipe, NULL, DT_DEVICE_NONE, NULL, NULL,
462+
dt_print_pipe(DT_DEBUG_PIPE | DT_DEBUG_MEMORY, "pipe cache check", pipe, NULL, DT_DEVICE_NONE, NULL, NULL,
463463
"%i lines (important=%i, used=%i). Freed %iMB. Using using %iMB, limit=%iMB",
464464
cache->entries, cache->limportant, cache->lused,
465465
_to_mb(freed), _to_mb(cache->allmem), _to_mb(cache->memlimit));
@@ -470,7 +470,7 @@ void dt_dev_pixelpipe_cache_report(dt_dev_pixelpipe_t *pipe)
470470
dt_dev_pixelpipe_cache_t *cache = &(pipe->cache);
471471

472472
_cline_stats(cache);
473-
dt_print_pipe(DT_DEBUG_PIPE, "cache report", pipe, NULL, DT_DEVICE_NONE, NULL, NULL,
473+
dt_print_pipe(DT_DEBUG_PIPE | DT_DEBUG_MEMORY, "cache report", pipe, NULL, DT_DEVICE_NONE, NULL, NULL,
474474
"%i lines (important=%i, used=%i, invalid=%i). Using %iMB, limit=%iMB. Hits/run=%.2f. Hits/test=%.3f",
475475
cache->entries, cache->limportant, cache->lused, cache->linvalid,
476476
_to_mb(cache->allmem), _to_mb(cache->memlimit),

src/develop/pixelpipe_hb.c

Lines changed: 82 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,17 @@ gboolean dt_dev_pixelpipe_init_cached(dt_dev_pixelpipe_t *pipe,
256256
return dt_dev_pixelpipe_cache_init(pipe, entries, size, memlimit);
257257
}
258258

259-
static void get_output_format(
260-
dt_iop_module_t *module,
261-
dt_dev_pixelpipe_t *pipe,
262-
dt_dev_pixelpipe_iop_t *piece,
263-
dt_develop_t *dev,
264-
dt_iop_buffer_dsc_t *dsc)
259+
size_t dt_get_available_pipe_mem(const dt_dev_pixelpipe_t *pipe)
260+
{
261+
size_t allmem = dt_get_available_mem();
262+
return MAX(1lu * 1024lu * 1024lu, allmem / (pipe->type & DT_DEV_PIXELPIPE_THUMBNAIL ? 3 : 1));
263+
}
264+
265+
static void get_output_format(dt_iop_module_t *module,
266+
dt_dev_pixelpipe_t *pipe,
267+
dt_dev_pixelpipe_iop_t *piece,
268+
dt_develop_t *dev,
269+
dt_iop_buffer_dsc_t *dsc)
265270
{
266271
if(module) return module->output_format(module, pipe, piece, dsc);
267272

@@ -662,15 +667,14 @@ void dt_dev_pixelpipe_usedetails(dt_dev_pixelpipe_t *pipe)
662667
pipe->want_detail_mask = TRUE;
663668
}
664669

665-
static void _dump_pipe_pfm_diff(
666-
const char *mod,
667-
const void *indata,
668-
const dt_iop_roi_t *roi_in,
669-
const int inbpp,
670-
const void *outdata,
671-
const dt_iop_roi_t *roi_out,
672-
const int outbpp,
673-
const char *pipe)
670+
static void _dump_pipe_pfm_diff(const char *mod,
671+
const void *indata,
672+
const dt_iop_roi_t *roi_in,
673+
const int inbpp,
674+
const void *outdata,
675+
const dt_iop_roi_t *roi_out,
676+
const int outbpp,
677+
const char *pipe)
674678
{
675679
if(!darktable.dump_pfm_pipe) return;
676680
if(!mod) return;
@@ -1089,19 +1093,18 @@ static void _collect_histogram_on_CPU(dt_dev_pixelpipe_t *pipe,
10891093
}
10901094
}
10911095

1092-
static gboolean _pixelpipe_process_on_CPU(
1093-
dt_dev_pixelpipe_t *pipe,
1094-
dt_develop_t *dev,
1095-
float *input,
1096-
dt_iop_buffer_dsc_t *input_format,
1097-
const dt_iop_roi_t *roi_in,
1098-
void **output,
1099-
dt_iop_buffer_dsc_t **out_format,
1100-
const dt_iop_roi_t *roi_out,
1101-
dt_iop_module_t *module,
1102-
dt_dev_pixelpipe_iop_t *piece,
1103-
dt_develop_tiling_t *tiling,
1104-
dt_pixelpipe_flow_t *pixelpipe_flow)
1096+
static gboolean _pixelpipe_process_on_CPU(dt_dev_pixelpipe_t *pipe,
1097+
dt_develop_t *dev,
1098+
float *input,
1099+
dt_iop_buffer_dsc_t *input_format,
1100+
const dt_iop_roi_t *roi_in,
1101+
void **output,
1102+
dt_iop_buffer_dsc_t **out_format,
1103+
const dt_iop_roi_t *roi_out,
1104+
dt_iop_module_t *module,
1105+
dt_dev_pixelpipe_iop_t *piece,
1106+
dt_develop_tiling_t *tiling,
1107+
dt_pixelpipe_flow_t *pixelpipe_flow)
11051108
{
11061109
if(dt_atomic_get_int(&pipe->shutdown))
11071110
return TRUE;
@@ -1162,7 +1165,7 @@ static gboolean _pixelpipe_process_on_CPU(
11621165
const size_t m_width = MAX(roi_in->width, roi_out->width);
11631166
const size_t m_height = MAX(roi_in->height, roi_out->height);
11641167

1165-
const gboolean fitting = dt_tiling_piece_fits_host_memory(m_width, m_height, m_bpp, tiling->factor, tiling->overhead);
1168+
const gboolean fitting = dt_tiling_piece_fits_host_memory(piece, m_width, m_height, m_bpp, tiling->factor, tiling->overhead);
11661169
/* process module on cpu. use tiling if needed and possible. */
11671170

11681171
const gboolean pfm_dump = darktable.dump_pfm_pipe
@@ -1330,16 +1333,15 @@ static inline gboolean _skip_piece_on_tags(const dt_dev_pixelpipe_iop_t *piece)
13301333
}
13311334

13321335
// recursive helper for process, returns TRUE in case of unfinished work or error
1333-
static gboolean _dev_pixelpipe_process_rec(
1334-
dt_dev_pixelpipe_t *pipe,
1335-
dt_develop_t *dev,
1336-
void **output,
1337-
void **cl_mem_output,
1338-
dt_iop_buffer_dsc_t **out_format,
1339-
const dt_iop_roi_t *roi_out,
1340-
GList *modules,
1341-
GList *pieces,
1342-
const int pos)
1336+
static gboolean _dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe,
1337+
dt_develop_t *dev,
1338+
void **output,
1339+
void **cl_mem_output,
1340+
dt_iop_buffer_dsc_t **out_format,
1341+
const dt_iop_roi_t *roi_out,
1342+
GList *modules,
1343+
GList *pieces,
1344+
const int pos)
13431345
{
13441346
if(dt_atomic_get_int(&pipe->shutdown))
13451347
return TRUE;
@@ -1917,13 +1919,13 @@ static gboolean _dev_pixelpipe_process_rec(
19171919
&& (cho == 1 || cho == 4)
19181920
&& dt_str_commasubstring(darktable.dump_diff_pipe, module->op))
19191921
{
1920-
const size_t ow = roi_out->width;
1921-
const size_t oh = roi_out->height;
1922-
const size_t iw = roi_in.width;
1923-
const size_t ih = roi_in.height;
1924-
float *clindata = dt_alloc_align_float(iw * ih * ch);
1925-
float *cloutdata = dt_alloc_align_float(ow * oh * cho);
1926-
float *cpudata = dt_alloc_align_float(ow * oh * cho);
1922+
const int ow = roi_out->width;
1923+
const int oh = roi_out->height;
1924+
const int iw = roi_in.width;
1925+
const int ih = roi_in.height;
1926+
float *clindata = dt_alloc_align_float((size_t)iw * ih * ch);
1927+
float *cloutdata = dt_alloc_align_float((size_t)ow * oh * cho);
1928+
float *cpudata = dt_alloc_align_float((size_t)ow * oh * cho);
19271929
if(clindata && cloutdata && cpudata)
19281930
{
19291931
cl_int terr = dt_opencl_read_host_from_device(pipe->devid, cloutdata, *cl_mem_output, ow, oh, cho * sizeof(float));
@@ -2582,14 +2584,13 @@ static gboolean _dev_pixelpipe_process_rec(
25822584
}
25832585

25842586

2585-
gboolean dt_dev_pixelpipe_process_no_gamma(
2586-
dt_dev_pixelpipe_t *pipe,
2587-
dt_develop_t *dev,
2588-
const int x,
2589-
const int y,
2590-
const int width,
2591-
const int height,
2592-
const float scale)
2587+
gboolean dt_dev_pixelpipe_process_no_gamma(dt_dev_pixelpipe_t *pipe,
2588+
dt_develop_t *dev,
2589+
const int x,
2590+
const int y,
2591+
const int width,
2592+
const int height,
2593+
const float scale)
25932594
{
25942595
// temporarily disable gamma mapping.
25952596
GList *gammap = g_list_last(pipe->nodes);
@@ -2638,16 +2639,15 @@ void dt_dev_pixelpipe_disable_before(dt_dev_pixelpipe_t *pipe, const char *op)
26382639
}
26392640

26402641
// returns TRUE in case of error or early exit
2641-
static gboolean _dev_pixelpipe_process_rec_and_backcopy(
2642-
dt_dev_pixelpipe_t *pipe,
2643-
dt_develop_t *dev,
2644-
void **output,
2645-
void **cl_mem_output,
2646-
dt_iop_buffer_dsc_t **out_format,
2647-
const dt_iop_roi_t *roi_out,
2648-
GList *modules,
2649-
GList *pieces,
2650-
const int pos)
2642+
static gboolean _dev_pixelpipe_process_rec_and_backcopy(dt_dev_pixelpipe_t *pipe,
2643+
dt_develop_t *dev,
2644+
void **output,
2645+
void **cl_mem_output,
2646+
dt_iop_buffer_dsc_t **out_format,
2647+
const dt_iop_roi_t *roi_out,
2648+
GList *modules,
2649+
GList *pieces,
2650+
const int pos)
26512651
{
26522652
dt_pthread_mutex_lock(&pipe->busy_mutex);
26532653
darktable.dtresources.group = 4 * darktable.dtresources.level;
@@ -2691,15 +2691,14 @@ static gboolean _dev_pixelpipe_process_rec_and_backcopy(
26912691
return ret;
26922692
}
26932693

2694-
gboolean dt_dev_pixelpipe_process(
2695-
dt_dev_pixelpipe_t *pipe,
2696-
dt_develop_t *dev,
2697-
const int x,
2698-
const int y,
2699-
const int width,
2700-
const int height,
2701-
const float scale,
2702-
const int devid)
2694+
gboolean dt_dev_pixelpipe_process(dt_dev_pixelpipe_t *pipe,
2695+
dt_develop_t *dev,
2696+
const int x,
2697+
const int y,
2698+
const int width,
2699+
const int height,
2700+
const float scale,
2701+
const int devid)
27032702
{
27042703
pipe->processing = TRUE;
27052704
pipe->nocache = (pipe->type & DT_DEV_PIXELPIPE_IMAGE) != 0;
@@ -2713,9 +2712,6 @@ gboolean dt_dev_pixelpipe_process(
27132712
if(!claimed) // don't free cachelines as the caller is using them
27142713
dt_dev_pixelpipe_cache_checkmem(pipe);
27152714

2716-
dt_print(DT_DEBUG_MEMORY, "[memory] before pixelpipe process");
2717-
dt_print_mem_usage();
2718-
27192715
if(pipe->devid > DT_DEVICE_CPU) dt_opencl_events_reset(pipe->devid);
27202716

27212717
dt_iop_roi_t roi = (dt_iop_roi_t){ x, y, width, height, scale };
@@ -2758,9 +2754,13 @@ gboolean dt_dev_pixelpipe_process(
27582754
pipe->image.id,
27592755
darktable.opencl->dev[pipe->devid].cname);
27602756
else
2761-
#endif
27622757
dt_print_pipe(DT_DEBUG_PIPE, "pipe starting", pipe, NULL, pipe->devid, &roi, &roi, "ID=%i",
27632758
pipe->image.id);
2759+
#else
2760+
dt_print_pipe(DT_DEBUG_PIPE, "pipe starting", pipe, NULL, pipe->devid, &roi, &roi, "ID=%i",
2761+
pipe->image.id);
2762+
#endif
2763+
dt_print_mem_usage("before pixelpipe process");
27642764

27652765
// run pixelpipe recursively and get error status
27662766
const gboolean err = _dev_pixelpipe_process_rec_and_backcopy(pipe, dev, &buf,
@@ -2772,10 +2772,9 @@ gboolean dt_dev_pixelpipe_process(
27722772
? (dt_opencl_events_flush(pipe->devid, TRUE) != 0)
27732773
: FALSE;
27742774

2775-
// Check if we had opencl errors,
2776-
// remark: opencl errors can come in two ways:
2777-
// processed pipe->opencl_error checked via 'err'
2778-
// OpenCL events so oclerr is TRUE
2775+
// Check if we had opencl errors, those can come in two ways:
2776+
// processed pipe->opencl_error checked via 'err'
2777+
// OpenCL events so oclerr is TRUE
27792778
const int old_devid = pipe->devid;
27802779
if(oclerr || (err && pipe->opencl_error))
27812780
{
@@ -2874,8 +2873,9 @@ gboolean dt_dev_pixelpipe_process(
28742873
if(!claimed)
28752874
dt_dev_pixelpipe_cache_report(pipe);
28762875

2877-
dt_print_pipe(DT_DEBUG_PIPE, "pipe finished", pipe, NULL, old_devid, &roi, &roi, "ID=%i\n",
2876+
dt_print_pipe(DT_DEBUG_PIPE, "pipe finished", pipe, NULL, old_devid, &roi, &roi, "ID=%i",
28782877
pipe->image.id);
2878+
dt_print_mem_usage("after pixelpipe process");
28792879

28802880
pipe->processing = FALSE;
28812881
return FALSE;

src/develop/pixelpipe_hb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ gboolean dt_dev_pixelpipe_init_cached(dt_dev_pixelpipe_t *pipe,
231231
const size_t size,
232232
const int32_t entries,
233233
const size_t memlimit);
234+
// returns available memory for the pipe
235+
size_t dt_get_available_pipe_mem(const dt_dev_pixelpipe_t *pipe);
234236
// constructs a new input buffer from given RGB float array.
235237
void dt_dev_pixelpipe_set_input(dt_dev_pixelpipe_t *pipe,
236238
struct dt_develop_t *dev,

0 commit comments

Comments
 (0)