2016-02-14 1 views
0

Il existe un programme qui multiplie la matrice et le vecteur en utilisant MPJ Express. La matrice est divisée par des lignes. Mais il existe une exception lors du traitement. Est-ce que je fais mal?Pourquoi une exception se produit-elle dans le programme qui a utilisé MPJ Express?

import java.util.Random; 

import mpi.Comm; 
import mpi.MPI; 

public class Main { 
    private static final int rootProcessorRank = 0; 
    private static Comm comunicator; 
    private static int processorsNumber; 
    private static int currentProcessorRank; 


    public static void main(String[] args) { 
     MPI.Init(args); 
     comunicator = MPI.COMM_WORLD; 
     currentProcessorRank = comunicator.Rank(); 
     processorsNumber = comunicator.Size(); 

     if (currentProcessorRank == rootProcessorRank) { 
      rootProcessorAction(); 
     } else { 
      notRootProcessorAction(); 
     } 

     MPI.Finalize(); 

    } 

    public static void rootProcessorAction() { 
     int[] matrixVectorSize = new int[] {5}; 
     int[][] matrix = createAndInitMatrix(matrixVectorSize[0]); 
     int[] vector = createAndInitVector(matrixVectorSize[0]); 

     for (int i = 1; i < processorsNumber; i++) { 
      comunicator.Isend(matrixVectorSize, 0, 1, MPI.INT, i, MPI.ANY_TAG); 
      System.out.println("Proc: " + currentProcessorRank + ", send matrixVectorSize"); 

      comunicator.Isend(vector, 0, vector.length, MPI.INT, i, MPI.ANY_TAG); 
      System.out.println("Proc: " + currentProcessorRank + ", send vector"); 
     } 

     int averageRowsPerProcessor = matrix.length/(processorsNumber - 1); 
     int[] rowsPerProcessor = new int[processorsNumber]; 
     int notDistributedRowsNumber = matrix.length; 
     for (int i = 1; i < rowsPerProcessor.length; i++) { 
      if (i == rowsPerProcessor.length - 1) { 
       rowsPerProcessor[i] = notDistributedRowsNumber; 
      } else { 
       rowsPerProcessor[i] = averageRowsPerProcessor; 
       notDistributedRowsNumber -= averageRowsPerProcessor; 
      } 
     } 

     int offset = 0; 
     // the processorRows[0] always will be '0' 
     for (int i = 1; i < rowsPerProcessor.length; i++) { 
      int[] processorRows = new int[1]; 
      processorRows[0] = rowsPerProcessor[i]; 
      comunicator.Isend(processorRows, 0, 1, MPI.INT, i, MPI.ANY_TAG); 
      comunicator.Isend(matrix, offset, processorRows[0], MPI.OBJECT, i, MPI.ANY_TAG); 
      offset += rowsPerProcessor[i]; 
     } 

     // there will be a code that receive a subRecults from all processes. 
    } 

    public static void notRootProcessorAction() { 
     int[] matrixVectorSize = new int[1]; 
     int[] rowsNumber = new int[1]; 
     int[] vector = null; 
     int[][] subMatrix = null; 

     comunicator.Probe(rootProcessorRank, MPI.ANY_SOURCE); 
     comunicator.Recv(matrixVectorSize, 0, 1, MPI.INT, rootProcessorRank, MPI.ANY_TAG); 
     System.out.println("Proc: " + currentProcessorRank + ", receive matrixVectorSize"); 

     vector = new int[matrixVectorSize[0]]; 
     comunicator.Probe(rootProcessorRank, MPI.ANY_SOURCE); 
     comunicator.Recv(vector, 0, vector.length, MPI.INT, rootProcessorRank, MPI.ANY_TAG); 
     System.out.println("Proc: " + currentProcessorRank + ", receive vector"); 

     comunicator.Probe(rootProcessorRank, MPI.ANY_SOURCE); 
     comunicator.Recv(rowsNumber, 0, 1, MPI.INT, rootProcessorRank, MPI.ANY_TAG); 
     System.out.println("Proc: " + currentProcessorRank + ", receive rowsNumber"); 
     subMatrix = new int[rowsNumber[0]][rowsNumber[0]]; 

     comunicator.Probe(rootProcessorRank, MPI.ANY_SOURCE); 
     comunicator.Recv(subMatrix, 0, subMatrix.length, MPI.OBJECT, rootProcessorRank, MPI.ANY_TAG); 
     System.out.println("Proc: " + currentProcessorRank + ", receive subMatrix"); 

     int[] result = new int[rowsNumber[0]]; 
     multiplyMatrixVector(subMatrix, vector, result); 

     comunicator.Send(result, 0, result.length, MPI.INT, rootProcessorRank, MPI.ANY_TAG); 
    } 

    private static void multiplyMatrixVector(int[][] matrix, int[] vector, int[] result) { 
     for (int i = 0; i < matrix.length; i++) { 
      int summ = 0; 
      for (int j = 0; j < matrix[i].length; j++) { 
       summ += matrix[i][j] * vector[j]; 
      } 
      result[i] = summ; 
     } 
    } 

    private static int[][] createAndInitMatrix(int size) { 
     int[][] matrix = new int[size][size]; 
     Random random = new Random(); 
     for (int i = 0; i < matrix.length; i++) { 
      for (int j = 0; j < matrix.length; j++) { 
       matrix[i][j] = random.nextInt(100); 
      } 
     } 
     return matrix; 
    } 

    private static int[] createAndInitVector(int size) { 
     int[] vector = new int[size]; 
     Random random = new Random(); 
     for (int i = 0; i < vector.length; i++) { 
      vector[i] = random.nextInt(100); 
     } 
     return vector; 
    } 
} 

Voici une exception:

MPJ Express (0,44) est démarré dans la configuration multi-cœurs java.lang.reflect.InvocationTargetException à sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) à sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:57) à sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) à java.lang.reflect.Method.invoke (Method.java:6 06) à runtime.starter.MulticoreStarter $ 1.run (MulticoreStarter.java:281) à java.lang.Thread.run (Thread.java:745) Causé par: mpi.MPIException: xdev.XDevException: java.lang .NullPointerException à mpi.Comm.isend (Comm.java:944) à mpi.Comm.Isend (Comm.java:885) à Main.rootProcessorAction (Main.java:35) à Main.main (Main.java: 20) ... 6 plus causé par: xdev.XDevException: java.lang.NullPointerException à xdev.smpdev.SMPDevice.isend (SMPDevice.java:104) à mpjdev.javampjdev.Comm.isend (Comm.java : 1019) à mpi.Comm.isend (Comm.java:941) ... 9 plus Causé par: java.lang.NullPointerException à xdev.smpdev.SMPDevice Impl $ SendQueue.add (SMPDeviceImpl.java:930) à xdev.smpdev.SMPDeviceImpl $ SendQueue.add (SMPDeviceImpl.java:909) à xdev.smpdev.SMPDeviceImpl.isend (SMPDeviceImpl.java:330) à xdev. smpdev.SMPDevice.isend (SMPDevice.java:101) ... 11 plus xdev.XDevException: java.lang.NullPointerException à xdev.smpdev.SMPDevice.recv (SMPDevice.java:162)

+0

L'exception de pointeur NULL peut être généralement due à l'accès à une partie non-existante de la mémoire ... les données sont-elles contiguës dans votre code source? –

+0

Etes-vous capable d'exécuter un simple MPJ hello world? – Zulan

+0

En fait, j'ai écrit un programme simple utilisant MPI. Et ça marche. –

Répondre

1

En mon expérience avec mpj express, essayez d'éviter d'utiliser les constantes MPI.ANY_SOURCE et MPI.ANY_TAG. Définissez votre propre tag et la source et vous devriez aller bien. Lorsque j'utilisais ces constantes dans mon programme, il m'arrivait parfois des plantages aléatoires avec la xDev.xDevException provoquée par un pointeur nul et parfois ça fonctionnait très bien.

Voici une liste des constantes internes de l'mpj exprimez vous ne devriez pas utiliser comme aswell tag, je montre que les constantes qui sont des nombres entiers:

public static final int mpi.MPI.NUM_OF_PROCESSORS = 4 
public static int mpi.MPI.UNDEFINED = -1 
public static int mpi.MPI.THREAD_SINGLE = 1 
public static int mpi.MPI.THREAD_FUNNELED = 2 
public static int mpi.MPI.THREAD_SERIALIZED = 3 
public static int mpi.MPI.THREAD_MULTIPLE = 4 
public static int mpi.MPI.ANY_SOURCE = -2 
public static int mpi.MPI.ANY_TAG = -2 
public static int mpi.MPI.PROC_NULL = -3 
public static int mpi.MPI.BSEND_OVERHEAD = 0 
public static int mpi.MPI.SEND_OVERHEAD = 0 
public static int mpi.MPI.RECV_OVERHEAD = 0 
public static final int mpi.MPI.IDENT = 0 
public static final int mpi.MPI.CONGRUENT = 3 
public static final int mpi.MPI.SIMILAR = 1 
public static final int mpi.MPI.UNEQUAL = 2 
public static int mpi.MPI.GRAPH = 1 
public static int mpi.MPI.CART = 2 
public static int mpi.MPI.TAG_UB = 0 
public static int mpi.MPI.HOST = 0 
public static int mpi.MPI.IO = 0 

acclamations.