#ifndef __BLI_PARALLEL_H__ #define __BLI_PARALLEL_H__ #ifdef WITH_TBB # define TBB_SUPPRESS_DEPRECATED_MESSAGES 1 # include "tbb/parallel_for.h" # include "tbb/parallel_invoke.h" #endif #include "BLI_index_range.h" #include "BLI_multi_map.h" #include "BLI_string_map.h" #include "BLI_string_multi_map.h" namespace BLI { /** * Call func for every index in the IndexRange. func has to receive a single uint parameter. */ template void parallel_for(IndexRange range, const FuncT &func) { if (range.size() == 0) { return; } #ifdef WITH_TBB tbb::parallel_for(range.first(), range.one_after_last(), func); #else for (uint i : range) { func(i); } #endif } /** * Call func for subranges of range. The size of the individual subranges is controlled by a * grain_size. func has to receive an IndexRange as parameter. */ template void blocked_parallel_for(IndexRange range, uint grain_size, const FuncT &func) { if (range.size() == 0) { return; } #ifdef WITH_TBB tbb::parallel_for( tbb::blocked_range(range.first(), range.one_after_last(), grain_size), [&](const tbb::blocked_range &sub_range) { func(IndexRange(sub_range)); }); #else UNUSED_VARS(grain_size); func(range); #endif } /** * Invoke multiple functions in parallel. */ template void parallel_invoke(const FuncT1 &func1, const FuncT2 &func2) { #ifdef WITH_TBB tbb::parallel_invoke(func1, func2); #else func1(); func2(); #endif } template void parallel_invoke(const FuncT1 &func1, const FuncT2 &func2, const FuncT3 &func3) { #ifdef WITH_TBB tbb::parallel_invoke(func1, func2, func3); #else func1(); func2(); func3(); #endif } template void parallel_map_items(const MultiMap &multi_map, const FuncT &func) { ScopedVector key_vector; ScopedVector> values_vector; multi_map.foreach_item([&](const KeyT &key, ArrayRef values) { key_vector.append(&key); values_vector.append(values); }); parallel_for(key_vector.index_range(), [&](uint index) { const KeyT &key = *key_vector[index]; ArrayRef values = values_vector[index]; func(key, values); }); } template void parallel_map_items(const StringMultiMap &string_multi_map, const FuncT &func) { ScopedVector key_vector; ScopedVector> values_vector; string_multi_map.foreach_item([&](StringRefNull key, ArrayRef values) { key_vector.append(key); values_vector.append(values); }); parallel_for(key_vector.index_range(), [&](uint index) { StringRefNull &key = key_vector[index]; ArrayRef values = values_vector[index]; func(key, values); }); } template void parallel_map_items(const StringMap &string_map, const FuncT &func) { ScopedVector key_vector; ScopedVector value_vector; string_map.foreach_item([&](StringRefNull key, const ValueT &value) { key_vector.append(key); value_vector.append(&value); }); parallel_for(key_vector.index_range(), [&](uint index) { StringRefNull key = key_vector[index]; const ValueT &value = *value_vector[index]; func(key, value); }); } template void parallel_map_keys(const StringMap &string_map, const FuncT &func) { ScopedVector key_vector; string_map.foreach_item( [&](StringRefNull key, const ValueT &UNUSED(value)) { key_vector.append(key); }); parallel_for(key_vector.index_range(), [&](uint index) { StringRefNull key = key_vector[index]; func(key); }); } } // namespace BLI #endif /* __BLI_PARALLEL_H__ */