Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallelisation for functors #3596

Draft
wants to merge 14 commits into
base: develop
Choose a base branch
from
10 changes: 10 additions & 0 deletions Verovio.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,10 @@
E76046C128D4829000C36204 /* calcledgerlinesfunctor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E76046BF28D4829000C36204 /* calcledgerlinesfunctor.cpp */; };
E76046C228D496B300C36204 /* calcledgerlinesfunctor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E76046BF28D4829000C36204 /* calcledgerlinesfunctor.cpp */; };
E76046C328D496B400C36204 /* calcledgerlinesfunctor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E76046BF28D4829000C36204 /* calcledgerlinesfunctor.cpp */; };
E7605A2E2B6EF47E00903A6A /* functor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E7605A2D2B6EF47E00903A6A /* functor.cpp */; };
E7605A2F2B6EF47E00903A6A /* functor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E7605A2D2B6EF47E00903A6A /* functor.cpp */; };
E7605A302B6EF47E00903A6A /* functor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E7605A2D2B6EF47E00903A6A /* functor.cpp */; };
E7605A312B6EF47E00903A6A /* functor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E7605A2D2B6EF47E00903A6A /* functor.cpp */; };
E763EF3F29E939C00029E56D /* convertfunctor.h in Headers */ = {isa = PBXBuildFile; fileRef = E763EF3E29E939C00029E56D /* convertfunctor.h */; };
E763EF4029E939C00029E56D /* convertfunctor.h in Headers */ = {isa = PBXBuildFile; fileRef = E763EF3E29E939C00029E56D /* convertfunctor.h */; settings = {ATTRIBUTES = (Public, ); }; };
E763EF4229E939FB0029E56D /* convertfunctor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E763EF4129E939FB0029E56D /* convertfunctor.cpp */; };
Expand Down Expand Up @@ -2206,6 +2210,7 @@
E75EA9FC29CC3A88003A97A7 /* calcarticfunctor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = calcarticfunctor.cpp; path = src/calcarticfunctor.cpp; sourceTree = "<group>"; };
E76046BC28D4828200C36204 /* calcledgerlinesfunctor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = calcledgerlinesfunctor.h; path = include/vrv/calcledgerlinesfunctor.h; sourceTree = "<group>"; };
E76046BF28D4829000C36204 /* calcledgerlinesfunctor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = calcledgerlinesfunctor.cpp; path = src/calcledgerlinesfunctor.cpp; sourceTree = "<group>"; };
E7605A2D2B6EF47E00903A6A /* functor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = functor.cpp; path = src/functor.cpp; sourceTree = "<group>"; };
E763EF3E29E939C00029E56D /* convertfunctor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = convertfunctor.h; path = include/vrv/convertfunctor.h; sourceTree = "<group>"; };
E763EF4129E939FB0029E56D /* convertfunctor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = convertfunctor.cpp; path = src/convertfunctor.cpp; sourceTree = "<group>"; };
E765675828BBFBA400BC6490 /* functorinterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = functorinterface.h; path = include/vrv/functorinterface.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3036,6 +3041,7 @@
E74A806528BC97D5005274E7 /* findfunctor.h */,
E722106528F856C4002CD6E9 /* findlayerelementsfunctor.cpp */,
E722106228F8569F002CD6E9 /* findlayerelementsfunctor.h */,
E7605A2D2B6EF47E00903A6A /* functor.cpp */,
E765675B28BC019F00BC6490 /* functor.h */,
E74A806828BC9842005274E7 /* functorinterface.cpp */,
E765675828BBFBA400BC6490 /* functorinterface.h */,
Expand Down Expand Up @@ -4153,6 +4159,7 @@
4DEC4D9721C81E3B00D1D273 /* expan.cpp in Sources */,
4D766EFF20ACAD6D006875D8 /* neume.cpp in Sources */,
4D1694581E3A44F300569BF4 /* accid.cpp in Sources */,
E7605A2F2B6EF47E00903A6A /* functor.cpp in Sources */,
4DACC9912990F29A00B55913 /* atts_critapp.cpp in Sources */,
4D1694591E3A44F300569BF4 /* custos.cpp in Sources */,
4D16945A1E3A44F300569BF4 /* dot.cpp in Sources */,
Expand Down Expand Up @@ -4430,6 +4437,7 @@
4DC34BA819BC4A83006175CD /* accid.cpp in Sources */,
4DC34BAA19BC4A83006175CD /* custos.cpp in Sources */,
4D7927D020ECCC6D0002A45D /* view_slur.cpp in Sources */,
E7605A2E2B6EF47E00903A6A /* functor.cpp in Sources */,
4D81351E2322C41800F59C01 /* keyaccid.cpp in Sources */,
BD2E4D95287587FD00B04350 /* stem.cpp in Sources */,
E77C198328CD31AD00F5BADA /* calcdotsfunctor.cpp in Sources */,
Expand Down Expand Up @@ -4720,6 +4728,7 @@
4DC34BAD19BC4A83006175CD /* dot.cpp in Sources */,
4D2073FD22A3BCE000E0765F /* tabgrp.cpp in Sources */,
4D7927D220ECCC6D0002A45D /* view_slur.cpp in Sources */,
E7605A302B6EF47E00903A6A /* functor.cpp in Sources */,
4DACC9922990F29A00B55913 /* atts_critapp.cpp in Sources */,
4DB3D8B91F83D0C600B5FC2B /* systemmilestone.cpp in Sources */,
4D2073FA22A3BCE000E0765F /* tabdursym.cpp in Sources */,
Expand Down Expand Up @@ -5004,6 +5013,7 @@
BB4C4B7F22A932DF001F6AF0 /* fb.cpp in Sources */,
BB4C4BA322A932E5001F6AF0 /* textdirinterface.cpp in Sources */,
BB4C4B3922A932CF001F6AF0 /* turn.cpp in Sources */,
E7605A312B6EF47E00903A6A /* functor.cpp in Sources */,
4DACC9932990F29A00B55913 /* atts_critapp.cpp in Sources */,
BB4C4BA122A932E5001F6AF0 /* scoredefinterface.cpp in Sources */,
BB4C4B4322A932D7001F6AF0 /* beatrpt.cpp in Sources */,
Expand Down
9 changes: 9 additions & 0 deletions include/vrv/adjustslursfunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ class AdjustSlursFunctor : public DocFunctor {
*/
bool ImplementsEndInterface() const override { return false; }

/*
* Enable parallelization
*/
///@{
ProcessingStrategy GetProcessingStrategy() const override { return ProcessingStrategy::SystemParallel; }
AdjustSlursFunctor *CloneFunctor() const override { return new AdjustSlursFunctor(*this); }
void MergeFunctor(const Functor *functor) override;
///@}

/*
* Check existence of cross-staff slurs
*/
Expand Down
8 changes: 8 additions & 0 deletions include/vrv/calcbboxoverflowsfunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ class CalcBBoxOverflowsFunctor : public DocFunctor {
*/
bool ImplementsEndInterface() const override { return true; }

/*
* Enable parallelization
*/
///@{
ProcessingStrategy GetProcessingStrategy() const override { return ProcessingStrategy::SystemParallel; }
CalcBBoxOverflowsFunctor *CloneFunctor() const override { return new CalcBBoxOverflowsFunctor(*this); }
///@}

/*
* Functor interface
*/
Expand Down
8 changes: 8 additions & 0 deletions include/vrv/calcdotsfunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ class CalcDotsFunctor : public DocFunctor {
*/
bool ImplementsEndInterface() const override { return false; }

/*
* Enable parallelization
*/
///@{
ProcessingStrategy GetProcessingStrategy() const override { return ProcessingStrategy::MeasureParallel; }
CalcDotsFunctor *CloneFunctor() const override { return new CalcDotsFunctor(*this); }
///@}

/*
* Functor interface
*/
Expand Down
8 changes: 8 additions & 0 deletions include/vrv/calcstemfunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ class CalcStemFunctor : public DocFunctor {
*/
bool ImplementsEndInterface() const override { return false; }

/*
* Enable parallelization
*/
///@{
ProcessingStrategy GetProcessingStrategy() const override { return ProcessingStrategy::MeasureParallel; }
CalcStemFunctor *CloneFunctor() const override { return new CalcStemFunctor(*this); }
///@}

/*
* Functor interface
*/
Expand Down
55 changes: 55 additions & 0 deletions include/vrv/functor.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#ifndef __VRV_FUNCTOR_H__
#define __VRV_FUNCTOR_H__

#include <optional>

//----------------------------------------------------------------------------

#include "comparison.h"
#include "functorinterface.h"
#include "vrvdef.h"
Expand All @@ -16,6 +20,9 @@ namespace vrv {

class Doc;

// Helper enum classes
enum class ProcessingStrategy { Sequential, MeasureParallel, SystemParallel };

//----------------------------------------------------------------------------
// FunctorBase
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -76,6 +83,20 @@ class FunctorBase {
*/
virtual bool ImplementsEndInterface() const = 0;

/**
* Override to enable parallel functor processing
*/
///@{
virtual ProcessingStrategy GetProcessingStrategy() const { return ProcessingStrategy::Sequential; }
virtual int GetMaxNumberOfThreads() const { return 1; }
///@}

/**
* Returns the object class on which parallelization is applied
* Additionally checks if we have more than one thread
*/
std::optional<ClassId> GetConcurrentClass() const;

private:
//
public:
Expand Down Expand Up @@ -108,6 +129,18 @@ class Functor : public FunctorBase, public FunctorInterface {
virtual ~Functor() = default;
///@}

/**
* Copy child classes
* Must be overridden in order to use it (e.g. during parallelization)
*/
virtual Functor *CloneFunctor() const;

/**
* Merge child classes, i.e. combine the state of the functor passed in with the current one
* The default implementation only considers the functor code
*/
virtual void MergeFunctor(const Functor *functor);

private:
//
public:
Expand All @@ -133,6 +166,18 @@ class ConstFunctor : public FunctorBase, public ConstFunctorInterface {
virtual ~ConstFunctor() = default;
///@}

/**
* Copy child classes
* Must be overridden in order to use it (e.g. during parallelization)
*/
virtual ConstFunctor *CloneFunctor() const;

/**
* Merge child classes, i.e. combine the state of the functor passed in with the current one
* The default implementation only considers the functor code
*/
virtual void MergeFunctor(const ConstFunctor *functor);

private:
//
public:
Expand Down Expand Up @@ -163,6 +208,11 @@ class DocFunctor : public Functor {
*/
Doc *GetDoc() { return m_doc; }

/*
* Get the maximal number of threads
*/
int GetMaxNumberOfThreads() const final;

private:
//
public:
Expand Down Expand Up @@ -197,6 +247,11 @@ class DocConstFunctor : public ConstFunctor {
*/
const Doc *GetDoc() const { return m_doc; }

/*
* Get the maximal number of threads
*/
int GetMaxNumberOfThreads() const final;

private:
//
public:
Expand Down
4 changes: 4 additions & 0 deletions include/vrv/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,11 @@ class Object : public BoundingBox {
*/
///@{
void Process(Functor &functor, int deepness = UNLIMITED_DEPTH, bool skipFirst = false);
void ProcessChildren(Functor &functor, int deepness);
void ProcessInParallel(Functor &functor, int deepness, const ArrayOfObjects &objects);
void Process(ConstFunctor &functor, int deepness = UNLIMITED_DEPTH, bool skipFirst = false) const;
void ProcessChildren(ConstFunctor &functor, int deepness) const;
void ProcessInParallel(ConstFunctor &functor, int deepness, const ArrayOfConstObjects &objects) const;
///@}

/**
Expand Down
1 change: 1 addition & 0 deletions include/vrv/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,7 @@ class Options {
OptionBool m_incip;
OptionBool m_justifyVertically;
OptionBool m_landscape;
OptionInt m_maxThreads;
OptionDbl m_minLastJustification;
OptionBool m_mmOutput;
OptionBool m_moveScoreDefinitionToStaff;
Expand Down
19 changes: 19 additions & 0 deletions include/vrv/resetfunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ class ResetHorizontalAlignmentFunctor : public Functor {
*/
bool ImplementsEndInterface() const override { return false; }

/*
* Enable parallelization
*/
///@{
ProcessingStrategy GetProcessingStrategy() const override { return ProcessingStrategy::MeasureParallel; }
ResetHorizontalAlignmentFunctor *CloneFunctor() const override
{
return new ResetHorizontalAlignmentFunctor(*this);
}
///@}

/*
* Functor interface
*/
Expand Down Expand Up @@ -167,6 +178,14 @@ class ResetVerticalAlignmentFunctor : public Functor {
*/
bool ImplementsEndInterface() const override { return false; }

/*
* Enable parallelization
*/
///@{
ProcessingStrategy GetProcessingStrategy() const override { return ProcessingStrategy::MeasureParallel; }
ResetVerticalAlignmentFunctor *CloneFunctor() const override { return new ResetVerticalAlignmentFunctor(*this); }
///@}

/*
* Functor interface
*/
Expand Down
10 changes: 10 additions & 0 deletions src/adjustslursfunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ AdjustSlursFunctor::AdjustSlursFunctor(Doc *doc) : DocFunctor(doc)
this->ResetCurrent();
}

void AdjustSlursFunctor::MergeFunctor(const Functor *functor)
{
Functor::MergeFunctor(functor);

const AdjustSlursFunctor *adjustSlursFunctor = dynamic_cast<const AdjustSlursFunctor *>(functor);
if (adjustSlursFunctor && adjustSlursFunctor->HasCrossStaffSlurs()) {
m_crossStaffSlurs = true;
}
}

void AdjustSlursFunctor::ResetCurrent()
{
m_currentCurve = NULL;
Expand Down
84 changes: 84 additions & 0 deletions src/functor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/////////////////////////////////////////////////////////////////////////////
// Name: functor.cpp
// Author: David Bauer
// Created: 2024
// Copyright (c) Authors and others. All rights reserved.
/////////////////////////////////////////////////////////////////////////////

#include "functor.h"

//----------------------------------------------------------------------------

#include "doc.h"

namespace vrv {

//----------------------------------------------------------------------------
// FunctorBase
//----------------------------------------------------------------------------

std::optional<ClassId> FunctorBase::GetConcurrentClass() const
{
if (this->GetMaxNumberOfThreads() > 1) {
switch (this->GetProcessingStrategy()) {
case ProcessingStrategy::MeasureParallel: return MEASURE;
case ProcessingStrategy::SystemParallel: return SYSTEM;
default: break;
}
}
return std::nullopt;
}

//----------------------------------------------------------------------------
// Functor
//----------------------------------------------------------------------------

Functor *Functor::CloneFunctor() const
{
assert(false);
return NULL;
}

void Functor::MergeFunctor(const Functor *functor)
{
if (functor->GetCode() == FUNCTOR_STOP) {
this->SetCode(FUNCTOR_STOP);
}
}

//----------------------------------------------------------------------------
// ConstFunctor
//----------------------------------------------------------------------------

ConstFunctor *ConstFunctor::CloneFunctor() const
{
assert(false);
return NULL;
}

void ConstFunctor::MergeFunctor(const ConstFunctor *functor)
{
if (functor->GetCode() == FUNCTOR_STOP) {
this->SetCode(FUNCTOR_STOP);
}
}

//----------------------------------------------------------------------------
// DocFunctor
//----------------------------------------------------------------------------

int DocFunctor::GetMaxNumberOfThreads() const
{
return m_doc->GetOptions()->m_maxThreads.GetValue();
}

//----------------------------------------------------------------------------
// DocConstFunctor
//----------------------------------------------------------------------------

int DocConstFunctor::GetMaxNumberOfThreads() const
{
return m_doc->GetOptions()->m_maxThreads.GetValue();
}

} // namespace vrv
Loading
Loading