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