Open Search
    Parallel Manual

    About

    The static classes maxon::ParallelFor, maxon::ParallelImage and maxon::ParallelInvoke are used to execute parallelized code.

    ParallelFor

    The maxon::ParallelFor class is used to execute code defined in a worker method. This code is executed in a loop distributed over multiple threads. The workload is distributed either dynamically or statically.

    • maxon::ParallelFor::Dynamic(): Runs a parallelized loop using dynamic distribution. This will usually yield the best performance and should be used as a default.
    • maxon::ParallelFor::Static(): Runs a parallelized loop using static distribution. This will usually yield a worse performance than the dynamic distribution and should not be used unless one has to specifically enforce a static distribution.
    // This example calculates an approximation of PI using random numbers.
    // array that stores the inside/outside state for each generated point
    // ParallelFor will write into this array from multiple threads simultaneously
    pointStates.Resize(count) iferr_return;
    auto worker = [&pointStates](maxon::Int i)
    {
    pointStates[i] = false;
    // create random point
    random.Init(maxon::UInt32(i));
    point.x = random.Get01();
    point.y = random.Get01();
    // check if inside circle
    if (point.GetSquaredLength() < 1.0)
    pointStates[i] = true;
    };
    // generate and check random points
    // get pi
    maxon::Int64 insideCount = 0;
    for (const maxon::Bool pointInside : pointStates)
    {
    if (pointInside)
    insideCount++;
    }
    const maxon::Float pi = 4.0 * maxon::Float(insideCount) / maxon::Float(count);
    DiagnosticOutput("PI approximation: @", pi);
    Py_ssize_t i
    Definition: abstract.h:645
    Py_ssize_t count
    Definition: abstract.h:640
    Definition: basearray.h:415
    ResultMem Resize(Int newCnt, COLLECTION_RESIZE_FLAGS resizeFlags=COLLECTION_RESIZE_FLAGS::DEFAULT)
    Definition: basearray.h:1218
    Definition: lib_math.h:19
    FLOAT Get01()
    Returns the next random value in the range of [0..1].
    static auto Dynamic(FROMTYPE from, INDEXTYPE to, const LOOP &obj, const Granularity &granularity=Granularity(), JobQueueInterface *queue=JOBQUEUE_CURRENT, Int deprecatedThrCnt=0) -> decltype(obj(to))
    Definition: parallelfor.h:265
    uint32_t UInt32
    32 bit unsigned integer datatype.
    Definition: apibase.h:202
    Int64 Int
    signed 32/64 bit int, size depends on the platform
    Definition: apibase.h:213
    Float64 Float
    Definition: apibase.h:222
    bool Bool
    boolean type, possible values are only false/true, 8 bit
    Definition: apibase.h:206
    int64_t Int64
    64 bit signed integer datatype.
    Definition: apibase.h:203
    #define DiagnosticOutput(formatString,...)
    Definition: debugdiagnostics.h:170
    #define iferr_return
    Definition: resultbase.h:1524
    A vector consisting of two components X and Y.
    Definition: vec2.h:16
    T y
    Definition: vec2.h:34
    T x
    Definition: vec2.h:33
    constexpr T GetSquaredLength() const
    Returns the squared length of the vector.
    Definition: vec2.h:430

    maxon::ParallelFor::BreakContext is a base class to define a context for maxon::ParallelFor loops that support cancellation. A class based on maxon::ParallelFor::BreakContext stores the data handled in a thread.

    maxon::ParallelFor can call additional "Init" and "Finalize" functions for each thread. The behaviour is defined with these flags:

    // This example calculates an approximation of PI using random numbers.
    // total number inside the unit-circle
    maxon::Int insideCount = 0;
    // data structure
    struct LocalData : public maxon::ParallelFor::BreakContext
    {
    maxon::Int localCount; // number of points inside the unit-circle
    };
    // init thread (called threaded)
    auto init = [](LocalData& context)
    {
    context.localCount = 0;
    };
    // worker
    auto worker = [](maxon::Int i, LocalData& context)
    {
    random.Init(maxon::UInt32(i));
    point.x = random.Get01();
    point.y = random.Get01();
    if (point.GetSquaredLength() < 1.0)
    context.localCount++;
    };
    // finalize thread (called synchronously)
    auto finalize = [&insideCount](LocalData& context)
    {
    // get total number of points inside the unit-circle
    insideCount += context.localCount;
    };
    // run parallel code
    maxon::ParallelFor::Dynamic<LocalData, maxon::PARALLELFORFLAGS::INITTHREADED_FINALIZESYNC>(0, count, init, worker, finalize) iferr_return;
    // get pi
    const maxon::Float pi = 4.0 * maxon::Float(insideCount) / maxon::Float(count);
    DiagnosticOutput("PI approximation: @", pi);
    Context for ParallelFor loops that support cancellation.
    Definition: parallelfor.h:216
    void * context
    Definition: pycapsule.h:49

    ParallelImage

    maxon::ParallelImage is a special class to process image data of a given size per pixel.

    // This example fills a BaseBitmap with an UV color gradient.
    // allocate bitmap
    if (bitmap == nullptr)
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    // define bitmap size
    const maxon::Int width = 1024;
    const maxon::Int height = 1024;
    const IMAGERESULT res = bitmap->Init(width, height, 24);
    return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    // dimensions as float values
    const maxon::Float widthF = maxon::Float(width);
    const maxon::Float heightF = maxon::Float(height);
    auto worker = [widthF, heightF, &bitmap](maxon::Int x, maxon::Int y)
    {
    // get UV coords for the given pixel
    const maxon::Float yf = maxon::Float(y);
    const maxon::Float u = xf / widthF;
    const maxon::Float v = yf / heightF;
    // set colors based on UV coords
    const maxon::Int32 red = maxon::SafeConvert<maxon::Int32>(u * 255.9);
    const maxon::Int32 green = maxon::SafeConvert<maxon::Int32>(v * 255.9);
    const maxon::Int32 blue = 0;
    // store color in the bitmap
    bitmap->SetPixel(Int32(x), Int32(y), red, green, blue);
    };
    // process every pixel of the given bitmap
    maxon::ParallelImage::Process(width, height, 30, worker);
    ShowBitmap(bitmap);
    PyObject PyObject * v
    Definition: abstract.h:297
    Bool ShowBitmap(const Filename &fn)
    Definition: ge_autoptr.h:37
    static void Process(Int width, Int height, Int tileSize, const WORKER &worker)
    Definition: parallelimage.h:216
    PyObject * x
    Definition: bytesobject.h:38
    Py_UCS4 * res
    Definition: unicodeobject.h:1113
    maxon::Int32 Int32
    Definition: ge_sys_math.h:60
    int32_t Int32
    32 bit signed integer datatype.
    Definition: apibase.h:201
    IMAGERESULT
    Definition: ge_prepass.h:3912
    @ OK
    Image loaded/created.
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:67
    unsigned long Py_ssize_t width
    Definition: pycore_traceback.h:88

    ParallelInvoke

    The maxon::ParallelInvoke function can be used to execute multiple arbitrary functions in parallel.

    // This example uses ParallelInvoke() to search for
    // min/max values in two given arrays in parallel.
    // min/max values
    maxon::Float minA = 0.0, maxA = 0.0, minB = 0.0, maxB = 0.0;
    // search for min/max values in the given arrays
    // GetMinMax() is a custom function
    [&arrayA, &minA, &maxA] { GetMinMax(arrayA, minA, maxA); },
    [&araryB, &minB, &maxB] { GetMinMax(araryB, minB, maxB); }
    // check min/max values
    if ((minA > minB) && (maxA < maxB))
    DiagnosticOutput("Min/max values of a array A are within the min/max values of array B"_s);
    Result< void > ParallelInvoke(Bool parallel, ARGS &&... args)
    Definition: parallelinvoke.h:153

    Further Reading