Skip to content

Commit 4d2f751

Browse files
authored
Merge pull request #542 from shkodm/arb_cut
Implement cuts for the arbitrary lattice
2 parents 1825c3e + 828cd47 commit 4d2f751

6 files changed

Lines changed: 89 additions & 16 deletions

File tree

src/ArbConnectivity.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <memory>
55
#include <numeric>
66
#include <vector>
7+
#include "types.h"
78

89
struct ArbLatticeConnectivity {
910
using Index = long;
@@ -15,18 +16,22 @@ struct ArbLatticeConnectivity {
1516
std::unique_ptr<Index[]> nbrs;
1617
std::unique_ptr<ZoneIndex[]> zones_per_node;
1718
std::vector<ZoneIndex> zones;
19+
std::unique_ptr<cut_t[]> cuts;
1820
double grid_size{};
21+
bool has_cuts{};
1922

2023
ArbLatticeConnectivity() = default;
21-
ArbLatticeConnectivity(size_t chunk_begin_, size_t chunk_end_, size_t num_nodes_global_, size_t Q_)
24+
ArbLatticeConnectivity(size_t chunk_begin_, size_t chunk_end_, size_t num_nodes_global_, size_t Q_, bool has_cuts_ = false)
2225
: chunk_begin(chunk_begin_),
2326
chunk_end(chunk_end_),
2427
num_nodes_global(num_nodes_global_),
2528
Q(Q_),
2629
coords(std::make_unique<double[]>(3 * (chunk_end_ - chunk_begin_))),
2730
og_index(std::make_unique<Index[]>(chunk_end_ - chunk_begin_)),
2831
nbrs(std::make_unique<Index[]>((chunk_end_ - chunk_begin_) * Q)),
29-
zones_per_node(std::make_unique<ZoneIndex[]>(chunk_end_ - chunk_begin_)) {
32+
zones_per_node(std::make_unique<ZoneIndex[]>(chunk_end_ - chunk_begin_)),
33+
cuts(has_cuts_ ? std::make_unique<cut_t[]>(26 * (chunk_end_ - chunk_begin_)) : nullptr),
34+
has_cuts(has_cuts_) {
3035
zones.reserve(getLocalSize());
3136
}
3237

@@ -52,6 +57,8 @@ struct ArbLatticeConnectivity {
5257
double coord(size_t dim, size_t local_node_ind) const { return coords[local_node_ind + dim * getLocalSize()]; }
5358
Index& neighbor(size_t q, size_t local_node_ind) { return nbrs[local_node_ind + q * getLocalSize()]; }
5459
Index neighbor(size_t q, size_t local_node_ind) const { return nbrs[local_node_ind + q * getLocalSize()]; }
60+
cut_t& cut_distance(size_t d, size_t local_node_ind) { return cuts[local_node_ind + d * getLocalSize()]; }
61+
cut_t cut_distance(size_t d, size_t local_node_ind) const { return cuts[local_node_ind + d * getLocalSize()]; }
5562
};
5663

5764
inline auto computeInitialNodeDist(size_t num_nodes_global, size_t comm_size) -> std::vector<long> {

src/ArbLattice.cpp

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,14 +160,35 @@ void ArbLattice::readFromCxn(const std::string& cxn_path) {
160160
});
161161
for (size_t i = 0; i != labels.size(); ++i) label_to_ind_map.emplace(labels[i], i);
162162

163-
// Nodes header
164-
process_section("NODES", [&](size_t num_nodes_global) {
163+
// Optional CUTS section - check at the next word to see if it's CUTS or NODES
164+
bool has_cuts = false;
165+
{
166+
file >> word;
167+
check_file_ok("Failed to read section header: expected CUTS or NODES");
168+
if (word == "CUTS") {
169+
size_t n_cuts{};
170+
file >> n_cuts;
171+
check_file_ok("Failed to read CUTS size");
172+
if (n_cuts != 26) throw std::logic_error(wrap_err_msg("Expected CUTS 26, got CUTS " + std::to_string(n_cuts)));
173+
has_cuts = true;
174+
file >> word;
175+
check_file_ok("Failed to read section header: NODES");
176+
}
177+
check_expected_word("NODES", word);
178+
}
179+
180+
// Nodes
181+
{
182+
size_t num_nodes_global{};
183+
file >> num_nodes_global;
184+
check_file_ok("Failed to read section size: NODES");
185+
165186
// Compute the current rank's offset and number of nodes to read
166187
const auto chunk_offsets = computeInitialNodeDist(num_nodes_global, static_cast<size_t>(comm_size));
167188
const auto chunk_begin = static_cast<size_t>(chunk_offsets[comm_rank]), chunk_end = static_cast<size_t>(chunk_offsets[comm_rank + 1]);
168189
const auto num_nodes_local = chunk_end - chunk_begin;
169190

170-
connect = ArbLatticeConnectivity(chunk_begin, chunk_end, num_nodes_global, Q);
191+
connect = ArbLatticeConnectivity(chunk_begin, chunk_end, num_nodes_global, Q, has_cuts);
171192
connect.grid_size = grid_size;
172193

173194
// Skip chunk_begin + 1 (header) newlines
@@ -193,9 +214,16 @@ void ArbLattice::readFromCxn(const std::string& cxn_path) {
193214
file >> zone;
194215
}
195216

217+
if (has_cuts) {
218+
for (size_t d = 0; d != 26; ++d) {
219+
auto& cut = connect.cut_distance(d, local_node_ind);
220+
file >> cut;
221+
}
222+
}
223+
196224
check_file_ok("Failed to read node data");
197225
}
198-
});
226+
}
199227
}
200228

201229
void ArbLattice::partition() {
@@ -293,6 +321,12 @@ void ArbLattice::allocDeviceMemory() {
293321
neighbors_device = cudaMakeUnique2D<unsigned>(sizes.neighbors_pitch, Q);
294322
sizes.coords_pitch = local_sz;
295323
coords_device = cudaMakeUnique2D<real_t>(sizes.coords_pitch, 3);
324+
sizes.cuts_pitch = local_sz;
325+
if (connect.has_cuts) {
326+
cut_distances_device = cudaMakeUnique2D<cut_t>(sizes.cuts_pitch, 26);
327+
} else {
328+
cut_distances_device.reset();
329+
}
296330
sizes.snaps_pitch = local_sz + ghost_nodes.size() + 1;
297331
snaps_device = cudaMakeUnique2D<storage_t>(sizes.snaps_pitch, sizes.snaps * NF);
298332
node_types_device = cudaMakeUnique<flag_t>(local_sz);
@@ -358,6 +392,17 @@ std::vector<real_t> ArbLattice::computeCoords() const {
358392
return retval;
359393
}
360394

395+
std::vector<cut_t> ArbLattice::computeCutDistances() const {
396+
const auto local_sz = connect.getLocalSize();
397+
std::vector<cut_t> retval(sizes.cuts_pitch * 26);
398+
for (size_t d = 0; d != 26; ++d) {
399+
size_t i = 0;
400+
for (; i != local_sz; ++i) retval[local_permutation[i] + d * sizes.cuts_pitch] = connect.cut_distance(d, i);
401+
for (; i != sizes.cuts_pitch; ++i) retval[i + d * sizes.cuts_pitch] = NO_CUT; // padding
402+
}
403+
return retval;
404+
}
405+
361406
unsigned int ArbLattice::lookupLocalGhostIndex(ArbLatticeConnectivity::Index gid) const {
362407
const unsigned local_sz = connect.getLocalSize();
363408
const auto it = std::lower_bound(ghost_nodes.begin(), ghost_nodes.end(), gid);
@@ -393,6 +438,10 @@ void ArbLattice::initDeviceData(pugi::xml_node arb_node, const std::map<std::str
393438
copyVecToDeviceAsync(neighbors_device.get(), nbrs, inStream);
394439
const auto coords = computeCoords();
395440
copyVecToDeviceAsync(coords_device.get(), coords, inStream);
441+
if (connect.has_cuts) {
442+
const auto cuts = computeCutDistances();
443+
copyVecToDeviceAsync(cut_distances_device.get(), cuts, inStream);
444+
}
396445
CudaStreamSynchronize(inStream);
397446
}
398447

@@ -404,6 +453,8 @@ void ArbLattice::initContainer() {
404453
#endif
405454
launcher.container.nbrs = neighbors_device.get();
406455
launcher.container.coords = coords_device.get();
456+
launcher.container.Q = connect.has_cuts ? cut_distances_device.get() : nullptr;
457+
launcher.container.cuts_pitch = sizes.cuts_pitch;
407458
launcher.container.node_types = node_types_device.get();
408459
launcher.container.nbrs_pitch = sizes.neighbors_pitch;
409460
launcher.container.coords_pitch = sizes.coords_pitch;
@@ -843,4 +894,4 @@ void ArbLattice::resetAverage(){
843894
CudaMemset(&getSnapPtr(Snap)[f.id*sizes.snaps_pitch], 0, sizes.snaps_pitch*sizeof(real_t));
844895
}
845896
}
846-
}
897+
}

src/ArbLattice.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class ArbLattice : public LatticeBase {
3333
size_t neighbors_pitch; /// B + I + padding
3434
size_t coords_pitch; /// B + I + padding (should be the same as neighbors_pitch, but let's be extra safe since they come from separate pitched allocation calls)
3535
size_t snaps_pitch; /// B + I + G + 1 + padding
36+
size_t cuts_pitch; /// B + I + padding (should be the same as neighbors_pitch, but same as above)
3637
};
3738

3839
struct CommManager {
@@ -63,6 +64,7 @@ class ArbLattice : public LatticeBase {
6364
std::unordered_map<std::string, int> label_to_ind_map; /// Label string to unique ID
6465
CudaUniquePtr<unsigned> neighbors_device; /// Device allocation of the neighbor table: (B + I) x Q
6566
CudaUniquePtr<real_t> coords_device; /// Device allocation of node coordinates: (B + I) x 3
67+
CudaUniquePtr<cut_t> cut_distances_device; /// Device allocation of cut-distances: (B + I) x 26
6668
CudaUniquePtr<storage_t> snaps_device; /// Device allocation of snaps: (B + I + G + 1) x NF x num_snaps
6769
CudaUniquePtr<flag_t> node_types_device; /// Device allocation of node type array: (B + I)
6870
std::vector<flag_t, pinned_allocator<flag_t> > node_types_host; /// Host (pinned) allocation of node type array: (B + I)
@@ -145,6 +147,7 @@ class ArbLattice : public LatticeBase {
145147
void computeNodeTypesOnHost(pugi::xml_node arb_node, const std::map<std::string, int>& setting_zones, bool permute); /// Compute the node types to be stored on the device, `permute` enables better code reuse
146148
std::vector<real_t> computeCoords() const; /// Compute the coordinates 2D array to be stored on the device
147149
std::vector<unsigned> computeNeighbors() const; /// Compute the neighbors 2D array to be stored on the device
150+
std::vector<cut_t> computeCutDistances() const; /// Compute the cut-distances 2D array to be stored on the device
148151
void initDeviceData(pugi::xml_node arb_node, const std::map<std::string, int>& setting_zones); /// Initialize data residing in device memory
149152
void initCommManager(); /// Compute which fields need to be sent to/received from which neighbors
150153
void initContainer(); /// Initialize the data residing in launcher.container

src/ArbLatticeAccess.hpp.Rt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,9 @@ class ArbLatticeAccess {
8686
CudaDeviceFunction real_t getY() const { return getDim(1); }
8787
CudaDeviceFunction real_t getZ() const { return getDim(2); }
8888
CudaDeviceFunction flag_t getNodeType() const { return node_type; }
89-
CudaDeviceFunction cut_t getQ(int) const { /// TODO
90-
printf("Cuts not implemented for arbitrary lattice");
91-
assert(false);
92-
return NO_CUT;
89+
CudaDeviceFunction cut_t getQ(int d) const {
90+
if (container->Q == nullptr) return NO_CUT;
91+
return container->Q[container->cuts_pitch*d + lid];
9392
}
9493
<?R
9594
for (f in rows(Fields)) { ?>

src/ArbLatticeContainer.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010
struct ArbLatticeContainer {
1111
const unsigned* nbrs;
1212
const real_t* coords;
13+
cut_t* Q; // cut-distances
1314
const storage_t* snap_in;
1415
storage_t* snap_out;
1516
#ifdef ADJOINT
1617
const storage_t* adj_snap_in;
1718
storage_t* adj_snap_out;
1819
#endif
1920
const flag_t* node_types;
20-
unsigned nbrs_pitch, coords_pitch, snaps_pitch, num_border_nodes, num_interior_nodes;
21+
unsigned nbrs_pitch, coords_pitch, cuts_pitch, snaps_pitch, num_border_nodes, num_interior_nodes;
2122

2223
// Packing/unpacking on device
2324
storage_t* pack_buf;

src/toArb.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,14 @@ static auto makeArbLatticeIndexMap(const lbRegion& region, const std::vector<boo
5757
return retval;
5858
}
5959

60-
static int writeArbLatticeHeader(std::fstream& file, size_t n_nodes, double grid_size, const Model& model, const std::map<std::string, int>& zone_map) {
60+
static int writeArbLatticeHeader(std::fstream& file, size_t n_nodes, double grid_size, const Model& model, const std::map<std::string, int>& zone_map, bool has_cuts) {
6161
file << "OFFSET_DIRECTIONS " << Model_m::offset_directions.size() << '\n';
6262
for (const auto [x, y, z] : Model_m::offset_directions) file << x << ' ' << y << ' ' << z << '\n';
6363
file << "GRID_SIZE " << grid_size << '\n';
6464
file << "NODE_LABELS " << model.nodetypeflags.size() + zone_map.size() << '\n';
6565
for (const auto& ntf : model.nodetypeflags) file << ntf.name << '\n';
6666
for (const auto& [name, zf] : zone_map) file << "_Z_" << name << '\n';
67+
if (has_cuts) file << "CUTS 26\n";
6768
file << "NODES " << n_nodes << '\n';
6869
return file.good() ? EXIT_SUCCESS : EXIT_FAILURE;
6970
}
@@ -74,7 +75,8 @@ static int writeArbLatticeNodes(const Geometry& geo,
7475
const std::unordered_map<long, long>& lin_to_arb_index_map,
7576
const std::vector<bool>& bulk_bmp,
7677
std::fstream& file,
77-
double spacing) {
78+
double spacing,
79+
bool has_cuts) {
7880
const long nx = geo.totalregion.nx, ny = geo.totalregion.ny, nz = geo.totalregion.nz;
7981
const auto get_nbr_id = [&](long my_pos, long nbr_pos) -> long {
8082
if (my_pos != nbr_pos && bulk_bmp[my_pos] && bulk_bmp[nbr_pos]) return -1; // ignore edges between bulk nodes
@@ -120,6 +122,15 @@ static int writeArbLatticeNodes(const Geometry& geo,
120122
if (zone_flag == zf) file << gz_ind << ' ';
121123
++gz_ind;
122124
}
125+
126+
if (has_cuts) {
127+
size_t regsize = geo.region.sizeL();
128+
for (int d=0; d < 26; d++){
129+
size_t k = geo.region.offset(x, y, z);
130+
const cut_t q = geo.Q[regsize*d + k];
131+
file << q << ' ';
132+
}
133+
}
123134
file << '\n';
124135
if (!file.good()) break; // Fail early
125136
}
@@ -135,13 +146,14 @@ static int writeArbLattice(const Geometry& geo,
135146
const std::vector<bool>& bulk_bmp,
136147
const std::string& filename,
137148
double spacing) {
149+
const bool has_cuts = geo.Q != nullptr;
138150
std::fstream file(filename, std::ios_base::out);
139151
if (!file.good()) {
140152
ERROR("Failed to open .cxn file for writing");
141153
return EXIT_FAILURE;
142154
}
143-
if (writeArbLatticeHeader(file, lin_to_arb_index_map.size(), spacing, model, zone_map)) return EXIT_FAILURE;
144-
return writeArbLatticeNodes(geo, model, zone_map, lin_to_arb_index_map, bulk_bmp, file, spacing);
155+
if (writeArbLatticeHeader(file, lin_to_arb_index_map.size(), spacing, model, zone_map, has_cuts)) return EXIT_FAILURE;
156+
return writeArbLatticeNodes(geo, model, zone_map, lin_to_arb_index_map, bulk_bmp, file, spacing, has_cuts);
145157
}
146158

147159
static int writeArbXml(const Solver& solver, const Geometry& geo, const Model& model, const std::string& cxn_path) {

0 commit comments

Comments
 (0)