1 /*
2 * Distributed under the OSI-approved Apache License, Version 2.0. See
3 * accompanying file Copyright.txt for details.
4 *
5 * Settings.cpp
6 *
7 * Created on: Dec 2017
8 * Author: Norbert Podhorszki
9 */
10
11 #include "ReadSettings.h"
12
13 #include <cstdlib>
14 #include <errno.h>
15 #include <iomanip>
16 #include <iostream>
17 #include <stdexcept>
18
convertToUint(std::string varName,char * arg)19 static unsigned int convertToUint(std::string varName, char *arg)
20 {
21 char *end;
22 long retval = std::strtol(arg, &end, 10);
23 if (end[0] || errno == ERANGE)
24 {
25 throw std::invalid_argument("Invalid value given for " + varName +
26 ": " + std::string(arg));
27 }
28 if (retval < 0)
29 {
30 throw std::invalid_argument("Negative value given for " + varName +
31 ": " + std::string(arg));
32 }
33 return static_cast<unsigned int>(retval);
34 }
35
ReadSettings(int argc,char * argv[],int rank,int nproc)36 ReadSettings::ReadSettings(int argc, char *argv[], int rank, int nproc)
37 : rank{rank}
38 {
39 if (argc < 6)
40 {
41 throw std::invalid_argument("Not enough arguments");
42 }
43 this->nproc = (unsigned int)nproc;
44
45 configfile = argv[1];
46 inputfile = argv[2];
47 outputfile = argv[3];
48 npx = convertToUint("N", argv[4]);
49 npy = convertToUint("M", argv[5]);
50
51 if (npx * npy != static_cast<unsigned int>(this->nproc))
52 {
53 throw std::invalid_argument("N*M must equal the number of processes");
54 }
55 posx = rank % npx;
56 posy = rank / npx;
57 }
58
DecomposeArray(int gndx,int gndy)59 void ReadSettings::DecomposeArray(int gndx, int gndy)
60 {
61 // 2D decomposition of global array reading
62 size_t ndx = gndx / npx;
63 size_t ndy = gndy / npy;
64 size_t offsx = ndx * posx;
65 size_t offsy = ndy * posy;
66 if (posx == npx - 1)
67 {
68 // right-most processes need to read all the rest of rows
69 ndx = gndx - ndx * (npx - 1);
70 }
71
72 if (posy == npy - 1)
73 {
74 // bottom processes need to read all the rest of columns
75 ndy = gndy - ndy * (npy - 1);
76 }
77 readsize.push_back(ndx);
78 readsize.push_back(ndy);
79 offset.push_back(offsx);
80 offset.push_back(offsy);
81
82 std::cout << "rank " << rank << " reads 2D slice " << ndx << " x " << ndy
83 << " from offset (" << offsx << "," << offsy << ")" << std::endl;
84 }
85