Esempio n. 1
0
/**
 *  \brief The program starts here.
 *  \param argc The number of arguments passed to the program.
 *  \param argv Pointers to the arguments passed to the program.
 *  \result 0 (zero) if all process OK.
 */
int main (int argc, char *argv[])
{
	void *fileList = NULL;
	int i, found = 0, width = 80;
	char fullVersion[81];

	strcpy (fullVersion, VERSION);
#ifdef USE_STATX
	strcat (fullVersion, ".X");
#endif
	if (strcmp (directoryVersion(), fullVersion) != 0)
	{
		fprintf (stderr, "Library (%s) does not match Utility (%s).\n", directoryVersion(), VERSION);
		exit (1);
	}

	displayInit ();
	width = displayGetWidth();

	while ((i = getopt(argc, argv, "CPqw:?")) != -1)
	{
		switch (i)
		{
		case 'C':
			displayFlags |= DISPLAY_COLOURS;
			break;

		case 'P':
			displayFlags |= DISPLAY_IN_PAGES;
			break;

		case 'q':
			displayQuiet ^= 1;
			break;

		case 'w':
			width = atoi (optarg);
			displayWidth = (width / 8) * 8;
			if (displayWidth < 8 || displayWidth > 80)
			{
				displayWidth = 16;
			}
			break;

		case '?':
			helpThem (argv[0]);
			exit (1);
		}
	}

	/*----------------------------------------------------------------------------------------------------------------*
     * If the size option has not been used calculate the best one for this screen size.                              *
	 *----------------------------------------------------------------------------------------------------------------*/
	if (displayWidth == -1)
	{
		displayWidth = 8;
		do
		{
			int newWidth = (displayQuiet ? (displayWidth * 3) : ((displayWidth * 4) + (displayWidth / 8) + 10));
			if (newWidth > width)
			{
				displayWidth -= 8;
				break;
			}
			displayWidth += 8;
		}
		while (displayWidth < 80);
		if (displayWidth < 8)
		{
			displayWidth = 8;
		}
	}
	displayCols = allocTable (displayWidth);

	/*----------------------------------------------------------------------------------------------------------------*
     * If no file name has been passed in then use stdin.                                                             *
	 *----------------------------------------------------------------------------------------------------------------*/
	if (optind == argc)
	{
		showStdIn ();
	}
	else
	{
		for (; optind < argc; ++optind)
		{
			found += directoryLoad (argv[optind], ONLYFILES|ONLYLINKS, NULL, &fileList);
		}

		if (found)
		{
			/*--------------------------------------------------------------------------------------------------------*
    	     * Now we can sort the directory.                                                                         *
			 *--------------------------------------------------------------------------------------------------------*/
			directorySort (&fileList);
			directoryProcess (showDir, &fileList);
		}
		else
		{
			version ();
			printf ("No files found\n");
			return 0;
		}
	}
	if (!displayQuiet && filesFound)
	{
		if (!displayColumnInit (2, ptrFileColumn, 0))
		{
			fprintf (stderr, "ERROR in: displayColumnInit\n");
			return 0;
		}
		displayDrawLine (0);
		displayInColumn (0, "%d %s shown\n", filesFound, filesFound == 1 ? "File" : "Files");
		displayNewLine(DISPLAY_INFO);
		displayAllLines ();
		displayTidy ();
	}
	return 0;
}
void ElementFile::distributeByRankOfDOF(const int* mpiRankOfDOF,
                                        const index_t* nodesId)
{
    const int size = MPIInfo->size;
    if (size > 1) {
#ifdef ESYS_MPI
        const int myRank = MPIInfo->rank;
        int numRequests = 0;
        std::vector<MPI_Request> mpi_requests(8 * size);
        std::vector<MPI_Status> mpi_stati(8 * size);

        // count the number elements that have to be sent to each processor
        // (send_count) and define a new element owner as the processor with
        // the largest number of DOFs and the smallest id
        std::vector<dim_t> send_count(size);
        std::vector<dim_t> recv_count(size);
        int* newOwner = new int[numElements];
#pragma omp parallel
        {
            std::vector<dim_t> loc_proc_mask(size);
            std::vector<dim_t> loc_send_count(size);
#pragma omp for
            for (index_t e = 0; e < numElements; e++) {
                if (Owner[e] == myRank) {
                    newOwner[e] = myRank;
                    loc_proc_mask.assign(size, 0);
                    for (int j = 0; j < numNodes; j++) {
                        const int p = mpiRankOfDOF[Nodes[INDEX2(j, e, numNodes)]];
                        loc_proc_mask[p]++;
                    }
                    dim_t loc_proc_mask_max = 0;
                    for (int p = 0; p < size; ++p) {
                        if (loc_proc_mask[p] > 0)
                            loc_send_count[p]++;
                        if (loc_proc_mask[p] > loc_proc_mask_max) {
                            newOwner[e] = p;
                            loc_proc_mask_max = loc_proc_mask[p];
                        }
                    }
                } else {
                    newOwner[e] = -1;
                }
            }
#pragma omp critical
            {
                for (int p = 0; p < size; ++p)
                    send_count[p] += loc_send_count[p];
            }
        } // end parallel section
        MPI_Alltoall(&send_count[0], 1, MPI_DIM_T, &recv_count[0], 1,
                     MPI_DIM_T, MPIInfo->comm);
        // get the new number of elements for this processor
        dim_t newNumElements = 0;
        dim_t numElementsInBuffer = 0;
        for (int p = 0; p < size; ++p) {
            newNumElements += recv_count[p];
            numElementsInBuffer += send_count[p];
        }

        std::vector<index_t> Id_buffer(numElementsInBuffer);
        std::vector<int> Tag_buffer(numElementsInBuffer);
        std::vector<int> Owner_buffer(numElementsInBuffer);
        std::vector<index_t> Nodes_buffer(numElementsInBuffer * numNodes);
        std::vector<index_t> send_offset(size);
        std::vector<index_t> recv_offset(size);
        std::vector<unsigned char> proc_mask(size);

        // calculate the offsets for the processor buffers
        for (int p = 0; p < size - 1; ++p) {
            recv_offset[p + 1] = recv_offset[p] + recv_count[p];
            send_offset[p + 1] = send_offset[p] + send_count[p];
        }

        send_count.assign(size, 0);
        // copy element into buffers. proc_mask makes sure that an element is
        // copied once only for each processor
        for (index_t e = 0; e < numElements; e++) {
            if (Owner[e] == myRank) {
                proc_mask.assign(size, 1);
                for (int j = 0; j < numNodes; j++) {
                    const int p = mpiRankOfDOF[Nodes[INDEX2(j, e, numNodes)]];
                    if (proc_mask[p]) {
                        const index_t k = send_offset[p] + send_count[p];
                        Id_buffer[k] = Id[e];
                        Tag_buffer[k] = Tag[e];
                        Owner_buffer[k] = newOwner[e];
                        for (int i = 0; i < numNodes; i++)
                            Nodes_buffer[INDEX2(i, k, numNodes)] =
                                         nodesId[Nodes[INDEX2(i, e, numNodes)]];
                        send_count[p]++;
                        proc_mask[p] = 0;
                    }
                }
            }
        }
        // allocate new tables
        allocTable(newNumElements);

        // start to receive new elements
        for (int p = 0; p < size; ++p) {
            if (recv_count[p] > 0) {
                MPI_Irecv(&Id[recv_offset[p]], recv_count[p], MPI_DIM_T, p,
                          MPIInfo->counter() + myRank, MPIInfo->comm,
                          &mpi_requests[numRequests]);
                numRequests++;
                MPI_Irecv(&Tag[recv_offset[p]], recv_count[p], MPI_INT, p,
                          MPIInfo->counter() + size + myRank, MPIInfo->comm,
                          &mpi_requests[numRequests]);
                numRequests++;
                MPI_Irecv(&Owner[recv_offset[p]], recv_count[p], MPI_INT, p,
                          MPIInfo->counter() + 2 * size + myRank,
                          MPIInfo->comm, &mpi_requests[numRequests]);
                numRequests++;
                MPI_Irecv(&Nodes[recv_offset[p] * numNodes],
                          recv_count[p] * numNodes, MPI_DIM_T, p,
                          MPIInfo->counter() + 3 * size + myRank,
                          MPIInfo->comm, &mpi_requests[numRequests]);
                numRequests++;
            }
        }
        // now the buffers can be sent away
        for (int p = 0; p < size; ++p) {
            if (send_count[p] > 0) {
                MPI_Issend(&Id_buffer[send_offset[p]], send_count[p],
                           MPI_DIM_T, p, MPIInfo->counter() + p,
                           MPIInfo->comm, &mpi_requests[numRequests]);
                numRequests++;
                MPI_Issend(&Tag_buffer[send_offset[p]], send_count[p],
                           MPI_INT, p, MPIInfo->counter() + size + p,
                           MPIInfo->comm, &mpi_requests[numRequests]);
                numRequests++;
                MPI_Issend(&Owner_buffer[send_offset[p]], send_count[p],
                           MPI_INT, p, MPIInfo->counter() + 2 * size + p,
                           MPIInfo->comm, &mpi_requests[numRequests]);
                numRequests++;
                MPI_Issend(&Nodes_buffer[send_offset[p] * numNodes],
                           send_count[p] * numNodes, MPI_DIM_T, p,
                           MPIInfo->counter() + 3 * size + p,
                           MPIInfo->comm, &mpi_requests[numRequests]);
                numRequests++;
            }
        }
        MPIInfo->incCounter(4 * size);
        // wait for the requests to be finalized
        MPI_Waitall(numRequests, &mpi_requests[0], &mpi_stati[0]);
        delete[] newOwner;
#endif
    } else { // single rank
#pragma omp parallel for
        for (index_t e = 0; e < numElements; e++) {
            Owner[e] = 0;
            for (int i = 0; i < numNodes; i++)
                Nodes[INDEX2(i, e, numNodes)] =
                                     nodesId[Nodes[INDEX2(i, e, numNodes)]];
        }
    }
}