-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfileConvert.cpp
174 lines (167 loc) · 5.77 KB
/
fileConvert.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
* Copyright (c) 2021-2022, Virginia Tech.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "filetypes.hpp"
#include "readMtxToCSR.hpp"
#ifndef WEIGHT_TYPE
#ifndef DISABLE_DP_WEIGHT
#define WEIGHT_TYPE double
#else
#define WEIGHT_TYPE float
#endif
#endif
int main(int argc, char *argv[]) {
if (argc != 4) {
std::cerr << "Error, incorrect number of args, usage is:\n.fileConvert <input.[mtx|csr]> "
"<output.[mtx|csr]> <keepReverseEdges (0 or 1)>"
<< std::endl;
}
std::ifstream fileIn;
std::ofstream fileOut;
graphFileType inType, outType, working;
setupInFile(argv[1], fileIn, inType);
setupOutFile(argv[2], fileOut, outType);
bool keepReverseEdges = static_cast<bool>(atoi(argv[3]));
bool isWeighted = false, isDirected = false, hasReverseEdges = false, isZeroIndexed = false,
dropWeights = false;
int32_t numVerts = 0, numEdges = 0;
char *force_dw = std::getenv("CONVERT_FORCE_DROP_WEIGHTS");
if (force_dw != nullptr) {
std::cerr << "FORCE Drop Weights" << std::endl;
dropWeights = true;
}
std::set<std::tuple<int32_t, int32_t, WEIGHT_TYPE>> *mtx_in = nullptr;
GraphCSRView<int32_t, int32_t, WEIGHT_TYPE> *csr_in = nullptr;
// Fetch the input
switch (inType) {
case (mtx): {
working = mtx;
// Header information comes with the MTX reader
mtx_in = fileToMTXSet<int32_t, int32_t, WEIGHT_TYPE>(fileIn, &isWeighted, &isDirected,
&numVerts, &numEdges, dropWeights);
if (dropWeights) isWeighted = false;
// By spec, MTX doesn't typically have reverse edges (It would have to be in general form,
// which we couldn't distinguish from a regular directed graph without exhaustively checking
// all the edge pairs)
} break;
case (csr): {
working = csr;
// Header information comes from the file
CSRFileHeader header;
csr_in =
static_cast<GraphCSRView<int32_t, int32_t, WEIGHT_TYPE> *>(FileToCSR(fileIn, &header));
isWeighted = header.flags.isWeighted;
isDirected = header.flags.isDirected;
isZeroIndexed = header.flags.isZeroIndexed;
hasReverseEdges = header.flags.hasReverseEdges;
numVerts = header.numVerts;
numEdges = header.numEdges;
} break;
default: {
std::cerr << "Unsupported input file type" << std::endl;
} break;
}
fileIn.close();
// Check that we can actually respect a reverseEdge request, if not emit a warning
if (keepReverseEdges) {
if (isDirected) {
std::cerr << "Warning, Cannot retain reverseEdges of Directed input, could cause collisions"
<< std::endl;
keepReverseEdges = false;
}
if (outType == mtx) {
std::cerr << "Warning, Cannot retain reverseEdges with MTX output, would be "
"indistinguishable from directed"
<< std::endl;
keepReverseEdges = false;
}
char *force_ec = std::getenv("CONVERT_FORCE_REVERSE");
if (force_ec != nullptr) {
std::cerr << "FORCE Reverse Edge Generation" << std::endl;
keepReverseEdges = true;
}
}
// Generate reverse edges if we need to, remove them if we need to
if (keepReverseEdges && !hasReverseEdges) {
// Generate them
if (working == csr) {
// Switch it to MTX to reverse them
mtx_in = CSRToMtx(*csr_in, isZeroIndexed, isWeighted);
working = mtx;
isZeroIndexed = false;
// Don't need to maintain it as CSR anymore
delete csr_in;
}
std::set<std::tuple<int32_t, int32_t, WEIGHT_TYPE>> *reverse = invertDirection(*mtx_in);
mtx_in->insert(reverse->begin(), reverse->end());
hasReverseEdges = true;
numEdges = mtx_in->size();
delete reverse;
} else if (hasReverseEdges && !keepReverseEdges) {
// Remove them
if (working == csr) {
// Convert it to MTX to dedup
mtx_in = CSRToMtx(*csr_in, isZeroIndexed, isWeighted);
working = mtx;
isZeroIndexed = false;
// Don't need to maintain it as CSR anymore
delete csr_in;
} else if (working != mtx) {
// Future formats;
}
removeReverseEdges(*mtx_in);
hasReverseEdges = false;
numEdges = mtx_in->size();
}
// And write it
switch (outType) {
case (csr): {
if (working == mtx) {
// Promote it to CSR
csr_in = mtxSetToCSR(*mtx_in, true, isZeroIndexed);
working = csr;
isZeroIndexed = true;
delete mtx_in;
} else if (working != csr) {
// Future formats
}
// Write it
CSRToFile(fileOut, *csr_in, isZeroIndexed, isWeighted, isDirected, hasReverseEdges);
} break;
case (mtx): {
// Just write it
if (working == csr) {
// Convert it back to MTX
mtx_in = CSRToMtx(*csr_in, isZeroIndexed, isWeighted);
working = mtx;
isZeroIndexed = false;
// Don't need to maintain it as CSR anymore
delete csr_in;
} else if (working != mtx) {
// Future formats
}
// Write it
mtxSetToFile(fileOut, *mtx_in, numVerts, numEdges, isWeighted, isDirected);
} break;
default: {
std::cerr << "Unsupported output file type" << std::endl;
} break;
}
fileOut.close();
if (working == csr) {
delete csr_in;
}
if (working == mtx) delete mtx_in;
}