Actes JFPC 2013 Une adaptation simple et efficace du modèle MapReduce pour la programmation par contraintes Jean-Charles Régin Mohamed Rezgui Arnaud Malapert Université Nice-Sophia Antipolis I3S UMR 6070, CNRS, France. {Jean-Charles.REGIN,Arnaud.Malapert}@unice.fr, rezgui@i3s.unice.fr Résumé Nous proposons MapReduceCP, une méthode simple et efficace pour résoudre les problèmes de programmation par contraintes en parallèle. Au lieu d utiliser l approche classique basée sur le work stealing, nous adaptons le modèle MapReduce à la décomposition de l espace de recherche. Nous découpons le problème initial en un grand nombre de sousproblèmes distincts puis nous les résolvons de façon dynamique avec les workers disponibles (les cœurs des machines). Les expériences avec les problèmes de satisfaction et les problèmes d optimisation suggèrent de fixer à trente, le nombre de sous-problèmes non détectés inconsistants par worker afin d obtenir un bon passage à l échelle. Nous montrons que notre méthode est très compétitive avec l approche work stealing et qu elle est capable de résoudre certains problèmes classiques avec la capacité maximale des machines multi-cœurs. Grâce à cette méthode, l utilisateur peut paralléliser la résolution d un problème sans modifier le solveur ou écrire de code source parallèle. 1 Introduction Il existe principalement deux manières de paralléliser un solveur de programmation par contraintes. D une part, les algorithmes de filtrage (ou la propagation) sont parallélisés ou distribués. Le travail le plus remarquable sur ce sujet a été réalisé par Y. Hamadi [6]. D autre part, le processus de recherche est parallélisé. Nous focalisons notre attention sur cette méthode. Pour une description plus complète des méthodes qui ont été testées pour l utilisation d un solveur CP en parallèle, le lecteur peut se référer à l étude de Gent et al. [5]. Lorsque nous voulons utiliser k machines pour la résolution d un problème, nous pouvons découper le problème initial en k sous-problèmes disjoints et donner un sous-problème à chaque machine. Nous appelons cette méthode : méthode de décomposition statique simple. Ensuite, nous recueillons les différents résultats afin de produire des résultats correspondant à l ensemble du problème. L avantage de cette méthode est sa simplicité. Malheureusement, il souffre de plusieurs inconvénients qui surviennent fréquemment dans la pratique : les temps passés à résoudre chaque sous-problème sont rarement bien équilibrés. Afin d équilibrer les sous-problèmes qui doivent être résolus, certains travaux ont été réalisés sur la décomposition de l arbre de recherche [9, 3, 8]. Toutefois, la taille des arbres est approximative et n est pas strictement corrélée avec le temps de résolution. Ainsi, comme mentionné par Bordeaux et al. [1], il est assez difficile de s assurer que chaque worker recevra la même quantité de travail. Par conséquent, cette méthode souffre de quelques problèmes de passage à l échelle, car le temps de résolution est le maximum du temps de résolution de chaque worker. Afin de remédier à ces problèmes, une autre approche a été proposée et est actuellement plus populaire : l idée du work stealing. Le work stealing est assez simple : les workers résolvent une partie des problèmes et quand un worker entre en phase de famine, il "vole" un peu de travail d un autre worker. Habituellement, il est mis en œuvre comme suit : quand un worker W n a plus de travail, il demande à un autre worker V s il a du travail à lui donner. Si la réponse est positive, alors le worker V découpe le problème qu il résout actuellement en deux sous-problèmes et en donne un des deux au worker W. Si la réponse est négative, alors W demande à un autre worker U, jusqu à ce qu il arrive à avoir un travail à faire ou que tous les autres workers ont été considérés. Cette méthode a été mise en œuvre dans un grand
nombre de solveurs (Comet [10] ou ILOG Solver [12] par exemple), et de plusieurs manières [14, 7, 16, 2] en fonction du fait que le travail à faire est centralisé ou non, du découpage de l arbre de recherche, ou de la méthode de communication entre les workers. L approche work stealing résout en partie le problème d équilibrage de la méthode de décomposition statique simple, principalement parce que la décomposition est dynamique. Par conséquent, il n est pas nécessaire d être en mesure de découper un problème en plusieurs parties équilibrées. Cependant, tous les sous-problèmes donnés à un autre worker ne sont pas égaux. Quand un worker est affamé, il doit éviter de voler trop de problèmes faciles, car dans ce cas, il devra demander un autre travail presque immédiatement. Cela se produit fréquemment à la fin de la recherche lorsqu un grand nombre de workers n ont pas de problèmes à résoudre et demandent tout le temps du travail et donc cela complexifie et ralentit la fin de la recherche en augmentant le temps de communication entre les workers. Ainsi, nous observons généralement que la méthode obtient un bon passage à l échelle pour un petit nombre de workers mais qu il est difficile de maintenir un gain linéaire lorsque le nombre de workers devient plus grand (certaines méthodes ont été développées pour tenter d augmenter ce passage à l échelle[15]). Dans cet article, nous proposons une autre méthode proche de la méthode de décomposition statique simple en utilisant les principes de la méthode MapReduce. Lorsque nous avons k workers, au lieu d essayer de découper le problème en k sous-parties équivalentes, nous proposons de découper le problème dans un grand nombre de sous-problèmes, par exemple 30k sous-problèmes, puis de donner successivement et de façon dynamique ces sousproblèmes aux workers lorsque ces derniers ont besoin de travail. Au lieu d attendre d avoir des sous-problèmes équivalents, nous nous attendons à ce que pour chaque worker, la somme des temps de résolution de ses sous-problèmes doit être équivalente. Ainsi, l idée n est pas de décomposer à priori le problème initial en un ensemble de problèmes équivalents, mais de décomposer le problème initial en un ensemble de sous-problèmes dont le temps de résolution peut être partagé d une manière équivalente par un ensemble de workers. Notez que nous ne savons pas à l avance les sous-problèmes qui seront résolus par worker, car c est déterminé de manière dynamique. Tous les sousproblèmes sont mis dans une file d attente et un worker prend un sous-problème dans cette file lorsqu il a besoin de travailler. La décomposition en sous-problèmes doit être fait avec soin. Nous ne devons pas définir un sous-problème si ce sous-problème aurait été éliminé par le mécanisme de propagation du solveur dans une recherche séquentielle. Ainsi,nous générons seulement les problèmes qui ne sont pas détéctés inconsistants par le solveur. Le papier est organisé comme suit. Nous rappelons d abord quelques principes sur la méthode MapReduce et les facteurs qui peuvent influer sur la parallélisation de l arbre de recherche. Puis, nous introduisons notre méthode, MapReduceCP, pour décomposer les problèmes initiaux. Ensuite, nous donnons des résultats expérimentaux. Enfin, nous concluons. 2 Préliminaires MapReduce est un modèle de programmation pour le traitement de grands ensembles de données, et également le nom d une implémentation du modèle par Google [4]. Il s agit d un cadre pour le traitement des problèmes massivement parallèles à travers les très grands ensembles de données utilisés par un grand nombre d ordinateurs. Ici, nous ne sommes pas intéressés par les détails du MapReduce, mais par ses principes. MapReduce a deux étapes : une étape Map et une étape Reduce : l étape Map : le nœud maître prend le problème initial, le découpe en petits sous-problèmes, et les distribue aux nœuds esclaves. Un nœud esclave peut le faire à nouveau à son tour, conduisant à une structure d arbre à niveaux multiples. Le nœud esclave traite le problème plus petit, et passe la réponse à son nœud maître. L étape Reduce : le nœud maître recueille ensuite les réponses de tous les sous-problèmes et les combine d une certaine manière pour former la sortie, qui correspond à la réponse au problème initial. Dans cet article, nous représentons l espace de recherche comme l immense ensemble de données du modèle MapReduce. Deux facteurs peuvent influer sur le rendement de la parallélisation de la recherche d un solveur (pas nécessairement un solveur CP) basée sur une méthode de décomposition, comme la décomposition statique simple, ou le work stealing, ou encore MapReduce. Nous considérons une partition d un problème P en un ensemble S de sousproblèmes. Si la somme du temps de résolution des sousproblèmes de S est plus grande que le temps de résolution de P, alors il sera difficile de passer à l échelle en fonction du nombre de workers. Cela peut arriver dans certains cas : la stratégie de recherche utilisée est basée sur les calculs précédents. Les expériences que nous avons effectuées ne montrent pas un tel comportement avec un solveur CP. Cependant, nous les avons constaté dans certains cas, avec un solveur MIP. Les temps de résolution de certains sous-problèmes de S sont courts ou bien vraiment plus courts que les autres. Toute méthode doit être en mesure de minimiser les communications et doit équilibrer l activité des workers. Les temps de résolution courts signifient que les workers doivent souvent demander du travail,
ce qui augmente les temps de communication. D autre part, si seulement quelques sous-problèmes requièrent des temps plus longs alors que la plupart d entre eux sont faciles, alors il peut être difficile d équilibrer la charge de chaque worker. 3 Décomposition de problème Dans cette partie, nous calculons S, une partition de sous-problèmes d un problème initial P. 3.1 Principes Nous avons vu que la décomposition du problème initial dans le même nombre de sous-problèmes que le nombre de workers peut causer des temps de résolution déséquilibrés pour chaque sous-problème. Ainsi, notre idée est d augmenter fortement le nombre de sous-problèmes considérés, d une manière similaire à celle de la méthode MapReduce. Aussi, nous définissons un nœud maître qui est en charge de la création et l envoi des sous-problèmes, en d autres termes de l opération Map. Ce nœud maître va également récupérer les calculs effectués par les workers, c est à dire de l opération Reduce. Avant d entrer dans les détails sur la mise en œuvre, nous établissons certaines propriétés. Durant la résolution d un problème, nous appellerons : le temps d activité d un worker la somme des temps de résolution d un worker. le temps d inactivité d un worker la différence entre le temps écoulé pour résoudre le problème en entier et les temps d activité des workers. Notre approche est principalement basée par la remarque suivante : Remarque Les temps d activités de tous les workers peuvent être bien équilibrés, même si le temps de résolution de chaque sous-problème n est pas bien équilibré Lorsqu un worker résout plusieurs sous-problèmes, ces derniers peuvent avoir des temps de résolution différents alors que la somme des ces temps reste égale à une valeur donnée. Considérons un problème dont le temps de résolution est de 100 secondes. Ce problème peut être découpé en sous-problèmes ayant des temps de résolution non balancés : 25, 20, 15, 10, 10, 10, 5, 5 secondes. Avec 4 workers, la répartition de charge pourrait être 25, 20 + 5, 15 + 10, 10 + 10 + 5, ce qui la rend bien balancée. La principale difficulté d une décomposition statique n est pas de définir des problèmes équivalents, mais d éviter d avoir des workers actifs pendant que d autres ont terminã c leur travail. Nous n avons pas besoin de connaître à l avance le temps de résolution de chaque sousproblème. Nous espérons juste que les workers auront des temps d activité équivalents. Pour atteindre cet objectif, il est important de décomposer les problèmes initiaux en un grand nombre de sous-problèmes pour trois raisons. nous augmentons ainsi nos chances d obtenir des temps d activités bien équilibrés pour les workers, car nous augmentons nos chances d être en mesure d obtenir une combinaison de valeurs menant à la même période d activité pour chaque worker. lorsque l espace de recherche tend à ne pas être équilibré, nous aurons des sous-problèmes qui prendront plus de temps à être résolus. En ayant un grand nombre de sousproblèmes, nous augmentons nos chances de découper ces sous-problèmes en plusieurs parties ayant des temps de résolution comparables et ainsi d obtenir à la fin une répartition de charge bien équilibrée des workers. quand un sous-problème a un temps de résolution plus long que n importe quel autre problème, nous avons une chance de voir cette différence moins importante lorsque ce sous-problème est découpé en plusieurs sousproblèmes. Dans ce cas, nous pouvons espérer réduire l importance du sous-problème. Considérons un problème qui nécessite 140 secondes à résoudre et que nous ayons 4 workers. Si nous divisons le problème en 4 sous-problèmes alors nous avons les temps de résolution suivants : 20, 80, 20, 20. Nous aurons besoin de 80 secondes pour résoudre ces sous-problèmes en parallèle. Par conséquent, nous gagnons un facteur 140/80 = 1.75. Maintenant, si nous séparons à nouveau chaque sous-problème en 4 sousproblèmes, nous pourrons obtenir les sous-problèmes suivants représentés par leurs temps de résolution : (5+5+5+5)+(20, 10, 10, 40)+(2, 5, 10, 3)+(2, 2, 8, 8). Dans ce cas, nous pourrons avoir les assignements suivants : "worker1" : 5 + 20 + 2 + 8 = 35 ; "worker2" : 5+10+2+10 = 27 ; "worker3" : 5+10+5+3+2+8 = 33 and "worker4" : 5 + 40 = 45. Le temps écoulé est maintenant à 45 secondes et nous obtenons un facteur de gain à 140/45 = 3.1. En découpant encore les sous-problèmes, nous réduirons le temps de résolution moyen des sousproblèmes et nous espérons couper le sous-problème prenant 40 secondes en des sous-probllèmes prenant moins de temps. Notons que nous avons seulement peu de chance d augmenter le temps écoulé en décomposant plus le sous-problème. Propriété 1 Si un problème est découpé en plusieurs sous-problèmes dont le temps de résolution maximum est tmax, alors (i) le temps de résolution minimum du problème en entier est tmax (ii) le temps d inactivité maximum du worker est inférieur ou égal à tmax. preuve : (i) est clair. (ii) Supposons qu un worker W ait un temps d inactivité qui est supérieur à tmax.
Considérons le moment où W commence à attendre après son temps d activité. À ce moment, il n y a plus de sous-problèmes disponibles à résoudre, autrement W aurait été actif. De plus, un autre worker était déjà en charge du sous-problème le plus long à résoudre ou bien ce dernier a déjà été résolu. Ainsi, la durée maximale de la résolution de cet autre worker est inférieure à tmax. L approche work stealing a un contrôle précis et dynamique sur la façon dont l arbre de recherche est exploré et partagé. Cependant, notre méthode peut conduire à des résultats équivalents : Propriété 2 Il existe une décomposition du problème initial en sous-problèmes, qui est aussi bon que celui de n importe quelle méthode de work stealing. preuve : l approche work stealing est juste une décomposition dynamique, et nous pouvons utiliser cette décomposition dans notre méthode. Un avantage intéressant de notre méthode dans la pratique, est que nous pouvons tout simplement rejouer une résolution en parallèle en sauvegardant l ordre dans lequel les sous-problèmes ont été exécutées. Cela ne coûte presque rien et c est très utile dans le débogage d applications. Dans la section suivante, nous considérons diverses façons possibles pour définir les sous-problèmes. 3.2 Génération des sous-problèmes Même si ce n est pas vraiment important d avoir des sous-problèmes équivalents, il est généralement préférable d avoir des problèmes correspondant à la même taille de l espace de recherche. Cela ne signifie pas qu ils auront le même temps de résolution, mais il est recommandé d avoir de l homogénéité dans les problèmes générés. Supposons que nous voulions découper un problème en q problèmes disjoints. Une méthode simple peut être définie par la manière suivante : nous considérons tout ordre de variables x 1,...,x n. nous définissons par A k le produit cartésien D(x 1 )... D(x k ). nous calculons la valeur k de telle sorte que A k 1 < q A k. Chaque assignement de A k définit un sousproblème et donc A k est la décomposition recherché. Cette méthode fonctionne bien pour certains problèmes tels que les n-reines ou la règle de Golomb, mais elle est très mauvaise pour d autres problèmes, parce qu un grand nombre d assignements de A peut se révéler être trivialement inconsistant. Considérons par exemple que x 1, x 2 et x 3 possèdent trois valeurs {a, b, c} dans leurs domaines et qu on applique une contrainte alldiff sur ces trois variables. Le produit cartésien de domaines de ces variables contiennent 27 tuples. Parmi eux seulement 6 ((a, b, c), (a, c, b), (b, a, c),(b, c, a),(c, a, b), (c, b, a)) qui ne sont pas inconsistants avec la contrainte alldiff. Ainsi, seulement 6/27 = 2/9 des problèmes générés ne sont pas trivialement inconsistants. C est important de noter que la plupart des problèmes inconsistants pourrait ne jamais être considérée par une résolution séquentielle. Pour certains problèmes, nous observons que plus de 99% des problèmes générés sont détéctés inconsistants en lançant le mécanisme de propagation. Ainsi, nous présentons une autre méthode qui évite de tomber dans ce cas. Nous proposons de générer seulement les sousproblèmes qui ne sont pas détectés inconsistants par la propagation. Nous les appelons des sous-problèmes NDI. La génération de ces q sous-problèmes devient plus complexe car le nombre de sous-problèmes NDI peut ne pas être lié au produit catésien de certaines domaines. Un algorithme simple pourrait consister à effecturer un parcours en largeur (BFS), dans l arbre de recherche jusqu à que le nombre de sous-problèmes NDI désiré est atteint. Malheureusement, c est n est pas facile d exécuter efficacement une BFS en général car une BFS n est pas un algorithme incrémental comme un parcours en profondeur (DFS). Par conséquent, nous proposons d utiliser un parcours en profondeur bornée Depth-bounded Depth First Search (DBDFS) en anglais, qui est une DFS qui ne visite jamais les nœuds situés à une profondeur supérieure à une valeur donnée. Chaque branche d un arbre de recherche calculée par cette recherche définit un assignement. Nous noterons NDI k, l ensemble des assignements calculés pour une profondeur k. Pour générer q sous-problèmes, nous répétons la DBDFS jusqu à que nous atteignons un niveau k de telle sorte que NDI k 1 < q NDI k. Pour plus de commodité et de simplicité, nous utilisons un ordre statique des variables. Nous améliorons cette méthode de trois façons : (i) nous essayons d estimer quelques bonnes valeurs pour k afin d éviter de très répéter l algorithme DBDFS. Nous utilisons le produit cartésien. Par exemple, si pour une profondeur donnée u, nous générons seulement q/1000 sous-problèmes et si la taille des domaines des trois variables suivantes non assignées est 10, alors nous pouvons déduire que nous avons besoin d aller au moins à la profondeur u + 3. (ii) dans le but d éviter de répéter la même DFS pour les premières variables en répétant l algorithme DBDFS, nous sauvegardons les assignements calculés précédemment dans une contrainte de table. Plus précisément, si nous avons calculé NDI k alors nous utilisons une contrainte de table contenant tous ces assignements lorsque nous recherchons NDI l avec l > k.
(iii) Nous effectuons cette décomposition en parallèle car elle peut prendre un certain temps par rapport à l ensemble de la résolution du problème. Nous parallélisons notre algorithme de décomposition d une manière simple. Considérons que nous avons w workers. Nous recherchons w sous-problèmes NDI. Ensuite, chaque worker reçoit un de ces sous-problèmes et le décompose en q/w sous-problèmes NDI en utilisant notre algorithme. Le nœud maître rassemble tous les sous-problèmes calculées. Notons que l équilibrage de charge n est pas vraiment important car une fois qu un worker a terminé la décomposition d un sous-problème, il commence à résoudre les sous-problèmes disponibles. Il est également possible que le worker ne soit pas en mesure de générer q/w sousproblèmes car il peut résoudre le sous-problème donné par le nœud maître en effectuant la décomposition. Nous pourrons essayer d éviter ce cas mais nos expériences montrent que cela arrive très rarement et étant donné que nous recherchons un certain nombre de sous-problèmes à peu près égal à q, alors ce n est vraiment pas important. Par ailleurs, Nous verrons également que cette parallélisation n est pas nécessaire pour les meilleurs paramètres de notre méthode. 3.3 Implémentation MapReduceCP consiste principalement à définir les fonctions Map et Reduce de la méthode MapReduce pour les problèmes de satisfaction et d optimisation. 3.3.1 Problèmes de satisfaction La fonction Map function consiste à calculer une partition du problème initial P en un ensemble S de sous-problèmes. gérer l ensemble des sous-problèmes afin de les distribuer aux workers lorsqu ils demandent du travail. Le premier point est défini par l utilisation d un des algorithmes décrits précédemment, alors que le deuxième est implémenté par l utilisation d une structure de données de type FIFO (une queue par exemple). La fonction Reduce est assez simple : lors de la recherche d une solution, si une solution est trouvée, alors on stoppe l exploration de l arbre de recherche ; lors de la recherche de toutes les solutions, les solutions trouvées par les workers sont collectées par le nœud maître. 3.3.2 Problèmes d optimisation Dans le cas des problèmes d optimisation, nous devons gérer la meilleure valeur de l objectif trouvée durant la résolution. Ainsi, les fonctions Map et Reduce sont légèrement modifiées. La fonction Map consiste à calculer une partition du problème initial P en un ensemble S de sous-problèmes. gérer l ensemble des sous-problèmes et de la meilleure valeur de la fonction objective trouvée durant la résolution. Lorsqu un worker demande du travail, la fonction Map lui donne un sous-problème à résoudre. il lui donne églament la meilleure valeur de l objectif trouvée précédemment. Notons qu il n y a pas d autres communications, ceci se présente lorsqu un worker trouve une meilleure solution, les autres workers, qui sont en train de travailler, ne peuvent l utiliser pour améliorer la résolution de leurs problèmes courants. De même, si l absence de communication peut améliorer nos performances, cet aspect peut également conduire à une baisse de performance. Heureusement, nous n observons pas ce comportement dans la pratique. Nous pouvons voir ici un autre argument pour engendrer un grand nombre de sous-problèmes dans le cas des problèmes d optimisation : la résolution d un sousproblème doit être courte pour améliorer la transmission d une meilleure valeur de l objectif et d éviter d effectuer certains travaux qui auraient pu être ignorés avec une meilleure valeur objective. La fonction Reduce gère la valeur optimale trouvée par le worker qui sera ensuite utilisée par la fonction Map. 3.4 Taille de la partition Une question importante par rapport à la taille de la partition : combien de sous-problèmes devons nous générer? Il s agit principalement d une question expérimentale. Cependant, notons que, si nous voulons passer à l échelle alors ce nombre devrait être défini en fonction du nombre de workers qui sont impliqués. Plus précisément, il est plus cohérent d avoir q sous-problèmes par worker qu un total de q sous-problèmes. 4 Partie Expérimentale Machines Toutes les expériences ont été effectuées sur des machines Dell ayant quatre E7-4870 processeurs Intel, ayant chacun 10 cœurs avec 256 Go de mémoire et fonctionnant sous Scientific Linux. En exécutant le même programme 10 fois dans chaque cœur de la machine, nous avons pu atteindre un facteur par rapport à une résolution séquentielle de 37.5. Par conséquent, c est le gain maximum que nous pouvons espérer pour une machine. Nos expériences peuvent être reproduites en téléchargeant le programme MapReduceCP sur Linux à partir de ce lien [13].
Solveurs Nous avons implémenté notre méthode dans deux solveurs CP : or-tools rev2555 par Google et Gecode 4.0.0 (http ://www.gecode.org/). Notre code exécute seule- Protocole Expérimental ment trois opérations : soit il lit un fichier contenant un modèle FlatZinc ou soit le problème est directement modélisé par l API du solveur. il crée les "threads" et definit une instance du solveur dans chaque "thread". il calcule les sous-problèmes à générer, puis les fournit aux "threads" et rassemble les résultats. Pour chaque problème, nous allons soit chercher toutes les solutions des problèmes de satisfaction ou prouver l optimalité des problèmes d optimisation, ou résoudre les problèmes d optimisation dans leur ensemble (trouver la meilleure solution et de prouver son optimalité). Nous citerons le type de résolution que nous effectuons dans chaque expérience. Notons que les tests de performance d une méthode parallèle est plus complexe avec un problème d optimisation parce que la chance peut jouer un rôle. Il peut être avantage ou un inconvénient pour nous. Cependant, dans la vie réelle, les problèmes d optimisation sont très fréquents, il est donc important de tester notre méthode sur ces derniers. Instances sélectionnées Nous avons sélectionné un large éventail de problèmes qui sont représentatifs des types de problèmes résolus en CP. Certains viennent de la CSPLib et ont été modélisés par Hakank (http ://www.hakank.org/) et d autres proviennent de la distribution minizinc (1.5 voir [11]). Nous avons sélectionné les instances qui ne sont ni très faciles (supérieur à 20 secondes en séquentiel), ni très longues à résoudre (inférieur à 700 secondes) avec le solveur Gecode. 1. Les exemples fournis par Hakank sont : golombruler- 13 ; magicsequence-40000 ; sportsleague-10 (10 équipes, nous énumérons toutes les solutions) ; warehouses (nombre de warehouses = 10, nombre de stores = 20 et un coût fixé = 180) ; setcovering (Placer les casernes de pompiers avec 80 villes et une distance minimale fixée à 24) ; allinterval-15 (le modèle proposé par Régin et Puget de la CSPLib est utilisé). 2. Les instances Flatzinc provenant de la distribution sont : 2DLevelPacking (5-20-6), depotplacement (att48-5 ; rat99-5), fastfood (58), openstacks (01-problem-15-15 ;01-wbp-30-15-1), sugiyama (2- g5-7-7-7-7-2), patternsetmining (k1-german-credit ; k1-segment ; k1-ionosphere), sb-sb (13-13-6-4), quasigroup7-10, non-non-fast-6, radiation-03, bacp- 7, talent-scheduling-alt-film116. FIGURE 1 17-reines : performance en fonction de #sppw. Nous ne constatons plus la limite d un facteur de gain de 29. Tests Notons #sppw, le nombre de sous-problèmes par worker. Nous allons étudier les aspects suivants de notre méthode : 4.1 le facteur de gain par rapport aux autres décompositions statiques 4.2 le temps d inactivité des workers selon la valeur de #sspw 4.3 la difficulté des sous-problèmes engendrés. En particulier, nous allons examiner le ratio des sous-problèmes NDI. 4.4 l avantage de la parallélisation de la décomposition 4.5 l influence de #sspw sur le facteur d améliorations 4.6 l impact du nombre des workers sur la meilleure valeur de #sspw 4.7 sa performance par rapport au work stealing 4.8 l influence du solveur CP qui est utilisé 4.1 Comparaison avec la décomposition statique simple Nous considérons le problème des n-dames, parce que certaines méthodes proposées [7, 1] n ont pas été en mesure d observer un facteur de gain par rapport au séquentiel supérieur à 29 avec une décomposition statique simple des problèmes même en utilisant 64 machines (ou cœurs). La figure 1 montre que notre méthode obtient un meilleur gain lorsque #sppw est supérieur à 20 (Notons que, pour un ou deux sous-problèmes par worker, nous n obtenons pas un bon gain). La limite de ce gain (un ratio maximum à 29) décrit dans [1] disparait clairement. Nous utilisons la même strategie que dans [1]. Des résultats similaires sont obtenus pour ce problème avec d autres valeurs de n. Nous obtenons également un facteur de gain de 32 pour le problème d optimisation de la règle de Golomb de taille 13.
FIGURE 2 Pourcentage des sous-problèmes NDI générés par la méthode de décomposition simple FIGURE 4 Pourcentage du temps écoulé durant la décomposition. 4.3 Le temps d inactivité selon la valeur de #sppw La figure 3 montre que le temps d inactivité des workers diminue lorsque le nombre de sous-problèmes par worker est augmenté. En outre, il montre que la répartition de charge est bonne quand nous avons plus de 10 sousproblèmes par worker. Il faut faire attention à ces résultats : on ne peut pas dériver la durée totale de la résolution seulement avec le temps d inactivité car le temps de décomposition n est pas considéré. 4.4 Parallélisation de la décomposition FIGURE 3 Maximum du temps d inactivité des workers. 4.2 Ratio des sous-problèmes NDI La figure 2 montre le pourcentage des sous-problèmes NDI générés par la méthode de décomposition simple. Nous pouvons voir que ce nombre dépend fortement du nombre d instances considérées. Pour certaines instances, le nombre est proche de 100%, tandis que pour d autres il peut être vraiment proche de 0%, cela nous indique qu il y a un problème de décomposition. La moyenne commence à 65% et diminue en fonction du nombre de sous-problèmes puis termine à 10%. Par conséquent, pour certaines instances (comme les n-reines ou la règle de Golomb), la décomposition simple est une bonne méthode alors que pour d autres c est une très mauvaise approche et ne doit en aucun cas être utilisée. C est la raison pour laquelle nous avons développé la décomposition par DBDFS avec la méthode de propagation qui ne génère pas de problèmes qui ne sont pas NDI, donc pour le nombre de problèmes NDI générés est de 100%. La figure 4 compare le pourcentage de temps total nécessaire pour décomposer le problème lorsque seul le nœud maître effectue cette opération ou lorsque les workers sont également impliqués. Nous observons clairement que la parallélisation de la décomposition permet de gagner du temps, surtout pour un grand nombre de sous-problèmes par worker. 4.5 Influence du nombre de sous-problèmes à considérer La figure 5 décrit le facteur de gain par rapport à une résolution séquentielle obtenu par la méthode MapReduceCP en fonction du nombre de sous-problèmes pour le solveur Gecode. La meilleure valeur semble être autour de 30 sousproblèmes par worker. En d autres termes, nous proposons de commencer la décomposition avec q = 30w, où w est le nombre de workers. Pour cette valeur : pour 80% des problèmes considérés, le facteur de gain maximum est obtenu ; seuls 20% des problèmes pourraient être améliorés avec une autre valeur, mais jamais plus de 20%. Cela montre que cette valeur ne dépend pas du problème considéré.
FIGURE 6 Meilleure valeur de #sspw en fonction du nombre de workers. FIGURE 7 Résolution de tous les problèmes avec Gecode. Le nombre de workers est à 40 et nous fixons #sspw=30. FIGURE 5 Facteur de gain par rapport à une résolution séquentielle (speedup) en fonction du nombre de sousproblèmes pour trouver toutes les solutions des problèmes des satisfaction (au-dessus), pour trouver et prouver l oprimalit e des problèmes d optimisation (au milieu), et pour tous les problèmes (en bas). La réduction de la performance en augmentant la valeur de #sspw vient du fait que le processus de décomposition résout une partie croissante du problème, et ce processus est plus lent qu une procédure de résolution. Notons qu avec notre méthode, seuls 10% du temps de résolution est perdu si nous utilisons une décomposition séquentielle au lieu d une décomposition parallèle. 4.6 Nombre de workers et meilleure valeur de #sspw Pour savoir si le nombre de sous-problèmes dépend du nombre de workers, nous avons cherché la meilleure valeur de #sspw pour différents nombres de workers. La figure 6 montre les résutats obtenus. Il apparaît clairement que ces nombres ne sont pas corrélés et que la valeur 30 semble constante.
4.7 Comparaison avec le work stealing La Figure 7 présente une comparaison entre notre méthode et la méthode du work stealing disponible dans Gecode. Le facteur de gain moyen de la méthode work stealing est de 11,2 (14,5 pour les problèmes de satisfaction et 9,8 pour les problèmes d optimisation) alors qu avec l approche MapReduceCP, le facteur de gain est de 16,4 (20,0 pour les problèmes de satisfaction et 14,9 pour les problèmes d optimisation). Notre méthode est meilleure que le work stealing dans tous les cas sauf un. 4.8 Influence du solveur CP Nous avons également effectué des expériences en utilisant le solver or-tools. Avec or-tools, les facteurs de gain par rapport au séquentiel de notre méthode sont augmentés. Nous présentons les résultats dans la figure 8. Nous obtenons un facteur moyen d un gain de 14,4 pour le solveur de Gecode et 23,3 pour or-tools. Nous obtenons un facteur de gain moyen de 16,4 pour Gecode et de 23,3 pour or-tools. 5 Remerciements Nous tenons à remercier vivement Laurent Perron et Claude Michel pour leurs commentaires qui ont permis d améliorer cet article. 6 Conclusion Dans cet article, nous avons présenté MapReduceCP, une méthode simple pour résoudre les problèmes CP en parallèle, qui est basée sur le principe de la méthode MapReduce. Nous proposons de décomposer le problème initial en un ensemble de k sous-problèmes qui ne sont pas détectés inconsistants puis d envoyer ces problèmes aux workers afin d être résolu. Après quelques expérimentations, il apparaît que découper le problème initial en 30 sousproblèmes par worker, donne un facteur de gain moyen égal à 23 avec or-tools et 16, 4 avec Gecode tout en recherchant toutes les solutions ou alors trouver et prouver l optimalité sur une machine ayant 40 cœurs. La méthode est compétitive avec l approche work stealing. FIGURE 8 Résolution de tous les problèmes avec or-tools. Le nombre de workers est à 40 et nous fixons #sspw=30. Références [1] Lucas Bordeaux, Youssef Hamadi, and Horst Samulowitz. Experiments with massively parallel constraint solving. In Craig Boutilier, editor, IJCAI, pages 443 448, 2009. [2] Geoffrey Chu, Christian Schulte, and Peter J. Stuckey. Confidence-based work stealing in parallel constraint programming. In Ian P. Gent, editor, CP, volume 5732 of Lecture Notes in Computer Science, pages 226 241. Springer, 2009. [3] Gérard Cornuéjols, Miroslav Karamanov, and Yanjun Li. Early estimates of the size of branch-and-bound trees. INFORMS Journal on Computing, 18(1) :86 96, 2006. [4] Jeffrey Dean and Sanjay Ghemawat. Mapreduce : Simplified data processing on large clusters. In OSDI, pages 137 150. USENIX Association, 2004. [5] Ian P. Gent, Chris Jefferson, Ian Miguel, Neil C.A. Moore, Peter Nightingale, Patrick Prosser, and Chris Unsworth. A preliminary review of literature on parallel constraint solving,. In Proceedings PMCS-11 Workshop on Parallel Methods for Constraint Solving, 2011. [6] Youssef Hamadi. Optimal distributed arcconsistency. Constraints, 7 :367 385, 2002. [7] Joxan Jaffar, Andrew E. Santosa, Roland H. C. Yap, and Kenny Qili Zhu. Scalable distributed depth-first search with greedy work stealing. In ICTAI, pages 98 103. IEEE Computer Society, 2004.
[8] Philip Kilby, John K. Slaney, Sylvie Thiébaux, and Toby Walsh. Estimating search tree size. In AAAI, pages 1014 1019, 2006. [9] Donald E. Knuth. Estimating the efficiency of backtrack program. Mathematics of Computation, 29 :121 136, 1975. [10] Laurent Michel, Andrew See, and Pascal Van Hentenryck. Transparent parallelization of constraint programming. INFORMS Journal on Computing, 21(3) :363 382, 2009. [11] MiniZinc. http ://www.g12.csse.unimelb.edu.au/minizinc/, 2012. [12] Laurent Perron. Search procedures and parallelism in constraint programming. In Joxan Jaffar, editor, CP, volume 1713 of Lecture Notes in Computer Science, pages 346 360. Springer, 1999. [13] Jean-Charles Régin. www.constraintprogramming.com/people/regin/papers. [14] Christian Schulte. Parallel search made simple. In University of Singapore, pages 41 57, 2000. [15] Feng Xie and Andrew J. Davenport. Massively parallel constraint programming for supercomputers : Challenges and initial results. In Andrea Lodi, Michela Milano, and Paolo Toth, editors, CPAIOR, volume 6140 of Lecture Notes in Computer Science, pages 334 338. Springer, 2010. [16] Peter Zoeteweij and Farhad Arbab. A componentbased parallel constraint solver. In Rocco De Nicola, Gian Luigi Ferrari, and Greg Meredith, editors, COORDINATION, volume 2949 of Lecture Notes in Computer Science, pages 307 322. Springer, 2004.