Zoltan2
Loading...
Searching...
No Matches
UserInputForTests.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Zoltan2: A package of combinatorial algorithms for scientific computing
4//
5// Copyright 2012 NTESS and the Zoltan2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
13
14#ifndef USERINPUTFORTESTS
15#define USERINPUTFORTESTS
16
17#include "Tpetra_Access.hpp"
20#include <Zoltan2_Typedefs.hpp>
21
22#include <Tpetra_MultiVector.hpp>
23#include <Tpetra_CrsMatrix.hpp>
24#include <Tpetra_Map.hpp>
25#include <Xpetra_Vector.hpp>
26#include <Xpetra_CrsMatrix.hpp>
27#include <Xpetra_CrsGraph.hpp>
28
29#include <MatrixMarket_Tpetra.hpp>
30
31#ifdef HAVE_ZOLTAN2_GALERI
32#include <Galeri_XpetraProblemFactory.hpp>
33#include <Galeri_XpetraParameters.hpp>
34#endif
35
36#include <Tpetra_KokkosCompat_DefaultNode.hpp>
37
39#include <fstream>
40#include <string>
41
42#include <TpetraExt_MatrixMatrix_def.hpp>
43
44// pamgen required includes
46
47
48using Teuchos::RCP;
49using Teuchos::ArrayRCP;
50using Teuchos::ArrayView;
51using Teuchos::Array;
52using Teuchos::Comm;
53using Teuchos::rcp;
54using Teuchos::arcp;
55using Teuchos::rcp_const_cast;
56using Teuchos::ParameterList;
57using namespace Zoltan2_TestingFramework;
58
86
88
90{
91public:
92
93 typedef Tpetra::Map<zlno_t, zgno_t, znode_t> map_t;
94 typedef Tpetra::Export<zlno_t, zgno_t, znode_t> export_t;
95 typedef Tpetra::Import<zlno_t, zgno_t, znode_t> import_t;
96 typedef map_t::node_type default_znode_t;
97
98
117
118 UserInputForTests(string path, string testData,
119 const RCP<const Comm<int> > &c, bool debugInfo=false,
120 bool distributeInput=true);
121
138 UserInputForTests(int x, int y, int z, string matrixType,
139 const RCP<const Comm<int> > &c, bool debugInfo=false,
140 bool distributeInput=true);
141
157 UserInputForTests(const ParameterList &pList,
158 const RCP<const Comm<int> > &c);
159
162 static void getUIRandomData(unsigned int seed, zlno_t length,
163 zscalar_t min, zscalar_t max, ArrayView<ArrayRCP<zscalar_t > > data);
164
165 RCP<tMVector_t> getUICoordinates();
166
167 RCP<tMVector_t> getUIWeights();
168
169 RCP<tMVector_t> getUIEdgeWeights();
170
171 RCP<tcrsMatrix_t> getUITpetraCrsMatrix();
172
173 RCP<tcrsGraph_t> getUITpetraCrsGraph();
174
175 RCP<tVector_t> getUITpetraVector();
176
177 RCP<tMVector_t> getUITpetraMultiVector(int nvec);
178
179 RCP<xcrsMatrix_t> getUIXpetraCrsMatrix();
180
181 RCP<xcrsGraph_t> getUIXpetraCrsGraph();
182
183 RCP<xVector_t> getUIXpetraVector();
184
185 RCP<xMVector_t> getUIXpetraMultiVector(int nvec);
186
187#ifdef HAVE_ZOLTAN2_PAMGEN
188 PamgenMesh * getPamGenMesh(){return this->pamgen_mesh.operator->();}
189#endif
190
191 bool hasInput();
192
193 bool hasInputDataType(const string &input_type);
194
195 bool hasUICoordinates();
196
197 bool hasUIWeights();
198
199 bool hasUIEdgeWeights();
200
202
203 bool hasUITpetraCrsGraph();
204
205 bool hasUITpetraVector();
206
208
210
211 bool hasUIXpetraCrsGraph();
212
213 bool hasUIXpetraVector();
214
216
217 bool hasPamgenMesh();
218
219private:
220
221 bool verbose_;
222
223 const RCP<const Comm<int> > tcomm_;
224
225 bool havePamgenMesh;
226#ifdef HAVE_ZOLTAN2_PAMGEN
227 RCP<PamgenMesh> pamgen_mesh;
228#endif
229
230 RCP<tcrsMatrix_t> M_;
231 RCP<xcrsMatrix_t> xM_;
232
233 RCP<tMVector_t> xyz_;
234 RCP<tMVector_t> vtxWeights_;
235 RCP<tMVector_t> edgWeights_;
236
237 // Read a Matrix Market file into M_
238 // using Tpetra::MatrixMarket::Reader.
239 // If there are "Tim Davis" style coordinates
240 // that go with the file, read those into xyz_.
241
242 void readMatrixMarketFile(string path, string testData,bool distributeInput = true);
243
244 // Build matrix M_ from a mesh and a problem type
245 // with Galeri::Xpetra.
246
247 void buildCrsMatrix(int xdim, int ydim, int zdim, string type,
248 bool distributeInput);
249
250 // Read a Zoltan1 Chaco or Matrix Market file
251 // into M_. If it has geometric coordinates,
252 // read them into xyz_. If it has weights,
253 // read those into vtxWeights_ and edgWeights_.
254 void readZoltanTestData(string path, string testData,
255 bool distributeInput);
256
257 // Modify the Maps of an input matrix to make them non-contiguous
258 RCP<tcrsMatrix_t> modifyMatrixGIDs(RCP<tcrsMatrix_t> &in);
259 inline zgno_t newID(const zgno_t id) { return id * 2 + 10001; }
260
261 // Read Zoltan data that is in a .graph file.
262 void getUIChacoGraph(FILE *fptr, bool haveAssign, FILE *assignFile,
263 string name, bool distributeInput);
264
265 // Read Zoltan data that is in a .coords file.
266 void getUIChacoCoords(FILE *fptr, string name);
267
268 // Chaco reader code: This code is copied from zoltan/ch.
269 // It might benefit from a rewrite and simplification.
270
271 // Chaco reader helper functions: copied from zoltan/ch
272 static const int CHACO_LINE_LENGTH=200;
273 char chaco_line[CHACO_LINE_LENGTH]; /* space to hold values */
274 int chaco_offset; /* offset into line for next data */
275 int chaco_break_pnt; /* place in sequence to pause */
276 int chaco_save_pnt; /* place in sequence to save */
277
278 double chaco_read_val(FILE* infile, int *end_flag);
279 int chaco_read_int(FILE* infile, int *end_flag);
280 void chaco_flush_line(FILE*);
281
282 // Chaco graph reader: copied from zoltan/ch
283 int chaco_input_graph(FILE *fin, const char *inname, int **start,
284 int **adjacency, int *nvtxs, int *nVwgts,
285 float **vweights, int *nEwgts, float **eweights);
286
287 // Chaco coordinate reader: copied from zoltan/ch
288 int chaco_input_geom(FILE *fingeom, const char *geomname, int nvtxs,
289 int *igeom, double **x, double **y, double **z);
290
291 // Chaco coordinate reader: copied from zoltan/ch
292 int chaco_input_assign(FILE *finassign, const char *assignname, int nvtxs,
293 short *assignments);
294
295
296 // Read a GeomGen.txt file into M_
297 // Read coordinates into xyz_.
298 // If iti has weights read those to vtxWeights_
299 // and edgeWeights_
300 void readGeometricGenTestData(string path, string testData);
301
302 // Geometry Gnearatory helper function
303 void readGeoGenParams(string paramFileName,
304 ParameterList &geoparams);
305
306 // utility methods used when reading geom gen files
307
308 static string trim_right_copy(const string& s,
309 const string& delimiters = " \f\n\r\t\v" );
310
311 static string trim_left_copy(const string& s,
312 const string& delimiters = " \f\n\r\t\v" );
313
314 static string trim_copy(const string& s,
315 const string& delimiters = " \f\n\r\t\v" );
316
317
318 // Read a pamgen mesh
319 void readPamgenMeshFile(string path, string testData);
320#ifdef HAVE_ZOLTAN2_PAMGEN
321 void setPamgenAdjacencyGraph();
322 void setPamgenCoordinateMV();
323#endif
324};
325
326UserInputForTests::UserInputForTests(string path, string testData,
327 const RCP<const Comm<int> > &c,
328 bool debugInfo, bool distributeInput):
329verbose_(debugInfo), tcomm_(c), havePamgenMesh(false),
330M_(), xM_(), xyz_(), vtxWeights_(), edgWeights_(),
331chaco_offset(0), chaco_break_pnt(CHACO_LINE_LENGTH)
332{
333 bool zoltan1 = false;
334 string::size_type loc = path.find("/zoltan/test/"); // Zoltan1 data
335 if (loc != string::npos)
336 zoltan1 = true;
337
338 if (zoltan1)
339 readZoltanTestData(path, testData, distributeInput);
340 else
341 readMatrixMarketFile(path, testData);
342}
343
345 string matrixType,
346 const RCP<const Comm<int> > &c,
347 bool debugInfo,
348 bool distributeInput):
349verbose_(debugInfo), tcomm_(c), havePamgenMesh(false),
350M_(), xM_(), xyz_(), vtxWeights_(), edgWeights_(),
351chaco_offset(0), chaco_break_pnt(CHACO_LINE_LENGTH)
352{
353 if (matrixType.size() == 0){
354 int dim = 0;
355 if (x > 0) dim++;
356 if (y > 0) dim++;
357 if (z > 0) dim++;
358 if (dim == 1)
359 matrixType = string("Laplace1D");
360 else if (dim == 2)
361 matrixType = string("Laplace2D");
362 else if (dim == 3)
363 matrixType = string("Laplace3D");
364 else
365 throw std::runtime_error("input");
366
367 if (verbose_ && tcomm_->getRank() == 0)
368 std::cout << "UserInputForTests, Matrix type : " << matrixType << std::endl;
369 }
370
371 buildCrsMatrix(x, y, z, matrixType, distributeInput);
372}
373
374UserInputForTests::UserInputForTests(const ParameterList &pList,
375 const RCP<const Comm<int> > &c):
376tcomm_(c), havePamgenMesh(false),
377M_(), xM_(), xyz_(), vtxWeights_(), edgWeights_(),
378chaco_offset(0), chaco_break_pnt(CHACO_LINE_LENGTH)
379{
380
381 // get options
382 bool distributeInput = true, debugInfo = true;
383
384 if(pList.isParameter("distribute input"))
385 distributeInput = pList.get<bool>("distribute input");
386
387 if(pList.isParameter("debug"))
388 debugInfo = pList.get<bool>("debug");
389 this->verbose_ = debugInfo;
390
391 if(pList.isParameter("input file"))
392 {
393
394 // get input path
395 string path(".");
396 if(pList.isParameter("input path"))
397 path = pList.get<string>("input path");
398
399 string testData = pList.get<string>("input file");
400
401 // find out if we are working from the zoltan1 test diretory
402 USERINPUT_FILE_FORMATS file_format = MATRIX_MARKET;
403
404 // find out if we are using the geometric generator
405 if(pList.isParameter("file type") && pList.get<string>("file type") == "Geometric Generator")
406 file_format = GEOMGEN;
407 else if(pList.isParameter("file type") && pList.get<string>("file type") == "Pamgen")
408 {
409 file_format = PAMGEN;
410 }
411 else if(pList.isParameter("file type") && pList.get<string>("file type") == "Chaco")
412 file_format = CHACO; // this flag calls read ZoltanTestData, which calls the chaco readers...
413
414 // read the input file
415 switch (file_format) {
416 case GEOMGEN: readGeometricGenTestData(path,testData); break;
417 case PAMGEN: readPamgenMeshFile(path,testData); break;
418 case CHACO: readZoltanTestData(path, testData, distributeInput); break;
419 default: readMatrixMarketFile(path, testData, distributeInput); break;
420 }
421
422 }else if(pList.isParameter("x") || pList.isParameter("y") || pList.isParameter("z")){
423
424 int x,y,z;
425 x = y = z = 0;
426 if(pList.isParameter("x")) x = pList.get<int>("x");
427 if(pList.isParameter("y")) y = pList.get<int>("y");
428 if(pList.isParameter("z")) z = pList.get<int>("z");
429
430 string problemType = "";
431 if(pList.isParameter("equation type")) problemType = pList.get<string>("equation type");
432
433 if (problemType.size() == 0){
434 int dim = 0;
435 if (x > 0) dim++;
436 if (y > 0) dim++;
437 if (z > 0) dim++;
438 if (dim == 1)
439 problemType = string("Laplace1D");
440 else if (dim == 2)
441 problemType = string("Laplace2D");
442 else if (dim == 3)
443 problemType = string("Laplace3D");
444 else
445 throw std::runtime_error("input");
446
447 if (verbose_ && tcomm_->getRank() == 0)
448 std::cout << "UserInputForTests, Matrix type : " << problemType << std::endl;
449 }
450
451
452 buildCrsMatrix(x, y, z, problemType, distributeInput);
453
454 }else{
455 std::cerr << "Input file block undefined!" << std::endl;
456 }
457
458}
459
460
461RCP<Zoltan2_TestingFramework::tMVector_t> UserInputForTests::getUICoordinates()
462{
463 if (xyz_.is_null())
464 throw std::runtime_error("could not read coord file");
465 return xyz_;
466}
467
468RCP<Zoltan2_TestingFramework::tMVector_t> UserInputForTests::getUIWeights()
469{
470 return vtxWeights_;
471}
472
473RCP<Zoltan2_TestingFramework::tMVector_t> UserInputForTests::getUIEdgeWeights()
474{
475 return edgWeights_;
476}
477
478RCP<Zoltan2_TestingFramework::tcrsMatrix_t> UserInputForTests::getUITpetraCrsMatrix()
479{
480 if (M_.is_null())
481 throw std::runtime_error("could not read mtx file");
482 return M_;
483}
484
485RCP<Zoltan2_TestingFramework::tcrsGraph_t> UserInputForTests::getUITpetraCrsGraph()
486{
487 if (M_.is_null())
488 throw std::runtime_error("could not read mtx file");
489 return rcp_const_cast<tcrsGraph_t>(M_->getCrsGraph());
490}
491
492RCP<Zoltan2_TestingFramework::tVector_t> UserInputForTests::getUITpetraVector()
493{
494 RCP<tVector_t> V = rcp(new tVector_t(M_->getRowMap(), 1));
495 V->randomize();
496
497 return V;
498}
499
500RCP<Zoltan2_TestingFramework::tMVector_t> UserInputForTests::getUITpetraMultiVector(int nvec)
501{
502 RCP<tMVector_t> mV = rcp(new tMVector_t(M_->getRowMap(), nvec));
503 mV->randomize();
504
505 return mV;
506}
507
508RCP<Zoltan2_TestingFramework::xcrsMatrix_t> UserInputForTests::getUIXpetraCrsMatrix()
509{
510 if (M_.is_null())
511 throw std::runtime_error("could not read mtx file");
512 return xM_;
513}
514
515RCP<Zoltan2_TestingFramework::xcrsGraph_t> UserInputForTests::getUIXpetraCrsGraph()
516{
517 if (M_.is_null())
518 throw std::runtime_error("could not read mtx file");
519 return rcp_const_cast<xcrsGraph_t>(xM_->getCrsGraph());
520}
521
522RCP<Zoltan2_TestingFramework::xVector_t> UserInputForTests::getUIXpetraVector()
523{
525}
526
527RCP<Zoltan2_TestingFramework::xMVector_t> UserInputForTests::getUIXpetraMultiVector(int nvec)
528{
529 RCP<tMVector_t> tMV = getUITpetraMultiVector(nvec);
531}
532
534{
535 // find out if an input source has been loaded
536 return this->hasUICoordinates() || \
537 this->hasUITpetraCrsMatrix() || \
538 this->hasUITpetraCrsGraph() || \
539 this->hasPamgenMesh();
540}
541
542bool UserInputForTests::hasInputDataType(const string &input_type)
543{
544 if(input_type == "coordinates")
545 return this->hasUICoordinates();
546 else if(input_type == "tpetra_vector")
547 return this->hasUITpetraVector();
548 else if(input_type == "tpetra_multivector")
549 return this->hasUITpetraMultiVector();
550 else if(input_type == "tpetra_crs_graph")
551 return this->hasUITpetraCrsGraph();
552 else if(input_type == "tpetra_crs_matrix")
553 return this->hasUITpetraCrsMatrix();
554 else if(input_type == "xpetra_vector")
555 return this->hasUIXpetraVector();
556 else if(input_type == "xpetra_multivector")
557 return this->hasUIXpetraMultiVector();
558 else if(input_type == "xpetra_crs_graph")
559 return this->hasUIXpetraCrsGraph();
560 else if(input_type == "xpetra_crs_matrix")
561 return this->hasUIXpetraCrsMatrix();
562
563 return false;
564}
565
567{
568 return xyz_.is_null() ? false : true;
569}
570
572{
573 return vtxWeights_.is_null() ? false : true;
574}
575
577{
578 return edgWeights_.is_null() ? false : true;
579}
580
582{
583 return M_.is_null() ? false : true;
584}
585
587{
588 return M_.is_null() ? false : true;
589}
590
592{
593 return true;
594}
595
597{
598 return true;
599}
600
602{
603 return M_.is_null() ? false : true;
604}
605
607{
608 return M_.is_null() ? false : true;
609}
610
612{
613 return true;
614}
615
617{
618 return true;
619}
620
622{
623 return this->havePamgenMesh;
624}
625
626void UserInputForTests::getUIRandomData(unsigned int seed, zlno_t length,
627 zscalar_t min, zscalar_t max,
628 ArrayView<ArrayRCP<zscalar_t > > data)
629{
630 if (length < 1)
631 return;
632
633 size_t dim = data.size();
634 for (size_t i=0; i < dim; i++){
635 zscalar_t *tmp = new zscalar_t [length];
636 if (!tmp)
637 throw (std::bad_alloc());
638 data[i] = Teuchos::arcp(tmp, 0, length, true);
639 }
640
641 zscalar_t scalingFactor = (max-min) / RAND_MAX;
642 srand(seed);
643 for (size_t i=0; i < dim; i++){
644 zscalar_t *x = data[i].getRawPtr();
645 for (zlno_t j=0; j < length; j++)
646 *x++ = min + (zscalar_t(rand()) * scalingFactor);
647 }
648}
649
650// utility methods used when reading geom gen files
651
652string UserInputForTests::trim_right_copy(
653 const string& s,
654 const string& delimiters)
655{
656 return s.substr( 0, s.find_last_not_of( delimiters ) + 1 );
657}
658
659string UserInputForTests::trim_left_copy(
660 const string& s,
661 const string& delimiters)
662{
663 return s.substr( s.find_first_not_of( delimiters ) );
664}
665
666string UserInputForTests::trim_copy(
667 const string& s,
668 const string& delimiters)
669{
670 return trim_left_copy( trim_right_copy( s, delimiters ), delimiters );
671}
672
673void UserInputForTests::readGeometricGenTestData(string path,
674 string testData)
675{
676
677 std::ostringstream fname;
678 fname << path << "/" << testData << ".txt";
679
680 if (verbose_ && tcomm_->getRank() == 0)
681 std::cout << "UserInputForTests, Read: " << fname.str() << std::endl;
682
683 Teuchos::ParameterList geoparams("geo params");
684 readGeoGenParams(fname.str(),geoparams);
685
686 geometricgen_t * gg = new geometricgen_t(geoparams, this->tcomm_);
687
688 // get coordinate and point info
689 int coord_dim = gg->getCoordinateDimension();
690 int numWeightsPerCoord = gg->getNumWeights();
691 zlno_t numLocalPoints = gg->getNumLocalCoords();
692 zgno_t numGlobalPoints = gg->getNumGlobalCoords();
693
694 // allocate an array of coordinate arrays
695 zscalar_t **coords = new zscalar_t * [coord_dim];
696 for(int i = 0; i < coord_dim; ++i){
697 coords[i] = new zscalar_t[numLocalPoints];
698 }
699
700 // get a copy of the data
701 gg->getLocalCoordinatesCopy(coords);
702
703 // get an array of arrays of weight data (if any)
704 zscalar_t **weight = NULL;
705 if (numWeightsPerCoord) {
706 // memory allocation
707 weight = new zscalar_t * [numWeightsPerCoord];
708 for(int i = 0; i < numWeightsPerCoord; ++i){
709 weight[i] = new zscalar_t[numLocalPoints];
710 }
711
712 // get a copy of the weight data
713 gg->getLocalWeightsCopy(weight);
714 }
715
716 delete gg; // free up memory from geom gen
717
718
719 // make a Tpetra map
720 RCP<Tpetra::Map<zlno_t, zgno_t, znode_t> > mp =
721 rcp(new Tpetra::Map<zlno_t, zgno_t, znode_t>(numGlobalPoints, numLocalPoints, 0, this->tcomm_));
722
723 // make an array of array views containing the coordinate data
724 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > coordView(coord_dim);
725 for (int i=0; i < coord_dim; i++){
726 if(numLocalPoints > 0){
727 Teuchos::ArrayView<const zscalar_t> a(coords[i], numLocalPoints);
728 coordView[i] = a;
729 }
730 else {
731 Teuchos::ArrayView<const zscalar_t> a;
732 coordView[i] = a;
733 }
734 }
735
736 // set the xyz_ multivector
737 xyz_ = RCP<tMVector_t>(new
738 tMVector_t(mp, coordView.view(0, coord_dim),
739 coord_dim));
740
741 // set the vtx weights
742 if (numWeightsPerCoord) {
743 // make an array of array views containing the weight data
744 Teuchos::Array<Teuchos::ArrayView<const zscalar_t> > weightView(numWeightsPerCoord);
745 for (int i=0; i < numWeightsPerCoord; i++){
746 if(numLocalPoints > 0){
747 Teuchos::ArrayView<const zscalar_t> a(weight[i], numLocalPoints);
748 weightView[i] = a;
749 }
750 else {
751 Teuchos::ArrayView<const zscalar_t> a;
752 weightView[i] = a;
753 }
754 }
755
756 vtxWeights_ = RCP<tMVector_t>(new tMVector_t(mp, weightView.view(0, numWeightsPerCoord),
757 numWeightsPerCoord));
758 for(int i = 0; i < coord_dim; ++i) delete [] coords[i];
759 delete [] coords;
760 if(numWeightsPerCoord) {
761 for(int i = 0; i < numWeightsPerCoord; ++i) delete [] weight[i];
762 delete [] weight;
763 }
764 }
765}
766
767void UserInputForTests::readGeoGenParams(string paramFileName,
768 ParameterList &geoparams){
769
770 const char param_comment = '#';
771
772 std::string input = "";
773 char inp[25000];
774 for(int i = 0; i < 25000; ++i){
775 inp[i] = 0;
776 }
777
778 bool fail = false;
779 if(this->tcomm_->getRank() == 0){
780
781 std::fstream inParam(paramFileName.c_str());
782 if (inParam.fail())
783 {
784 fail = true;
785 }
786 if(!fail)
787 {
788 std::string tmp = "";
789 getline (inParam,tmp);
790 while (!inParam.eof()){
791 if(tmp != ""){
792 tmp = trim_copy(tmp);
793 if(tmp != ""){
794 input += tmp + "\n";
795 }
796 }
797 getline (inParam,tmp);
798 }
799 inParam.close();
800 for (size_t i = 0; i < input.size(); ++i){
801 inp[i] = input[i];
802 }
803 }
804 }
805
806
807
808 int size = (int)input.size();
809 if(fail){
810 size = -1;
811 }
812 this->tcomm_->broadcast(0, sizeof(int), (char*) &size);
813 if(size == -1){
814 throw "File " + paramFileName + " cannot be opened.";
815 }
816 this->tcomm_->broadcast(0, size, inp);
817 std::istringstream inParam(inp);
818 string str;
819 getline (inParam,str);
820 while (!inParam.eof()){
821 if(str[0] != param_comment){
822 size_t pos = str.find('=');
823 if(pos == string::npos){
824 throw "Invalid Line:" + str + " in parameter file";
825 }
826 string paramname = trim_copy(str.substr(0,pos));
827 string paramvalue = trim_copy(str.substr(pos + 1));
828 geoparams.set(paramname, paramvalue);
829 }
830 getline (inParam,str);
831 }
832}
833
835RCP<tcrsMatrix_t> UserInputForTests::modifyMatrixGIDs(
836 RCP<tcrsMatrix_t> &inMatrix
837)
838{
839 // Produce a new matrix with the same structure as inMatrix,
840 // but whose row/column GIDs are non-contiguous values.
841 // In this case GID g in inMatrix becomes g*2+1 in outMatrix.
842
843 // Create the map for the new matrix: same structure as inMap but with
844 // the GIDs modified.
845 RCP<const map_t> inMap = inMatrix->getRowMap();
846
847 size_t nRows = inMap->getLocalNumElements();
848 auto inRows = inMap->getMyGlobalIndices();
849 Teuchos::Array<zgno_t> outRows(nRows);
850 for (size_t i = 0; i < nRows; i++) {
851 outRows[i] = newID(inRows[i]);
852 }
853
854 Tpetra::global_size_t nGlobalRows = inMap->getGlobalNumElements();
855 RCP<map_t> outMap = rcp(new map_t(nGlobalRows, outRows(), 0,
856 inMap->getComm()));
857
858#ifdef INCLUDE_LENGTHY_OUTPUT
859 // Sanity check output
860 {
861 std::cout << inMap->getComm()->getRank() << " KDDKDD "
862 << "nGlobal " << inMap->getGlobalNumElements() << " "
863 << outMap->getGlobalNumElements() << "; "
864 << "nLocal " << inMap->getLocalNumElements() << " "
865 << outMap->getLocalNumElements() << "; "
866 << std::endl;
867 std::cout << inMap->getComm()->getRank() << " KDDKDD ";
868 for (size_t i = 0; i < nRows; i++)
869 std::cout << "(" << inMap->getMyGlobalIndices()[i] << ", "
870 << outMap->getMyGlobalIndices()[i] << ") ";
871 std::cout << std::endl;
872 }
873#endif // INCLUDE_LENGTHY_OUTPUT
874
875 // Create a new matrix using the new map
876 // Get the length of the longest row; allocate memory.
877 size_t rowLen = inMatrix->getLocalMaxNumRowEntries();
878 RCP<tcrsMatrix_t> outMatrix = rcp(new tcrsMatrix_t(outMap, rowLen));
879
880 typename tcrsMatrix_t::nonconst_global_inds_host_view_type indices("Indices", rowLen);
881 typename tcrsMatrix_t::nonconst_values_host_view_type values("Values", rowLen);
882
883 for (size_t i = 0; i < nRows; i++) {
884 size_t nEntries;
885 zgno_t inGid = inMap->getGlobalElement(i);
886 inMatrix->getGlobalRowCopy(inGid, indices, values, nEntries);
887 for (size_t j = 0; j < nEntries; j++)
888 indices[j] = newID(indices[j]);
889
890 zgno_t outGid = outMap->getGlobalElement(i);
891 ArrayView<zgno_t> Indices(indices.data(), nEntries);
892 ArrayView<zscalar_t> Values(values.data(), nEntries);
893 outMatrix->insertGlobalValues(outGid, Indices(0, nEntries),
894 Values(0, nEntries));
895 }
896 outMatrix->fillComplete();
897
898#ifdef INCLUDE_LENGTHY_OUTPUT
899 // Sanity check output
900 {
901 std::cout << inMap->getComm()->getRank() << " KDDKDD Rows "
902 << "nGlobal " << inMatrix->getGlobalNumRows() << " "
903 << outMatrix->getGlobalNumRows() << "; "
904 << "nLocal " << inMatrix->getLocalNumRows() << " "
905 << outMatrix->getLocalNumRows() << std::endl;
906 std::cout << inMap->getComm()->getRank() << " KDDKDD NNZS "
907 << "nGlobal " << inMatrix->getGlobalNumEntries() << " "
908 << outMatrix->getGlobalNumEntries() << "; "
909 << "nLocal " << inMatrix->getLocalNumEntries() << " "
910 << outMatrix->getLocalNumEntries() << std::endl;
911
912 size_t nIn, nOut;
913 Teuchos::Array<zgno_t> in(rowLen), out(rowLen);
914 Teuchos::Array<zscalar_t> inval(rowLen), outval(rowLen);
915
916 for (size_t i = 0; i < nRows; i++) {
917 std::cout << inMap->getComm()->getRank() << " KDDKDD " << i << " nnz(";
918 inMatrix->getGlobalRowCopy(inMap->getGlobalElement(i), in, inval, nIn);
919 outMatrix->getGlobalRowCopy(outMap->getGlobalElement(i), out, outval,
920 nOut);
921
922 std::cout << nIn << ", " << nOut << "): ";
923 for (size_t j = 0; j < nIn; j++) {
924 std::cout << "(" << in[j] << " " << inval[j] << ", "
925 << out[j] << " " << outval[j] << ") ";
926 }
927 std::cout << std::endl;
928 }
929 }
930#endif // INCLUDE_LENGTHY_OUTPUT
931
932 return outMatrix;
933}
934
936
937void UserInputForTests::readMatrixMarketFile(
938 string path,
939 string testData,
940 bool distributeInput
941)
942{
943 std::ostringstream fname;
944 fname << path << "/" << testData << ".mtx";
945
946 if (verbose_ && tcomm_->getRank() == 0)
947 std::cout << "UserInputForTests, Read: " << fname.str() << std::endl;
948
949 // FIXME (mfh 01 Aug 2016) Tpetra::MatrixMarket::Reader has a graph
950 // ("pattern" matrix) reader. Call its readSparseGraphFile method.
951
952 RCP<tcrsMatrix_t> toMatrix;
953 RCP<tcrsMatrix_t> fromMatrix;
954 bool aok = true;
955 try{
956 typedef Tpetra::MatrixMarket::Reader<tcrsMatrix_t> reader_type;
957 fromMatrix = reader_type::readSparseFile(fname.str(), tcomm_,
958 true, false, false);
959#ifdef KDD_NOT_READY_YET
960 // See note below about modifying coordinate IDs as well.
961 //if (makeNonContiguous)
962 fromMatrix = modifyMatrixGIDs(fromMatrix);
963#endif
964
965 if(!distributeInput)
966 {
967 if (verbose_ && tcomm_->getRank() == 0)
968 std::cout << "Constructing serial distribution of matrix" << std::endl;
969 // need to make a serial map and then import the data to redistribute it
970 RCP<const map_t> fromMap = fromMatrix->getRowMap();
971
972 size_t numGlobalCoords = fromMap->getGlobalNumElements();
973 size_t numLocalCoords = this->tcomm_->getRank() == 0 ? numGlobalCoords : 0;
974 RCP<const map_t> toMap = rcp(new map_t(numGlobalCoords,numLocalCoords, 0, tcomm_));
975
976 RCP<import_t> importer = rcp(new import_t(fromMap, toMap));
977 toMatrix = rcp(new tcrsMatrix_t(toMap,0));
978 toMatrix->doImport(*fromMatrix, *importer, Tpetra::INSERT);
979 toMatrix->fillComplete();
980
981 }else{
982 toMatrix = fromMatrix;
983 }
984 }catch (std::exception &e) {
985 if (tcomm_->getRank() == 0) {
986 std::cout << "UserInputForTests unable to read matrix market file:"
987 << fname.str() << std::endl;
988 std::cout << e.what() << std::endl;
989 }
990 aok = false;
991 }
992 TEST_FAIL_AND_THROW(*tcomm_, aok,
993 "UserInputForTests unable to read matrix market file");
994
995 M_ = toMatrix;
996#ifdef INCLUDE_LENGTHY_OUTPUT
997 std::cout << tcomm_->getRank() << " KDDKDD " << M_->getLocalNumRows()
998 << " " << M_->getGlobalNumRows()
999 << " " << M_->getLocalNumEntries()
1000 << " " << M_->getGlobalNumEntries() << std::endl;
1001#endif // INCLUDE_LENGTHY_OUTPUT
1002
1004
1005 // Open the coordinate file.
1006
1007 fname.str("");
1008 fname << path << "/" << testData << "_coord.mtx";
1009
1010 size_t coordDim = 0, numGlobalCoords = 0;
1011 size_t msg[2]={0,0};
1012 ArrayRCP<ArrayRCP<zscalar_t> > xyz;
1013 std::ifstream coordFile;
1014
1015 if (tcomm_->getRank() == 0){
1016
1017 if (verbose_)
1018 std::cout << "UserInputForTests, Read: " <<
1019 fname.str() << std::endl;
1020
1021 int fail = 0;
1022 try{
1023 coordFile.open(fname.str().c_str());
1024 }
1025 catch (std::exception &){ // there is no coordinate file
1026 fail = 1;
1027 }
1028
1029 if (!fail){
1030
1031 // Read past banner to number and dimension of coordinates.
1032
1033 char c[256];
1034 bool done=false;
1035
1036 while (!done && !fail && coordFile.good()){
1037 coordFile.getline(c, 256);
1038 if (!c[0])
1039 fail = 1;
1040 else if (c[0] == '%')
1041 continue;
1042 else {
1043 done=true;
1044 std::istringstream s(c);
1045 s >> numGlobalCoords >> coordDim;
1046 if (!s.eof() || numGlobalCoords < 1 || coordDim < 1)
1047 fail=1;
1048 }
1049 }
1050
1051 if (done){
1052
1053 // Read in the coordinates.
1054
1055 xyz = Teuchos::arcp(new ArrayRCP<zscalar_t> [coordDim], 0, coordDim);
1056
1057 for (size_t dim=0; !fail && dim < coordDim; dim++){
1058 size_t idx;
1059 zscalar_t *tmp = new zscalar_t [numGlobalCoords];
1060 if (!tmp)
1061 fail = 1;
1062 else{
1063 xyz[dim] = Teuchos::arcp(tmp, 0, numGlobalCoords);
1064
1065 for (idx=0; !coordFile.eof() && idx < numGlobalCoords; idx++){
1066 coordFile.getline(c, 256);
1067 std::istringstream s(c);
1068 s >> tmp[idx];
1069 }
1070
1071 if (idx < numGlobalCoords)
1072 fail = 1;
1073 }
1074 }
1075
1076 if (fail){
1077 ArrayRCP<zscalar_t> emptyArray;
1078 for (size_t dim=0; dim < coordDim; dim++)
1079 xyz[dim] = emptyArray; // free the memory
1080
1081 coordDim = 0;
1082 }
1083 }
1084 else{
1085 fail = 1;
1086 }
1087
1088 coordFile.close();
1089 }
1090
1091 msg[0] = coordDim;
1092 msg[1] = numGlobalCoords;
1093 }
1094
1095 // Broadcast coordinate dimension
1096 Teuchos::broadcast<int, size_t>(*tcomm_, 0, 2, msg);
1097
1098 coordDim = msg[0];
1099 numGlobalCoords = msg[1];
1100
1101 if (coordDim == 0)
1102 return;
1103
1104 zgno_t base = 0;
1105 RCP<const map_t> toMap;
1106
1107 if (!M_.is_null()){
1108 const RCP<const map_t> &mapM = M_->getRowMap();
1109 toMap = mapM;
1110 }
1111 else{
1112 if (verbose_ && tcomm_->getRank() == 0)
1113 {
1114 std::cout << "Matrix was null. ";
1115 std::cout << "Constructing distribution map for coordinate vector."
1116 << std::endl;
1117 }
1118
1119 if(!distributeInput)
1120 {
1121 if (verbose_ && tcomm_->getRank() == 0)
1122 std::cout << "Constructing serial distribution map for coordinates."
1123 << std::endl;
1124
1125 size_t numLocalCoords = this->tcomm_->getRank()==0 ? numGlobalCoords : 0;
1126 toMap = rcp(new map_t(numGlobalCoords,numLocalCoords, base, tcomm_));
1127 }else{
1128 toMap = rcp(new map_t(numGlobalCoords, base, tcomm_));
1129 }
1130 }
1131
1132 // Export coordinates to their owners
1133
1134 xyz_ = rcp(new tMVector_t(toMap, coordDim));
1135
1136 ArrayRCP<ArrayView<const zscalar_t> > coordLists(coordDim);
1137
1138 if (tcomm_->getRank() == 0){
1139
1140 for (size_t dim=0; dim < coordDim; dim++)
1141 coordLists[dim] = xyz[dim].view(0, numGlobalCoords);
1142
1143 zgno_t *tmp = new zgno_t [numGlobalCoords];
1144 if (!tmp)
1145 throw std::bad_alloc();
1146
1147 ArrayRCP<const zgno_t> rowIds = Teuchos::arcp(tmp, 0, numGlobalCoords);
1148
1149#ifdef KDD_NOT_READY_YET
1150 // TODO if modifyMatrixGIDs, we need to modify ids here as well
1151 for (zgno_t id=0; id < zgno_t(numGlobalCoords); id++)
1152 *tmp++ = newID(id);
1153#else
1154 for (zgno_t id=0; id < zgno_t(numGlobalCoords); id++)
1155 *tmp++ = id;
1156#endif
1157
1158 RCP<const map_t> fromMap = rcp(new map_t(numGlobalCoords,
1159 rowIds.view(0, numGlobalCoords),
1160 base, tcomm_));
1161
1162 tMVector_t allCoords(fromMap, coordLists.view(0, coordDim), coordDim);
1163
1164 export_t exporter(fromMap, toMap);
1165
1166 xyz_->doExport(allCoords, exporter, Tpetra::INSERT);
1167 }
1168 else{
1169
1170 RCP<const map_t> fromMap = rcp(new map_t(numGlobalCoords,
1171 ArrayView<zgno_t>(), base, tcomm_));
1172
1173 tMVector_t allCoords(fromMap, coordLists.view(0, coordDim), coordDim);
1174
1175 export_t exporter(fromMap, toMap);
1176
1177 xyz_->doExport(allCoords, exporter, Tpetra::INSERT);
1178 }
1179}
1180
1181void UserInputForTests::buildCrsMatrix(int xdim, int ydim, int zdim,
1182 string problemType, bool distributeInput)
1183{
1184#ifdef HAVE_ZOLTAN2_GALERI
1185 Teuchos::CommandLineProcessor tclp;
1186 Galeri::Xpetra::Parameters<zgno_t> params(tclp,
1187 xdim, ydim, zdim, problemType);
1188
1189 RCP<const Tpetra::Map<zlno_t, zgno_t> > map;
1190 if (distributeInput)
1191 map = rcp(new Tpetra::Map<zlno_t, zgno_t>(params.GetNumGlobalElements(),
1192 0, tcomm_));
1193 else {
1194 // All data initially on rank 0
1195 size_t nGlobalElements = params.GetNumGlobalElements();
1196 size_t nLocalElements = ((tcomm_->getRank() == 0) ? nGlobalElements : 0);
1197 map = rcp(new Tpetra::Map<zlno_t, zgno_t>(nGlobalElements, nLocalElements, 0,
1198 tcomm_));
1199 }
1200
1201 if (verbose_ && tcomm_->getRank() == 0){
1202
1203 std::cout << "Matrix is " << (distributeInput ? "" : "not");
1204 std::cout << "distributed." << std::endl;
1205
1206 std::cout << "UserInputForTests, Create matrix with " << problemType;
1207 std::cout << " (and " << xdim;
1208 if (zdim > 0)
1209 std::cout << " x " << ydim << " x " << zdim;
1210 else if (ydim > 0)
1211 std::cout << " x" << ydim << " x 1";
1212 else
1213 std::cout << "x 1 x 1";
1214
1215 std::cout << " mesh)" << std::endl;
1216
1217 }
1218
1219 bool aok = true;
1220 try{
1221 RCP<Galeri::Xpetra::Problem<Tpetra::Map<zlno_t, zgno_t>, Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t>, Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t> > > Pr =
1222 Galeri::Xpetra::BuildProblem<zscalar_t, zlno_t, zgno_t, Tpetra::Map<zlno_t, zgno_t>, Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t>, Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t> >
1223 (params.GetMatrixType(), map, params.GetParameterList());
1224 M_ = Pr->BuildMatrix();
1225 }
1226 catch (std::exception &) { // Probably not enough memory
1227 aok = false;
1228 }
1229 TEST_FAIL_AND_THROW(*tcomm_, aok,
1230 "UserInputForTests Galeri::Xpetra::BuildProblem failed");
1231
1233
1234 // Compute the coordinates for the matrix rows.
1235
1236 if (verbose_ && tcomm_->getRank() == 0)
1237 std::cout <<
1238 "UserInputForTests, Implied matrix row coordinates computed" <<
1239 std::endl;
1240
1241 ArrayView<const zgno_t> gids = map->getLocalElementList();
1242 zlno_t count = static_cast<zlno_t>(gids.size());
1243 int dim = 3;
1244 size_t pos = problemType.find("2D");
1245 if (pos != string::npos)
1246 dim = 2;
1247 else if (problemType == string("Laplace1D") ||
1248 problemType == string("Identity"))
1249 dim = 1;
1250
1251 Array<ArrayRCP<zscalar_t> > coordinates(dim);
1252
1253 if (count > 0){
1254 for (int i=0; i < dim; i++){
1255 zscalar_t *c = new zscalar_t [count];
1256 if (!c)
1257 throw(std::bad_alloc());
1258 coordinates[i] = Teuchos::arcp(c, 0, count, true);
1259 }
1260
1261 if (dim==3){
1262 zscalar_t *x = coordinates[0].getRawPtr();
1263 zscalar_t *y = coordinates[1].getRawPtr();
1264 zscalar_t *z = coordinates[2].getRawPtr();
1265 zgno_t xySize = xdim * ydim;
1266 for (zlno_t i=0; i < count; i++){
1267 zgno_t iz = gids[i] / xySize;
1268 zgno_t xy = gids[i] - iz*xySize;
1269 z[i] = zscalar_t(iz);
1270 y[i] = zscalar_t(xy / xdim);
1271 x[i] = zscalar_t(xy % xdim);
1272 }
1273 }
1274 else if (dim==2){
1275 zscalar_t *x = coordinates[0].getRawPtr();
1276 zscalar_t *y = coordinates[1].getRawPtr();
1277 for (zlno_t i=0; i < count; i++){
1278 y[i] = zscalar_t(gids[i] / xdim);
1279 x[i] = zscalar_t(gids[i] % xdim);
1280 }
1281 }
1282 else{
1283 zscalar_t *x = coordinates[0].getRawPtr();
1284 for (zlno_t i=0; i < count; i++)
1285 x[i] = zscalar_t(gids[i]);
1286 }
1287 }
1288
1289 Array<ArrayView<const zscalar_t> > coordView(dim);
1290 if (count > 0)
1291 for (int i=0; i < dim; i++)
1292 coordView[i] = coordinates[i].view(0,count);
1293
1294 xyz_ = rcp(new tMVector_t(map, coordView.view(0, dim), dim));
1295#else
1296 throw std::runtime_error("Galeri input requested but Trilinos is "
1297 "not built with Galeri.");
1298#endif
1299}
1300
1301void UserInputForTests::readZoltanTestData(string path, string testData,
1302 bool distributeInput)
1303{
1304 int rank = tcomm_->getRank();
1305 FILE *graphFile = NULL;
1306 FILE *coordFile = NULL;
1307 FILE *assignFile = NULL;
1308 int fileInfo[3];
1309
1310 for (int i = 0; i < CHACO_LINE_LENGTH; i++) chaco_line[i] = '\0';
1311
1312 if (rank == 0){
1313 // set chacho graph file name
1314 std::ostringstream chGraphFileName;
1315 chGraphFileName << path << "/" << testData << ".graph";
1316
1317 // set chaco graph
1318 std::ostringstream chCoordFileName;
1319 chCoordFileName << path << "/" << testData << ".coords";
1320
1321 // set chaco graph
1322 std::ostringstream chAssignFileName;
1323 chAssignFileName << path << "/" << testData << ".assign";
1324
1325 // open file
1326 graphFile = fopen(chGraphFileName.str().c_str(), "r");
1327
1328 if(!graphFile) // maybe the user is using the default zoltan1 path convention
1329 {
1330 chGraphFileName.str("");
1331 chCoordFileName.str("");
1332 // try constructing zoltan1 paths
1333 chGraphFileName << path << "/ch_" << testData << "/" << testData << ".graph";
1334 chCoordFileName << path << "/ch_" << testData << "/" << testData << ".coords";
1335 chAssignFileName << path << "/ch_" << testData << "/" << testData << ".assign";
1336 // try to open the graph file again, if this doesn't open
1337 // the user has not provided a valid path to the file
1338 graphFile = fopen(chGraphFileName.str().c_str(), "r");
1339 }
1340
1341 memset(fileInfo, 0, sizeof(int) * 3); // set fileinfo to 0's
1342 if (graphFile){
1343 fileInfo[0] = 1;
1344 if (verbose_ && tcomm_->getRank() == 0)
1345 std::cout << "UserInputForTests, open " <<
1346 chGraphFileName.str () << std::endl;
1347
1348 coordFile = fopen(chCoordFileName.str().c_str(), "r");
1349 if (coordFile){
1350 fileInfo[1] = 1;
1351 if (verbose_ && tcomm_->getRank() == 0)
1352 std::cout << "UserInputForTests, open " <<
1353 chCoordFileName.str () << std::endl;
1354 }
1355
1356 assignFile = fopen(chAssignFileName.str().c_str(), "r");
1357 if (assignFile){
1358 fileInfo[2] = 1;
1359 if (verbose_ && tcomm_->getRank() == 0)
1360 std::cout << "UserInputForTests, open " <<
1361 chAssignFileName.str () << std::endl;
1362 }
1363 }else{
1364 if (verbose_ && tcomm_->getRank() == 0){
1365 std::cout << "UserInputForTests, unable to open file: ";
1366 std::cout << chGraphFileName.str() << std::endl;
1367 }
1368 }
1369 }
1370
1371 // broadcast whether we have graphs and coords to all processes
1372 Teuchos::broadcast<int, int>(*tcomm_, 0, 3, fileInfo);
1373
1374 bool haveGraph = (fileInfo[0] == 1);
1375 bool haveCoords = (fileInfo[1] == 1);
1376 bool haveAssign = (fileInfo[2] == 1);
1377
1378 if (haveGraph){
1379 // builds M_, vtxWeights_, and edgWeights_ and closes file.
1380 try{
1381 getUIChacoGraph(graphFile, haveAssign, assignFile,
1382 testData, distributeInput);
1383 }
1385
1386 if (haveCoords){
1387 // builds xyz_ and closes the file.
1388 try{
1389 getUIChacoCoords(coordFile, testData);
1390 }
1392 }
1393 }
1394
1396}
1397
1398void UserInputForTests::getUIChacoGraph(FILE *fptr, bool haveAssign,
1399 FILE *assignFile, string fname,
1400 bool distributeInput)
1401{
1402 int rank = tcomm_->getRank();
1403 int graphCounts[5];
1404 int nvtxs=0, nedges=0;
1405 int nVwgts=0, nEwgts=0;
1406 int *start = NULL, *adj = NULL;
1407 float *ewgts = NULL, *vwgts = NULL;
1408 size_t *nzPerRow = NULL;
1409 size_t maxRowLen = 0;
1410 zgno_t base = 0;
1411 ArrayRCP<const size_t> rowSizes;
1412 int fail = 0;
1413 bool haveEdges = true;
1414
1415 if (rank == 0){
1416
1417 memset(graphCounts, 0, 5*sizeof(int));
1418
1419 // Reads in the file and closes it when done.
1420 fail = chaco_input_graph(fptr, fname.c_str(), &start, &adj,
1421 &nvtxs, &nVwgts, &vwgts, &nEwgts, &ewgts);
1422
1423 // There are Zoltan2 test graphs that have no edges.
1424
1425 // nEwgts must be 1 or 0 - add error
1426
1427 if (start == NULL)
1428 haveEdges = false;
1429
1430 if (verbose_)
1431 {
1432 std::cout << "UserInputForTests, " << nvtxs << " vertices,";
1433 if (haveEdges)
1434 std::cout << start[nvtxs] << " edges,";
1435 else
1436 std::cout << "no edges,";
1437 std::cout << nVwgts << " vertex weights, ";
1438 std::cout << nEwgts << " edge weights" << std::endl;
1439 }
1440
1441 if (nvtxs==0)
1442 fail = true;
1443
1444 if (fail){
1445 Teuchos::broadcast<int, int>(*tcomm_, 0, 5, graphCounts);
1446 throw std::runtime_error("Unable to read chaco file");
1447 }
1448
1449 if (haveEdges)
1450 nedges = start[nvtxs];
1451
1452 nzPerRow = new size_t [nvtxs];
1453 if (!nzPerRow)
1454 throw std::bad_alloc();
1455 rowSizes = arcp(nzPerRow, 0, nvtxs, true);
1456
1457 if (haveEdges){
1458 for (int i=0; i < nvtxs; i++){
1459 nzPerRow[i] = start[i+1] - start[i];
1460 if (nzPerRow[i] > maxRowLen)
1461 maxRowLen = nzPerRow[i];
1462 }
1463 }
1464 else{
1465 memset(nzPerRow, 0, sizeof(size_t) * nvtxs);
1466 }
1467
1468 // Make sure base gid is zero.
1469
1470 if (nedges){
1471 int chbase = 1; // chaco input files are one-based
1472 for (int i=0; i < nedges; i++)
1473 adj[i] -= chbase;
1474 }
1475
1476 graphCounts[0] = nvtxs;
1477 graphCounts[1] = nedges;
1478 graphCounts[2] = nVwgts;
1479 graphCounts[3] = nEwgts;
1480 graphCounts[4] = (int)maxRowLen; // size_t maxRowLen will fit; it is <= (int-int)
1481 }
1482
1483 Teuchos::broadcast<int, int>(*tcomm_, 0, 5, graphCounts);
1484
1485 if (graphCounts[0] == 0)
1486 throw std::runtime_error("Unable to read chaco file");
1487
1488 haveEdges = (graphCounts[1] > 0);
1489
1490 RCP<tcrsMatrix_t> fromMatrix;
1491 RCP<const map_t> fromMap;
1492
1493 // Create a Tpetra::CrsMatrix where rank 0 has entire matrix.
1494 if (rank == 0){
1495 fromMap = rcp(new map_t(nvtxs, nvtxs, base, tcomm_));
1496
1497 fromMatrix =
1498 rcp(new tcrsMatrix_t(fromMap, rowSizes()));
1499
1500 if (haveEdges){
1501
1502 zgno_t *edgeIds = new zgno_t [nedges];
1503 if (nedges && !edgeIds)
1504 throw std::bad_alloc();
1505 for (int i=0; i < nedges; i++)
1506 edgeIds[i] = adj[i];
1507
1508 free(adj);
1509 adj = NULL;
1510
1511 zgno_t *nextId = edgeIds;
1512 Array<zscalar_t> values(nedges, 1.0);
1513 if (nedges > 0 && nEwgts > 0) {
1514 for (int i=0; i < nedges; i++)
1515 values[i] = ewgts[i];
1516 free(ewgts);
1517 ewgts = NULL;
1518 }
1519
1520 for (int i=0; i < nvtxs; i++){
1521 if (nzPerRow[i] > 0){
1522 ArrayView<const zgno_t> rowNz(nextId, nzPerRow[i]);
1523 fromMatrix->insertGlobalValues(i, rowNz, values.view(start[i], start[i+1] - start[i]));
1524 nextId += nzPerRow[i];
1525 }
1526 }
1527
1528 delete [] edgeIds;
1529 edgeIds = NULL;
1530 }
1531
1532 fromMatrix->fillComplete();
1533 }
1534 else{
1535 nvtxs = graphCounts[0];
1536 nedges = graphCounts[1];
1537 nVwgts = graphCounts[2];
1538 nEwgts = graphCounts[3];
1539 maxRowLen = graphCounts[4];
1540
1541 // Create a Tpetra::CrsMatrix where rank 0 has entire matrix.
1542
1543 fromMap = rcp(new map_t(nvtxs, 0, base, tcomm_));
1544
1545 fromMatrix =
1546 rcp(new tcrsMatrix_t(fromMap, rowSizes()));
1547
1548 fromMatrix->fillComplete();
1549 }
1550
1551#ifdef KDDKDDPRINT
1552 if (rank == 0) {
1553 size_t sz = fromMatrix->getLocalMaxNumRowEntries();
1554 Teuchos::Array<zgno_t> indices(sz);
1555 Teuchos::Array<zscalar_t> values(sz);
1556 for (size_t i = 0; i < fromMatrix->getLocalNumRows(); i++) {
1557 zgno_t gid = fromMatrix->getRowMap()->getGlobalElement(i);
1558 size_t num;
1559 fromMatrix->getGlobalRowCopy(gid, indices(), values(), num);
1560 std::cout << "ROW " << gid << ": ";
1561 for (size_t j = 0; j < num; j++)
1562 std::cout << indices[j] << " ";
1563 std::cout << std::endl;
1564 }
1565 }
1566#endif
1567
1568 RCP<const map_t> toMap;
1569 RCP<tcrsMatrix_t> toMatrix;
1570 RCP<import_t> importer;
1571
1572 if (distributeInput) {
1573 if (haveAssign) {
1574 // Read assignments from Chaco assignment file
1575 short *assignments = new short[nvtxs];
1576 if (rank == 0) {
1577 fail = chaco_input_assign(assignFile, fname.c_str(), nvtxs, assignments);
1578 }
1579 // Broadcast coordinate dimension
1580 Teuchos::broadcast<int, short>(*tcomm_, 0, nvtxs, assignments);
1581
1582 // Build map with my vertices
1583 Teuchos::Array<zgno_t> mine;
1584 for (int i = 0; i < nvtxs; i++) {
1585 if (assignments[i] == rank)
1586 mine.push_back(i);
1587 }
1588
1589 Tpetra::global_size_t dummy =
1590 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
1591 toMap = rcp(new map_t(dummy, mine(), base, tcomm_));
1592 delete [] assignments;
1593 }
1594 else {
1595 // Create a Tpetra::Map with default row distribution.
1596 toMap = rcp(new map_t(nvtxs, base, tcomm_));
1597 }
1598 toMatrix = rcp(new tcrsMatrix_t(toMap, maxRowLen));
1599
1600 // Import the data.
1601 importer = rcp(new import_t(fromMap, toMap));
1602 toMatrix->doImport(*fromMatrix, *importer, Tpetra::INSERT);
1603 toMatrix->fillComplete();
1604 }
1605 else {
1606 toMap = fromMap;
1607 toMatrix = fromMatrix;
1608 }
1609
1610 M_ = toMatrix;
1611
1612 // Vertex weights, if any
1613
1614 typedef ArrayRCP<const ArrayView<const zscalar_t> > arrayArray_t;
1615
1616 if (nVwgts > 0){
1617
1618 ArrayRCP<zscalar_t> weightBuf;
1619 ArrayView<const zscalar_t> *wgts = new ArrayView<const zscalar_t> [nVwgts];
1620
1621 if (rank == 0){
1622 size_t len = nVwgts * nvtxs;
1623 zscalar_t *buf = new zscalar_t [len];
1624 if (!buf) throw std::bad_alloc();
1625 weightBuf = arcp(buf, 0, len, true);
1626
1627 for (int widx=0; widx < nVwgts; widx++){
1628 wgts[widx] = ArrayView<const zscalar_t>(buf, nvtxs);
1629 float *vw = vwgts + widx;
1630 for (int i=0; i < nvtxs; i++, vw += nVwgts)
1631 buf[i] = *vw;
1632 buf += nvtxs;
1633 }
1634
1635 free(vwgts);
1636 vwgts = NULL;
1637 }
1638
1639 arrayArray_t vweights = arcp(wgts, 0, nVwgts, true);
1640
1641 RCP<tMVector_t> fromVertexWeights =
1642 rcp(new tMVector_t(fromMap, vweights.view(0, nVwgts), nVwgts));
1643
1644 RCP<tMVector_t> toVertexWeights;
1645 if (distributeInput) {
1646 toVertexWeights = rcp(new tMVector_t(toMap, nVwgts));
1647 toVertexWeights->doImport(*fromVertexWeights, *importer, Tpetra::INSERT);
1648 }
1649 else
1650 toVertexWeights = fromVertexWeights;
1651
1652 vtxWeights_ = toVertexWeights;
1653 }
1654
1655 // Edge weights, if any
1656
1657 if (haveEdges && nEwgts > 0){
1658
1659 // No longer distributing edge weights; they are the matrix values
1660 /*
1661 ArrayRCP<zscalar_t> weightBuf;
1662 ArrayView<const zscalar_t> *wgts = new ArrayView<const zscalar_t> [nEwgts];
1663
1664 toMap = rcp(new map_t(nedges, M_->getLocalNumEntries(), base, tcomm_));
1665
1666 if (rank == 0){
1667 size_t len = nEwgts * nedges;
1668 zscalar_t *buf = new zscalar_t [len];
1669 if (!buf) throw std::bad_alloc();
1670 weightBuf = arcp(buf, 0, len, true);
1671
1672 for (int widx=0; widx < nEwgts; widx++){
1673 wgts[widx] = ArrayView<const zscalar_t>(buf, nedges);
1674 float *ew = ewgts + widx;
1675 for (int i=0; i < nedges; i++, ew += nEwgts)
1676 buf[i] = *ew;
1677 buf += nedges;
1678 }
1679
1680 free(ewgts);
1681 ewgts = NULL;
1682 fromMap = rcp(new map_t(nedges, nedges, base, tcomm_));
1683 }
1684 else{
1685 fromMap = rcp(new map_t(nedges, 0, base, tcomm_));
1686 }
1687
1688 arrayArray_t eweights = arcp(wgts, 0, nEwgts, true);
1689
1690 RCP<tMVector_t> fromEdgeWeights;
1691 RCP<tMVector_t> toEdgeWeights;
1692 RCP<import_t> edgeImporter;
1693
1694 if (distributeInput) {
1695 fromEdgeWeights =
1696 rcp(new tMVector_t(fromMap, eweights.view(0, nEwgts), nEwgts));
1697 toEdgeWeights = rcp(new tMVector_t(toMap, nEwgts));
1698 edgeImporter = rcp(new import_t(fromMap, toMap));
1699 toEdgeWeights->doImport(*fromEdgeWeights, *edgeImporter, Tpetra::INSERT);
1700 }
1701 else
1702 toEdgeWeights = fromEdgeWeights;
1703
1704 edgWeights_ = toEdgeWeights;
1705 */
1706
1707 toMap = rcp(new map_t(nedges, M_->getLocalNumEntries(), base, tcomm_));
1708 edgWeights_ = rcp(new tMVector_t(toMap, nEwgts));
1709
1710 size_t maxSize = M_->getLocalMaxNumRowEntries();
1711 tcrsMatrix_t::nonconst_local_inds_host_view_type colind("colind", maxSize);
1712 tcrsMatrix_t::nonconst_values_host_view_type vals("values", maxSize);
1713 size_t nEntries;
1714
1715 for (size_t i = 0, idx = 0; i < M_->getLocalNumRows(); i++) {
1716 M_->getLocalRowCopy(i, colind, vals, nEntries);
1717 for (size_t j = 0; j < nEntries; j++) {
1718 edgWeights_->replaceLocalValue(idx, 0, vals[j]); // Assuming nEwgts==1
1719 idx++;
1720 }
1721 }
1722 }
1723
1724 if (start) {
1725 free(start);
1726 start = NULL;
1727 }
1728}
1729
1730void UserInputForTests::getUIChacoCoords(FILE *fptr, string fname)
1731{
1732 int rank = tcomm_->getRank();
1733 int ndim=0;
1734 double *x=NULL, *y=NULL, *z=NULL;
1735 int fail = 0;
1736
1737 size_t globalNumVtx = M_->getGlobalNumRows();
1738
1739 if (rank == 0){
1740
1741 // This function is from the Zoltan C-library.
1742
1743 // Reads in the file and closes it when done.
1744 fail = chaco_input_geom(fptr, fname.c_str(), (int)globalNumVtx,
1745 &ndim, &x, &y, &z);
1746
1747 if (fail)
1748 ndim = 0;
1749
1750 if (verbose_){
1751 std::cout << "UserInputForTests, read " << globalNumVtx;
1752 std::cout << " " << ndim << "-dimensional coordinates." << std::endl;
1753 }
1754 }
1755
1756 Teuchos::broadcast<int, int>(*tcomm_, 0, 1, &ndim);
1757
1758 if (ndim == 0)
1759 throw std::runtime_error("Can't read coordinate file");
1760
1761 ArrayRCP<ArrayRCP<const zscalar_t> > coords(ndim);
1762 zlno_t len = 0;
1763
1764 if (rank == 0){
1765
1766 for (int dim=0; dim < ndim; dim++){
1767 zscalar_t *v = new zscalar_t [globalNumVtx];
1768 if (!v)
1769 throw std::bad_alloc();
1770 coords[dim] = arcp<const zscalar_t>(v, 0, globalNumVtx, true);
1771 double *val = (dim==0 ? x : (dim==1 ? y : z));
1772 for (size_t i=0; i < globalNumVtx; i++)
1773 v[i] = zscalar_t(val[i]);
1774
1775 free(val);
1776 }
1777
1778 len = static_cast<zlno_t>(globalNumVtx);
1779 }
1780
1781 RCP<const map_t> fromMap = rcp(new map_t(globalNumVtx, len, 0, tcomm_));
1782 RCP<const map_t> toMap = M_->getRowMap();
1783 RCP<import_t> importer = rcp(new import_t(fromMap, toMap));
1784
1785 Array<ArrayView<const zscalar_t> > coordData;
1786 for (int dim=0; dim < ndim; dim++)
1787 coordData.push_back(coords[dim].view(0, len));
1788
1789 RCP<tMVector_t> fromCoords =
1790 rcp(new tMVector_t(fromMap, coordData.view(0, ndim), ndim));
1791
1792 RCP<tMVector_t> toCoords = rcp(new tMVector_t(toMap, ndim));
1793
1794 toCoords->doImport(*fromCoords, *importer, Tpetra::INSERT);
1795
1796 xyz_ = toCoords;
1797
1798}
1799
1802
1803double UserInputForTests::chaco_read_val(
1804 FILE* infile, /* file to read value from */
1805 int *end_flag /* 0 => OK, 1 => EOL, -1 => EOF */
1806)
1807{
1808 double val; /* return value */
1809 char *ptr; /* ptr to next string to read */
1810 char *ptr2; /* ptr to next string to read */
1811 int length; /* length of line to read */
1812 int length_left;/* length of line still around */
1813 int white_seen; /* have I detected white space yet? */
1814 int done; /* checking for end of scan */
1815 int i; /* loop counter */
1816
1817 *end_flag = 0;
1818
1819 if (chaco_offset == 0 || chaco_offset >= chaco_break_pnt) {
1820 if (chaco_offset >= chaco_break_pnt) { /* Copy rest of line back to beginning. */
1821 length_left = CHACO_LINE_LENGTH - chaco_save_pnt - 1;
1822 ptr2 = chaco_line;
1823 ptr = &chaco_line[chaco_save_pnt];
1824 for (i=length_left; i; i--) *ptr2++ = *ptr++;
1825 length = chaco_save_pnt + 1;
1826 }
1827 else {
1828 length = CHACO_LINE_LENGTH;
1829 length_left = 0;
1830 }
1831
1832 /* Now read next line, or next segment of current one. */
1833 ptr2 = fgets(&chaco_line[length_left], length, infile);
1834
1835 if (ptr2 == (char *) NULL) { /* We've hit end of file. */
1836 *end_flag = -1;
1837 return((double) 0.0);
1838 }
1839
1840 if ((chaco_line[CHACO_LINE_LENGTH - 2] != '\n') && (chaco_line[CHACO_LINE_LENGTH - 2] != '\f')
1841 && (strlen(chaco_line) == CHACO_LINE_LENGTH - 1)){
1842 /* Line too long. Find last safe place in chaco_line. */
1843 chaco_break_pnt = CHACO_LINE_LENGTH - 1;
1844 chaco_save_pnt = chaco_break_pnt;
1845 white_seen = 0;
1846 done = 0;
1847 while (!done) {
1848 --chaco_break_pnt;
1849 if (chaco_line[chaco_break_pnt] != '\0') {
1850 if (isspace((int)(chaco_line[chaco_break_pnt]))) {
1851 if (!white_seen) {
1852 chaco_save_pnt = chaco_break_pnt + 1;
1853 white_seen = 1;
1854 }
1855 }
1856 else if (white_seen) {
1857 done= 1;
1858 }
1859 }
1860 }
1861 }
1862 else {
1863 chaco_break_pnt = CHACO_LINE_LENGTH;
1864 }
1865
1866 chaco_offset = 0;
1867 }
1868
1869 while (isspace((int)(chaco_line[chaco_offset])) && chaco_offset < CHACO_LINE_LENGTH) chaco_offset++;
1870 if (chaco_line[chaco_offset] == '%' || chaco_line[chaco_offset] == '#') {
1871 *end_flag = 1;
1872 if (chaco_break_pnt < CHACO_LINE_LENGTH) {
1873 chaco_flush_line(infile);
1874 }
1875 return((double) 0.0);
1876 }
1877
1878 ptr = &(chaco_line[chaco_offset]);
1879 val = strtod(ptr, &ptr2);
1880
1881 if (ptr2 == ptr) { /* End of input line. */
1882 chaco_offset = 0;
1883 *end_flag = 1;
1884 return((double) 0.0);
1885 }
1886 else {
1887 chaco_offset = (int) (ptr2 - chaco_line) / sizeof(char);
1888 }
1889
1890 return(val);
1891}
1892
1893
1894int UserInputForTests::chaco_read_int(
1895 FILE *infile, /* file to read value from */
1896 int *end_flag /* 0 => OK, 1 => EOL, -1 => EOF */
1897)
1898{
1899 int val; /* return value */
1900 char *ptr; /* ptr to next string to read */
1901 char *ptr2; /* ptr to next string to read */
1902 int length; /* length of line to read */
1903 int length_left; /* length of line still around */
1904 int white_seen; /* have I detected white space yet? */
1905 int done; /* checking for end of scan */
1906 int i; /* loop counter */
1907
1908 *end_flag = 0;
1909
1910 if (chaco_offset == 0 || chaco_offset >= chaco_break_pnt) {
1911 if (chaco_offset >= chaco_break_pnt) { /* Copy rest of line back to beginning. */
1912 length_left = CHACO_LINE_LENGTH - chaco_save_pnt - 1;
1913 ptr2 = chaco_line;
1914 ptr = &chaco_line[chaco_save_pnt];
1915 for (i=length_left; i; i--) *ptr2++ = *ptr++;
1916 length = chaco_save_pnt + 1;
1917 }
1918 else {
1919 length = CHACO_LINE_LENGTH;
1920 length_left = 0;
1921 }
1922
1923 /* Now read next line, or next segment of current one. */
1924 ptr2 = fgets(&chaco_line[length_left], length, infile);
1925
1926 if (ptr2 == (char *) NULL) { /* We've hit end of file. */
1927 *end_flag = -1;
1928 return(0);
1929 }
1930
1931 if ((chaco_line[CHACO_LINE_LENGTH - 2] != '\n') && (chaco_line[CHACO_LINE_LENGTH - 2] != '\f')
1932 && (strlen(chaco_line) == CHACO_LINE_LENGTH - 1)){
1933 /* Line too long. Find last safe place in line. */
1934 chaco_break_pnt = CHACO_LINE_LENGTH - 1;
1935 chaco_save_pnt = chaco_break_pnt;
1936 white_seen = 0;
1937 done = 0;
1938 while (!done) {
1939 --chaco_break_pnt;
1940 if (chaco_line[chaco_break_pnt] != '\0') {
1941 if (isspace((int)(chaco_line[chaco_break_pnt]))) {
1942 if (!white_seen) {
1943 chaco_save_pnt = chaco_break_pnt + 1;
1944 white_seen = 1;
1945 }
1946 }
1947 else if (white_seen) {
1948 done= 1;
1949 }
1950 }
1951 }
1952 }
1953 else {
1954 chaco_break_pnt = CHACO_LINE_LENGTH;
1955 }
1956
1957 chaco_offset = 0;
1958 }
1959
1960 while (isspace((int)(chaco_line[chaco_offset])) && chaco_offset < CHACO_LINE_LENGTH) chaco_offset++;
1961 if (chaco_line[chaco_offset] == '%' || chaco_line[chaco_offset] == '#') {
1962 *end_flag = 1;
1963 if (chaco_break_pnt < CHACO_LINE_LENGTH) {
1964 chaco_flush_line(infile);
1965 }
1966 return(0);
1967 }
1968
1969 ptr = &(chaco_line[chaco_offset]);
1970 val = (int) strtol(ptr, &ptr2, 10);
1971
1972 if (ptr2 == ptr) { /* End of input chaco_line. */
1973 chaco_offset = 0;
1974 *end_flag = 1;
1975 return(0);
1976 }
1977 else {
1978 chaco_offset = (int) (ptr2 - chaco_line) / sizeof(char);
1979 }
1980
1981 return(val);
1982}
1983
1984void UserInputForTests::chaco_flush_line(
1985 FILE *infile /* file to read value from */
1986)
1987{
1988 char c; /* character being read */
1989
1990 c = fgetc(infile);
1991 while (c != '\n' && c != '\f')
1992 c = fgetc(infile);
1993}
1994
1995int UserInputForTests::chaco_input_graph(
1996 FILE *fin, /* input file */
1997 const char *inname, /* name of input file */
1998 int **start, /* start of edge list for each vertex */
1999 int **adjacency, /* edge list data */
2000 int *nvtxs, /* number of vertices in graph */
2001 int *nVwgts, /* # of vertex weights per node */
2002 float **vweights, /* vertex weight list data */
2003 int *nEwgts, /* # of edge weights per edge */
2004 float **eweights /* edge weight list data */
2005)
2006{
2007 int *adjptr; /* loops through adjacency data */
2008 float *ewptr; /* loops through edge weight data */
2009 int narcs; /* number of edges expected in graph */
2010 int nedges; /* twice number of edges really in graph */
2011 int nedge; /* loops through edges for each vertex */
2012 int flag; /* condition indicator */
2013 int skip_flag; /* should this edge be ignored? */
2014 int end_flag; /* indicates end of line or file */
2015 int vtx; /* vertex in graph */
2016 int line_num; /* line number in input file */
2017 int sum_edges; /* total number of edges read so far */
2018 int option = 0; /* input option */
2019 int using_ewgts; /* are edge weights in input file? */
2020 int using_vwgts; /* are vertex weights in input file? */
2021 int vtxnums; /* are vertex numbers in input file? */
2022 int vertex; /* current vertex being read */
2023 int new_vertex; /* new vertex being read */
2024 float weight; /* weight being read */
2025 float eweight; /* edge weight being read */
2026 int neighbor; /* neighbor of current vertex */
2027 int error_flag; /* error reading input? */
2028 int j; /* loop counters */
2029
2030 /* Read first line of input (= nvtxs, narcs, option). */
2031 /* The (decimal) digits of the option variable mean: 1's digit not zero => input
2032 edge weights 10's digit not zero => input vertex weights 100's digit not zero
2033 => include vertex numbers */
2034
2035 *start = NULL;
2036 *adjacency = NULL;
2037 *vweights = NULL;
2038 *eweights = NULL;
2039
2040 error_flag = 0;
2041 line_num = 0;
2042
2043 /* Read any leading comment lines */
2044 end_flag = 1;
2045 while (end_flag == 1) {
2046 *nvtxs = chaco_read_int(fin, &end_flag);
2047 ++line_num;
2048 }
2049 if (*nvtxs <= 0) {
2050 printf("ERROR in graph file `%s':", inname);
2051 printf(" Invalid number of vertices (%d).\n", *nvtxs);
2052 fclose(fin);
2053 return(1);
2054 }
2055
2056 narcs = chaco_read_int(fin, &end_flag);
2057 if (narcs < 0) {
2058 printf("ERROR in graph file `%s':", inname);
2059 printf(" Invalid number of expected edges (%d).\n", narcs);
2060 fclose(fin);
2061 return(1);
2062 }
2063
2064 /* Check if vertex or edge weights are used */
2065 if (!end_flag) {
2066 option = chaco_read_int(fin, &end_flag);
2067 }
2068 using_ewgts = option - 10 * (option / 10);
2069 option /= 10;
2070 using_vwgts = option - 10 * (option / 10);
2071 option /= 10;
2072 vtxnums = option - 10 * (option / 10);
2073
2074 /* Get weight info from Chaco option */
2075 (*nVwgts) = using_vwgts;
2076 (*nEwgts) = using_ewgts;
2077
2078 /* Read numbers of weights if they are specified separately */
2079 if (!end_flag && using_vwgts==1){
2080 j = chaco_read_int(fin, &end_flag);
2081 if (!end_flag) (*nVwgts) = j;
2082 }
2083 if (!end_flag && using_ewgts==1){
2084 j = chaco_read_int(fin, &end_flag);
2085 if (!end_flag) (*nEwgts) = j;
2086 }
2087
2088 /* Discard rest of line */
2089 while (!end_flag)
2090 j = chaco_read_int(fin, &end_flag);
2091
2092 /* Allocate space for rows and columns. */
2093 *start = (int *) malloc((unsigned) (*nvtxs + 1) * sizeof(int));
2094 if (narcs != 0)
2095 *adjacency = (int *) malloc((unsigned) (2 * narcs + 1) * sizeof(int));
2096 else
2097 *adjacency = NULL;
2098
2099 if (using_vwgts)
2100 *vweights = (float *) malloc((unsigned) (*nvtxs) * (*nVwgts) * sizeof(float));
2101 else
2102 *vweights = NULL;
2103
2104 if (using_ewgts)
2105 *eweights = (float *)
2106 malloc((unsigned) (2 * narcs + 1) * (*nEwgts) * sizeof(float));
2107 else
2108 *eweights = NULL;
2109
2110 adjptr = *adjacency;
2111 ewptr = *eweights;
2112
2113 sum_edges = 0;
2114 nedges = 0;
2115 (*start)[0] = 0;
2116 vertex = 0;
2117 vtx = 0;
2118 new_vertex = 1;
2119 while ((using_vwgts || vtxnums || narcs) && end_flag != -1) {
2120 ++line_num;
2121
2122 /* If multiple input lines per vertex, read vertex number. */
2123 if (vtxnums) {
2124 j = chaco_read_int(fin, &end_flag);
2125 if (end_flag) {
2126 if (vertex == *nvtxs)
2127 break;
2128 printf("ERROR in graph file `%s':", inname);
2129 printf(" no vertex number in line %d.\n", line_num);
2130 fclose(fin);
2131 return (1);
2132 }
2133 if (j != vertex && j != vertex + 1) {
2134 printf("ERROR in graph file `%s':", inname);
2135 printf(" out-of-order vertex number in line %d.\n", line_num);
2136 fclose(fin);
2137 return (1);
2138 }
2139 if (j != vertex) {
2140 new_vertex = 1;
2141 vertex = j;
2142 }
2143 else
2144 new_vertex = 0;
2145 }
2146 else
2147 vertex = ++vtx;
2148
2149 if (vertex > *nvtxs)
2150 break;
2151
2152 /* If vertices are weighted, read vertex weight. */
2153 if (using_vwgts && new_vertex) {
2154 for (j=0; j<(*nVwgts); j++){
2155 weight = chaco_read_val(fin, &end_flag);
2156 if (end_flag) {
2157 printf("ERROR in graph file `%s':", inname);
2158 printf(" not enough weights for vertex %d.\n", vertex);
2159 fclose(fin);
2160 return (1);
2161 }
2162 (*vweights)[(vertex-1)*(*nVwgts)+j] = weight;
2163 }
2164 }
2165
2166 nedge = 0;
2167
2168 /* Read number of adjacent vertex. */
2169 neighbor = chaco_read_int(fin, &end_flag);
2170
2171 while (!end_flag) {
2172 skip_flag = 0;
2173
2174 if (using_ewgts) { /* Read edge weight if it's being input. */
2175 for (j=0; j<(*nEwgts); j++){
2176 eweight = chaco_read_val(fin, &end_flag);
2177
2178 if (end_flag) {
2179 printf("ERROR in graph file `%s':", inname);
2180 printf(" not enough weights for edge (%d,%d).\n", vertex, neighbor);
2181 fclose(fin);
2182 return (1);
2183 }
2184
2185 else {
2186 *ewptr++ = eweight;
2187 }
2188 }
2189 }
2190
2191 /* Add edge to data structure. */
2192 if (!skip_flag) {
2193 if (++nedges > 2*narcs) {
2194 printf("ERROR in graph file `%s':", inname);
2195 printf(" at least %d adjacencies entered, but nedges = %d\n",
2196 nedges, narcs);
2197 fclose(fin);
2198 return (1);
2199 }
2200 *adjptr++ = neighbor;
2201 nedge++;
2202 }
2203
2204 /* Read number of next adjacent vertex. */
2205 neighbor = chaco_read_int(fin, &end_flag);
2206 }
2207
2208 sum_edges += nedge;
2209 (*start)[vertex] = sum_edges;
2210 }
2211
2212 /* Make sure there's nothing else in file. */
2213 flag = 0;
2214 while (!flag && end_flag != -1) {
2215 chaco_read_int(fin, &end_flag);
2216 if (!end_flag)
2217 flag = 1;
2218 }
2219
2220 (*start)[*nvtxs] = sum_edges;
2221
2222 if (vertex != 0) { /* Normal file was read. */
2223 if (narcs) {
2224 }
2225 else { /* no edges, but did have vertex weights or vertex numbers */
2226 free(*start);
2227 *start = NULL;
2228 if (*adjacency != NULL)
2229 free(*adjacency);
2230 *adjacency = NULL;
2231 if (*eweights != NULL)
2232 free(*eweights);
2233 *eweights = NULL;
2234 }
2235 }
2236
2237 else {
2238 /* Graph was empty */
2239 free(*start);
2240 if (*adjacency != NULL)
2241 free(*adjacency);
2242 if (*vweights != NULL)
2243 free(*vweights);
2244 if (*eweights != NULL)
2245 free(*eweights);
2246 *start = NULL;
2247 *adjacency = NULL;
2248 }
2249
2250 fclose(fin);
2251
2252 return (error_flag);
2253}
2254
2255
2256int UserInputForTests::chaco_input_geom(
2257 FILE *fingeom, /* geometry input file */
2258 const char *geomname, /* name of geometry file */
2259 int nvtxs, /* number of coordinates to read */
2260 int *igeom, /* dimensionality of geometry */
2261 double **x, /* coordinates of vertices */
2262 double **y,
2263 double **z
2264)
2265{
2266 double xc, yc, zc =0; /* first x, y, z coordinate */
2267 int nread; /* number of lines of coordinates read */
2268 int flag; /* any bad data at end of file? */
2269 int line_num; /* counts input lines in file */
2270 int end_flag; /* return conditional */
2271 int ndims; /* number of values in an input line */
2272 int i=0; /* loop counter */
2273
2274 *x = *y = *z = NULL;
2275 line_num = 0;
2276 end_flag = 1;
2277 while (end_flag == 1) {
2278 xc = chaco_read_val(fingeom, &end_flag);
2279 ++line_num;
2280 }
2281
2282 if (end_flag == -1) {
2283 printf("No values found in geometry file `%s'\n", geomname);
2284 fclose(fingeom);
2285 return (1);
2286 }
2287
2288 ndims = 1;
2289 yc = chaco_read_val(fingeom, &end_flag);
2290 if (end_flag == 0) {
2291 ndims = 2;
2292 zc = chaco_read_val(fingeom, &end_flag);
2293 if (end_flag == 0) {
2294 ndims = 3;
2295 chaco_read_val(fingeom, &end_flag);
2296 if (!end_flag) {
2297 printf("Too many values on input line of geometry file `%s'\n",
2298 geomname);
2299
2300 printf(" Maximum dimensionality is 3\n");
2301 fclose(fingeom);
2302 return (1);
2303 }
2304 }
2305 }
2306
2307 *igeom = ndims;
2308
2309 *x = (double *) malloc((unsigned) nvtxs * sizeof(double));
2310 (*x)[0] = xc;
2311 if (ndims > 1) {
2312 *y = (double *) malloc((unsigned) nvtxs * sizeof(double));
2313 (*y)[0] = yc;
2314 }
2315 if (ndims > 2) {
2316 *z = (double *) malloc((unsigned) nvtxs * sizeof(double));
2317 (*z)[0] = zc;
2318 }
2319
2320 for (nread = 1; nread < nvtxs; nread++) {
2321 ++line_num;
2322 if (ndims == 1) {
2323 i = fscanf(fingeom, "%lf", &((*x)[nread]));
2324 }
2325 else if (ndims == 2) {
2326 i = fscanf(fingeom, "%lf%lf", &((*x)[nread]), &((*y)[nread]));
2327 }
2328 else if (ndims == 3) {
2329 i = fscanf(fingeom, "%lf%lf%lf", &((*x)[nread]), &((*y)[nread]),
2330 &((*z)[nread]));
2331 }
2332
2333 if (i == EOF) {
2334 printf("Too few lines of values in geometry file; nvtxs=%d, but only %d read\n",
2335 nvtxs, nread);
2336 fclose(fingeom);
2337 return (1);
2338 }
2339 else if (i != ndims) {
2340 printf("Wrong number of values in line %d of geometry file `%s'\n",
2341 line_num, geomname);
2342 fclose(fingeom);
2343 return (1);
2344 }
2345 }
2346
2347 /* Check for spurious extra stuff in file. */
2348 flag = 0;
2349 end_flag = 0;
2350 while (!flag && end_flag != -1) {
2351 chaco_read_val(fingeom, &end_flag);
2352 if (!end_flag)
2353 flag = 1;
2354 }
2355
2356 fclose(fingeom);
2357
2358 return (0);
2359}
2360
2361// Chaco input assignments from filename.assign; copied from Zoltan
2362
2363int UserInputForTests::chaco_input_assign(
2364 FILE *finassign, /* input assignment file */
2365 const char *inassignname, /* name of input assignment file */
2366 int nvtxs, /* number of vertices to output */
2367 short *assignment) /* values to be printed */
2368{
2369 int flag; /* logical conditional */
2370 int end_flag; /* return flag from read_int() */
2371 int i, j; /* loop counter */
2372
2373 /* Get the assignment vector one line at a time, checking as you go. */
2374 /* First read past any comments at top. */
2375 end_flag = 1;
2376 while (end_flag == 1) {
2377 assignment[0] = chaco_read_int(finassign, &end_flag);
2378 }
2379
2380 if (assignment[0] < 0) {
2381 printf("ERROR: Entry %d in assignment file `%s' less than zero (%d)\n",
2382 1, inassignname, assignment[0]);
2383 fclose(finassign);
2384 return (1);
2385 }
2386
2387 if (end_flag == -1) {
2388 printf("ERROR: No values found in assignment file `%s'\n", inassignname);
2389 fclose(finassign);
2390 return (1);
2391 }
2392
2393 flag = 0;
2394 int np = this->tcomm_->getSize();
2395 if (assignment[0] >= np) flag = assignment[0];
2396 srand(this->tcomm_->getRank());
2397 for (i = 1; i < nvtxs; i++) {
2398 j = fscanf(finassign, "%hd", &(assignment[i]));
2399 if (j != 1) {
2400 printf("ERROR: Too few values in assignment file `%s'.\n", inassignname);
2401 fclose(finassign);
2402 return (1);
2403 }
2404 if (assignment[i] < 0) {
2405 printf("ERROR: Entry %d in assignment file `%s' less than zero (%d)\n",
2406 i+1, inassignname, assignment[i]);
2407 fclose(finassign);
2408 return (1);
2409 }
2410 if (assignment[i] >= np) { // warn since perhaps an error -- initial part
2411 // assignment is greater than number of processors
2412 if (assignment[i] > flag)
2413 flag = assignment[i];
2414 assignment[i] = rand() % np; // randomly assign vtx to a proc in this case
2415 }
2416 }
2417 srand(rand());
2418
2419 if (flag) {
2420 printf("WARNING: Possible error in assignment file `%s'\n",
2421 inassignname);
2422 printf(" Max assignment set (%d) greater than "
2423 "max processor rank (%d)\n", flag, np-1);
2424 printf(" Some vertices given random initial assignments\n");
2425 }
2426
2427 /* Check for spurious extra stuff in file. */
2428 flag = 0;
2429 end_flag = 0;
2430 while (!flag && end_flag != -1) {
2431 chaco_read_int(finassign, &end_flag);
2432 if (!end_flag)
2433 flag = 1;
2434 }
2435 if (flag) {
2436 printf("WARNING: Possible error in assignment file `%s'\n", inassignname);
2437 printf(" Numerical data found after expected end of file\n");
2438 }
2439
2440 fclose(finassign);
2441 return (0);
2442}
2443
2444// Pamgen Reader
2445void UserInputForTests::readPamgenMeshFile(string path, string testData)
2446{
2447#ifdef HAVE_ZOLTAN2_PAMGEN
2448 int rank = this->tcomm_->getRank();
2449 if (verbose_ && tcomm_->getRank() == 0)
2450 std::cout << "UserInputForTestsBD::readPamgenFile, Read: " << testData << std::endl;
2451
2452 size_t len;
2453 std::fstream file;
2454 int dimension;
2455 if (rank == 0){
2456 // set file name
2457 std::ostringstream meshFileName;
2458 meshFileName << path << "/" << testData << ".pmgen";
2459 // open file
2460
2461 file.open(meshFileName.str(), std::ios::in);
2462
2463 if(!file.is_open()) // may be a problem with path or filename
2464 {
2465 if(verbose_ && tcomm_->getRank() == 0)
2466 {
2467 std::cout << "Unable to open pamgen mesh: ";
2468 std::cout << meshFileName.str();
2469 std::cout <<"\nPlease check file path and name." << std::endl;
2470 }
2471 len = 0; // broadcaset 0 length ->will cause exit
2472 }else{
2473 // write to character array
2474 // get size of file
2475 file.seekg (0,file.end);
2476 len = file.tellg();
2477 file.seekg (0);
2478
2479 // get dimension
2480 dimension = 2;
2481 std::string line;
2482 while(std::getline(file,line))
2483 {
2484 if( line.find("nz") != std::string::npos ||
2485 line.find("nphi") != std::string::npos)
2486 {
2487 dimension = 3;
2488 break;
2489 }
2490 }
2491
2492 file.clear();
2493 file.seekg(0, std::ios::beg);
2494 }
2495 }
2496
2497 // broadcast the file size
2498 this->tcomm_->broadcast(0,sizeof(int), (char *)&dimension);
2499 this->tcomm_->broadcast(0,sizeof(size_t),(char *)&len);
2500 this->tcomm_->barrier();
2501
2502 if(len == 0){
2503 if(verbose_ && tcomm_->getRank() == 0)
2504 std::cout << "Pamgen Mesh file size == 0, exiting UserInputForTests early." << std::endl;
2505 return;
2506 }
2507
2508 char * file_data = new char[len+1];
2509 file_data[len] = '\0'; // critical to null terminate buffer
2510 if(rank == 0){
2511 file.read(file_data,len); // if proc 0 then read file
2512 }
2513
2514 // broadcast the file to the world
2515 this->tcomm_->broadcast(0,(int)len+1,file_data);
2516 this->tcomm_->barrier();
2517
2518 // Create the PamgenMesh
2519
2520 this->pamgen_mesh = rcp(new PamgenMesh);
2521 this->havePamgenMesh = true;
2522 pamgen_mesh->createMesh(file_data,dimension,this->tcomm_);
2523
2524 // save mesh info
2525 pamgen_mesh->storeMesh();
2526 this->tcomm_->barrier();
2527
2528 // set coordinates
2529 this->setPamgenCoordinateMV();
2530
2531 // set adjacency graph
2532 this->setPamgenAdjacencyGraph();
2533
2534 this->tcomm_->barrier();
2535 if(rank == 0) file.close();
2536 delete [] file_data;
2537#else
2538 throw std::runtime_error("Pamgen requested but Trilinos "
2539 "not built with Pamgen");
2540#endif
2541}
2542
2543#ifdef HAVE_ZOLTAN2_PAMGEN
2544void UserInputForTests::setPamgenCoordinateMV()
2545{
2546 int dimension = pamgen_mesh->num_dim;
2547 // get coordinate and point info;
2548// zlno_t numLocalPoints = pamgen_mesh->num_nodes;
2549// zgno_t numGlobalPoints = pamgen_mesh->num_nodes_global;
2550 zgno_t numelements = pamgen_mesh->num_elem;
2551 zgno_t numGlobalElements = pamgen_mesh->num_elems_global;
2552
2553 // make a Tpetra map
2554 Array<zgno_t> elementList(numelements);
2555 for (Array<zgno_t>::size_type k = 0; k < numelements; ++k) {
2556 elementList[k] = pamgen_mesh->element_order_map[k];
2557 }
2558 auto mp = rcp (new map_t (numGlobalElements, elementList, 0, this->tcomm_));
2559
2560 // set the xyz_ multivector
2561 xyz_ = RCP<tMVector_t>(new tMVector_t(mp, dimension, false));
2562 {
2563 auto lclXYZ = xyz_->getLocalViewHost(Tpetra::Access::OverwriteAll);
2564 for(int i = 0; i < dimension; ++i){
2565 double *tmp = &pamgen_mesh->element_coord[i*numelements];
2566 for (int j = 0; j < numelements; j++)
2567 lclXYZ(j, i) = tmp[j];
2568 }
2569 }
2570}
2571
2572void UserInputForTests::setPamgenAdjacencyGraph()
2573{
2574// int rank = this->tcomm_->getRank();
2575// if(rank == 0) std::cout << "Making a graph from our pamgen mesh...." << std::endl;
2576
2577 // Define Types
2578// typedef zlno_t lno_t;
2579// typedef zgno_t gno_t;
2580
2581 // get info for setting up map
2582 size_t local_nodes = (size_t)this->pamgen_mesh->num_nodes;
2583 size_t local_els = (size_t)this->pamgen_mesh->num_elem;
2584
2585 size_t global_els = (size_t)this->pamgen_mesh->num_elems_global; // global rows
2586 size_t global_nodes = (size_t)this->pamgen_mesh->num_nodes_global; //global columns
2587 // make map with global elements assigned to this mesh
2588 // make range map
2589// if(rank == 0) std::cout << "Building Rowmap: " << std::endl;
2590 RCP<const map_t> rowMap = rcp(new map_t(global_els,0,this->tcomm_));
2591 RCP<const map_t> rangeMap = rowMap;
2592
2593 // make domain map
2594 RCP<const map_t> domainMap = rcp(new map_t(global_nodes,0,this->tcomm_));
2595
2596 // Get max number of nodes per element
2597 int blks = this->pamgen_mesh->num_elem_blk;
2598 int max_nodes_per_el = 0;
2599 for(int i = 0; i < blks; i++)
2600 if (this->pamgen_mesh->nodes_per_element[i] > max_nodes_per_el)
2601 max_nodes_per_el = this->pamgen_mesh->nodes_per_element[i];
2602
2603 // make the element-node adjacency matrix
2604 Teuchos::RCP<tcrsMatrix_t> C = rcp(new tcrsMatrix_t(rowMap,max_nodes_per_el));
2605
2606 Array<zgno_t> g_el_ids(local_els);
2607 for (size_t k = 0; k < local_els; ++k) {
2608 g_el_ids[k] = pamgen_mesh->global_element_numbers[k]-1;
2609 }
2610
2611 Array<zgno_t> g_node_ids(local_nodes);
2612 for (size_t k = 0; k < local_nodes; ++k) {
2613 g_node_ids[k] = pamgen_mesh->global_node_numbers[k]-1;
2614 }
2615
2616 zlno_t el_no = 0;
2617 zscalar_t one = static_cast<zscalar_t>(1);
2618
2619// if(rank == 0) std::cout << "Writing C... " << std::endl;
2620 for(int i = 0; i < blks; i++)
2621 {
2622 int el_per_block = this->pamgen_mesh->elements[i];
2623 int nodes_per_el = this->pamgen_mesh->nodes_per_element[i];
2624 int * connect = this->pamgen_mesh->elmt_node_linkage[i];
2625
2626 for(int j = 0; j < el_per_block; j++)
2627 {
2628 const zgno_t gid = static_cast<zgno_t>(g_el_ids[el_no]);
2629 for(int k = 0; k < nodes_per_el; k++)
2630 {
2631 int g_node_i = g_node_ids[connect[j*nodes_per_el+k]-1];
2632 C->insertGlobalValues(gid,
2633 Teuchos::tuple<zgno_t>(g_node_i),
2634 Teuchos::tuple<zscalar_t>(one));
2635 }
2636 el_no++;
2637 }
2638 }
2639
2640 C->fillComplete(domainMap, rangeMap);
2641
2642
2643 // Compute product C*C'
2644// if(rank == 0) std::cout << "Compute Multiplication C... " << std::endl;
2645 RCP<tcrsMatrix_t> A = rcp(new tcrsMatrix_t(rowMap,0));
2646 Tpetra::MatrixMatrix::Multiply(*C, false, *C, true, *A);
2647
2648 // remove entries not adjacent
2649 // make graph
2650// if(rank == 0) std::cout << "Writing M_... " << std::endl;
2651 this->M_ = rcp(new tcrsMatrix_t(rowMap, A->getGlobalMaxNumRowEntries()));
2652
2653// if(rank == 0) std::cout << "\nSetting graph of connectivity..." << std::endl;
2654 Teuchos::ArrayView<const zgno_t> rowMapElementList =
2655 rowMap->getLocalElementList();
2656 for (Teuchos_Ordinal ii = 0; ii < rowMapElementList.size(); ii++)
2657 {
2658 zgno_t gid = rowMapElementList[ii];
2659 size_t numEntriesInRow = A->getNumEntriesInGlobalRow (gid);
2660 typename tcrsMatrix_t::nonconst_global_inds_host_view_type rowinds("Indices", numEntriesInRow);
2661 typename tcrsMatrix_t::nonconst_values_host_view_type rowvals("Values", numEntriesInRow);
2662
2663 // modified
2664 Array<zscalar_t> mod_rowvals;
2665 Array<zgno_t> mod_rowinds;
2666 A->getGlobalRowCopy (gid, rowinds, rowvals, numEntriesInRow);
2667 for (size_t i = 0; i < numEntriesInRow; i++) {
2668// if (rowvals[i] == 2*(this->pamgen_mesh->num_dim-1))
2669// {
2670 if (rowvals[i] >= 1)
2671 {
2672 mod_rowvals.push_back(one);
2673 mod_rowinds.push_back(rowinds[i]);
2674 }
2675 }
2676 this->M_->insertGlobalValues(gid, mod_rowinds, mod_rowvals);
2677 }
2678
2679 this->M_->fillComplete();
2681 // if(rank == 0) std::cout << "Completed M... " << std::endl;
2682
2683}
2684
2685#endif
2686
2687#endif
#define TEST_FAIL_AND_THROW(comm, ok, s)
const char param_comment
int buildCrsMatrix(int xdim, int ydim, int zdim, std::string problemType, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, Teuchos::RCP< Tpetra::CrsMatrix< scalar_t, lno_t, gno_t, nod_t > > &M_)
USERINPUT_FILE_FORMATS
A class that generates typical user input for testing.
@ MATRIX_MARKET
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
common code used by tests
float zscalar_t
Tpetra::Map ::local_ordinal_type zlno_t
Tpetra::Map ::global_ordinal_type zgno_t
keep typedefs that commonly appear in many places localized
Traits of Xpetra classes, including migration method.
int getNumWeights()
#######END Predistribution functions######################//
map_t::node_type default_znode_t
RCP< xcrsGraph_t > getUIXpetraCrsGraph()
Tpetra::Map< zlno_t, zgno_t, znode_t > map_t
static void getUIRandomData(unsigned int seed, zlno_t length, zscalar_t min, zscalar_t max, ArrayView< ArrayRCP< zscalar_t > > data)
Generate lists of random scalars.
Tpetra::Export< zlno_t, zgno_t, znode_t > export_t
RCP< tVector_t > getUITpetraVector()
Tpetra::Import< zlno_t, zgno_t, znode_t > import_t
RCP< tMVector_t > getUIEdgeWeights()
RCP< xMVector_t > getUIXpetraMultiVector(int nvec)
bool hasInputDataType(const string &input_type)
RCP< tMVector_t > getUITpetraMultiVector(int nvec)
RCP< tMVector_t > getUICoordinates()
RCP< tcrsGraph_t > getUITpetraCrsGraph()
RCP< xVector_t > getUIXpetraVector()
RCP< xcrsMatrix_t > getUIXpetraCrsMatrix()
RCP< tcrsMatrix_t > getUITpetraCrsMatrix()
UserInputForTests(string path, string testData, const RCP< const Comm< int > > &c, bool debugInfo=false, bool distributeInput=true)
Constructor that reads in a matrix/graph from disk.
RCP< tMVector_t > getUIWeights()
static const std::string fail
GeometricGen::GeometricGenerator< zscalar_t, zlno_t, zgno_t, znode_t > geometricgen_t
Tpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > tcrsMatrix_t
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tMVector_t
Tpetra::Vector< zscalar_t, zlno_t, zgno_t, znode_t > tVector_t
fname
Begin.
Definition validXML.py:19
static RCP< tMVector_t > coordinates
static RCP< User > convertToXpetra(const RCP< User > &a)
Convert the object to its Xpetra wrapped version.