void convert_snp_affymetrix_C(char **dirname_, char **filelist, unsigned *files_amount_, char **map_filename_, char **outfilename_, unsigned *skipaffym, char **alleleID_names, char *alleleID, unsigned *alleleID_amount) { char *outfilename = *outfilename_; char *dirname = *dirname_; char *map_filename = *map_filename_; unsigned files_amount=*files_amount_; std::map<std::string, char> coding; for(unsigned i=0 ; i<*alleleID_amount ; i++) { coding[alleleID_names[i]] = alleleID[i]; } Rprintf("reading map...\n"); //std::cout<<"reading map...\n"; AffymetrixChipMap Map(map_filename, 2, 0, 2, 4, 5, 3, 9, 10, 6); //std::cout<<"map is read...\n"; Rprintf("map is read...\n"); if(Map.get_exclude_amount() != 0) { Rprintf("%i SNPs excluded from annotation because of absent enough information annotation file\n", Map.get_exclude_amount()); } std::vector<ChipData *> ids_chip; for(unsigned i=0 ; i<files_amount ; i++) { std::string file = (std::string(dirname) + "/" + std::string(filelist[i])); Rprintf("%i: opening file %s\n", i+1, file.c_str()); ids_chip.push_back(new affymetrix_chip_data(file, 0, 1, *skipaffym)); } unsigned id_amount=ids_chip.size(); std::ofstream outfile(outfilename); if(!outfile.is_open()){error("Can not open file \"\"\n",outfilename);} Rprintf("Save to file %s\n", outfilename); outfile << "#GenABEL raw data version 0.1\n"; //save IDs Rprintf("saving Id names...\n"); std::string filelist_str; for(unsigned id=0 ; id<files_amount ; id++) { filelist_str = filelist[id]; for(unsigned i=0 ; i<filelist_str.length() ; i++) { if(filelist_str[i]==' ') filelist_str[i]='_'; } outfile<<filelist_str<<" "; } outfile<<"\n"; std::string snpname; unsigned long snp_excludet_from_output_data=0; //save snpnames Rprintf("saving SNP names...\n"); unsigned snp_amount=ids_chip[0]->get_snp_amount(); for(unsigned snp=0 ; snp<snp_amount ; snp++) { snpname = ids_chip[0]->get_snp_name(snp); if(Map.is_snp_in_map(snpname)){outfile<<Map.recode_snp(snpname.c_str())<<" ";} else{snp_excludet_from_output_data++;} } outfile<<"\n"; //save chromosome Rprintf("saving chromosome data...\n"); for(unsigned snp=0 ; snp<snp_amount ; snp++) { snpname = ids_chip[0]->get_snp_name(snp); if(Map.is_snp_in_map(snpname)){outfile<<Map.get_chromosome(snpname.c_str())<<" ";} } outfile<<"\n"; //save position (map) Rprintf("saving position data...\n"); for(unsigned snp=0 ; snp<snp_amount ; snp++) { snpname = ids_chip[0]->get_snp_name(snp); if(Map.is_snp_in_map(snpname)){outfile<<Map.get_phisical_position(snpname.c_str())<<" ";} } outfile<<"\n"; //save coding Rprintf("saving coding data...\n"); outfile.flags(std::ios_base::hex); //for what is it <-? for(unsigned snp=0 ; snp<snp_amount ; snp++) { snpname = ids_chip[0]->get_snp_name(snp); if(Map.is_snp_in_map(snpname)) { outfile.width(2); outfile.fill('0'); static std::string allele_A, allele_B; allele_A = Map.get_allele_A(snpname.c_str()); allele_B = Map.get_allele_B(snpname.c_str()); outfile<<unsigned(coding[allele_A+allele_B])<<" "; } } outfile<<"\n"; //save strand Rprintf("saving strand data...\n"); std::map<char, unsigned> strand_recode; strand_recode['u']=0; strand_recode['+']=1; strand_recode['-']=2; for(unsigned snp=0 ; snp<snp_amount ; snp++) { snpname = ids_chip[0]->get_snp_name(snp); if(Map.is_snp_in_map(snpname)) { outfile.width(2); outfile.fill('0'); static char strand; strand = Map.get_strand(snpname.c_str()); outfile<<strand_recode[strand]<<" "; } } outfile<<"\n"; //save polymorphism data Rprintf("saving polymorphism data...\n"); unsigned long gtps_byte_amount = (unsigned long)ceil((double)id_amount/4.); char *gtps_for_one_snp = new char[gtps_byte_amount]; unsigned *rearrangement_array = new unsigned[4]; rearrangement_array[0] = 6; rearrangement_array[1] = 4; rearrangement_array[2] = 2; rearrangement_array[3] = 0; for(unsigned snp=0 ; snp<snp_amount ; snp++) { if(!Map.is_snp_in_map(ids_chip[0]->get_snp_name(snp))) {continue;} // skip SNP if it doesn't exsist in our MAP for(unsigned i=0 ; i<gtps_byte_amount ; i++) gtps_for_one_snp[i]=0; static unsigned counter1, counter2; counter1=counter2=0; for(unsigned id=0 ; id<id_amount ; id++) { gtps_for_one_snp[counter2] = gtps_for_one_snp[counter2] | ids_chip[id]->get_polymorphism(snp) << rearrangement_array[counter1]; counter1++; if(counter1==4) {counter1=0; counter2++;} } for(unsigned id=0 ; id<gtps_byte_amount ; id++) { outfile.width(2); outfile.fill('0'); outfile<<unsigned(gtps_for_one_snp[id]&0xFF)<<" "; } outfile<<"\n"; } delete[] gtps_for_one_snp; delete[] rearrangement_array; Rprintf("%i SNPs excluded bacause of absent in annotation\n", snp_excludet_from_output_data); Rprintf("Total %i SNPs are written into output file\n", snp_amount-snp_excludet_from_output_data); Rprintf("Finshed... Data saved into file %s\n", outfilename); outfile.close(); }
//========================================================================= int Epetra_IntVector::PackAndPrepare(const Epetra_SrcDistObject & Source, int NumExportIDs, int * ExportLIDs, int & LenExports, char * & Exports, int & SizeOfPacket, int * Sizes, bool & VarSizes, Epetra_Distributor & Distor) { (void)Sizes; (void)VarSizes; (void)Distor; const Epetra_IntVector & A = dynamic_cast<const Epetra_IntVector &>(Source); int j, jj, k; int * From; A.ExtractView(&From); int MaxElementSize = Map().MaxElementSize(); bool ConstantElementSize = Map().ConstantElementSize(); int * FromFirstPointInElementList = 0; int * FromElementSizeList = 0; if (!ConstantElementSize) { FromFirstPointInElementList = A.Map().FirstPointInElementList(); FromElementSizeList = A.Map().ElementSizeList(); } SizeOfPacket = MaxElementSize * (int)sizeof(int); if(NumExportIDs*SizeOfPacket>LenExports) { if (LenExports>0) delete [] Exports; LenExports = NumExportIDs*SizeOfPacket; Exports = new char[LenExports]; } int * ptr; if (NumExportIDs>0) { ptr = (int *) Exports; // Point entry case if (MaxElementSize==1) for (j=0; j<NumExportIDs; j++) *ptr++ = From[ExportLIDs[j]]; // constant element size case else if (ConstantElementSize) { for (j=0; j<NumExportIDs; j++) { jj = MaxElementSize*ExportLIDs[j]; for (k=0; k<MaxElementSize; k++) *ptr++ = From[jj+k]; } } // variable element size case else { int thisSizeOfPacket = MaxElementSize; for (j=0; j<NumExportIDs; j++) { ptr = (int *) Exports + j*thisSizeOfPacket; jj = FromFirstPointInElementList[ExportLIDs[j]]; int ElementSize = FromElementSizeList[ExportLIDs[j]]; for (k=0; k<ElementSize; k++) *ptr++ = From[jj+k]; } } } return(0); }
int main(int argc, char *argv[]) { int ierr = 0, forierr = 0; bool debug = false; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< std::endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << std::endl << std::endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 10000; int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0, Comm); // Get update list and number of local equations from newly created Map int* MyGlobalElements = new int[Map.NumMyElements()]; Map.MyGlobalElements(MyGlobalElements); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNz = new int[NumMyEquations]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (int i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy, Map, NumNz); EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 double* Values = new double[2]; Values[0] = -1.0; Values[1] = -1.0; int* Indices = new int[2]; double two = 2.0; int NumEntries; forierr = 0; for (int i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, Values, Indices)==0); forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, MyGlobalElements+i)>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); int * indexOffsetTmp; int * indicesTmp; double * valuesTmp; // Finish up EPETRA_TEST_ERR(!(A.IndicesAreGlobal()),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr); // Should fail EPETRA_TEST_ERR(!(A.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr); // Should fail EPETRA_TEST_ERR(!(A.IndicesAreLocal()),ierr); EPETRA_TEST_ERR(A.StorageOptimized(),ierr); A.OptimizeStorage(); EPETRA_TEST_ERR(!(A.StorageOptimized()),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==0),ierr); // Should succeed const Epetra_CrsGraph & GofA = A.Graph(); EPETRA_TEST_ERR((indicesTmp!=GofA[0] || valuesTmp!=A[0]),ierr); // Extra check to see if operator[] is consistent EPETRA_TEST_ERR(A.UpperTriangular(),ierr); EPETRA_TEST_ERR(A.LowerTriangular(),ierr); int NumMyNonzeros = 3 * NumMyEquations; if(A.LRID(0) >= 0) NumMyNonzeros--; // If I own first global row, then there is one less nonzero if(A.LRID(NumGlobalEquations-1) >= 0) NumMyNonzeros--; // If I own last global row, then there is one less nonzero EPETRA_TEST_ERR(check(A, NumMyEquations, NumGlobalEquations, NumMyNonzeros, 3*NumGlobalEquations-2, MyGlobalElements, verbose),ierr); forierr = 0; for (int i = 0; i < NumMyEquations; i++) forierr += !(A.NumGlobalEntries(MyGlobalElements[i])==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); forierr = 0; for (int i = 0; i < NumMyEquations; i++) forierr += !(A.NumMyEntries(i)==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << std::endl<< std::endl; EPETRA_TEST_ERR(check_graph_sharing(Comm),ierr); // Create vectors for Power method Epetra_Vector q(Map); Epetra_Vector z(Map); Epetra_Vector resid(Map); // variable needed for iteration double lambda = 0.0; // int niters = 10000; int niters = 200; double tolerance = 1.0e-1; ///////////////////////////////////////////////////////////////////////////////////////////////// // Iterate Epetra_Flops flopcounter; A.SetFlopCounter(flopcounter); q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); Epetra_Time timer(Comm); EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); double elapsed_time = timer.ElapsedTime(); double total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); double MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for first solve = " << MFLOPs << std::endl<< std::endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << std::endl; // Iterate lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for transpose solve = " << MFLOPs << std::endl<< endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Increase diagonal dominance if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n" << endl; if (A.MyGlobalRow(0)) { int numvals = A.NumGlobalEntries(0); double * Rowvals = new double [numvals]; int * Rowinds = new int [numvals]; A.ExtractGlobalRowCopy(0, numvals, numvals, Rowvals, Rowinds); // Get A[0,0] for (int i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0; A.ReplaceGlobalValues(0, numvals, Rowvals, Rowinds); delete [] Rowvals; delete [] Rowinds; } // Iterate (again) lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for second solve = " << MFLOPs << endl<< endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << endl; // Iterate (again) lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for tranpose of second solve = " << MFLOPs << endl<< endl; if (verbose) cout << "\n\n*****Testing constant entry constructor" << endl<< endl; Epetra_CrsMatrix AA(Copy, Map, 5); if (debug) Comm.Barrier(); double dble_one = 1.0; for (int i=0; i< NumMyEquations; i++) AA.InsertGlobalValues(MyGlobalElements[i], 1, &dble_one, MyGlobalElements+i); // Note: All processors will call the following Insert routines, but only the processor // that owns it will actually do anything int One = 1; if (AA.MyGlobalRow(0)) { EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 0, &dble_one, &One)==0),ierr); } else EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 1, &dble_one, &One)==-1),ierr); EPETRA_TEST_ERR(!(AA.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(AA.StorageOptimized(),ierr); EPETRA_TEST_ERR(!(AA.UpperTriangular()),ierr); EPETRA_TEST_ERR(!(AA.LowerTriangular()),ierr); if (debug) Comm.Barrier(); EPETRA_TEST_ERR(check(AA, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); if (debug) Comm.Barrier(); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(AA.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing copy constructor" << endl<< endl; Epetra_CrsMatrix B(AA); EPETRA_TEST_ERR(check(B, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(B.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing local view constructor" << endl<< endl; Epetra_CrsMatrix BV(View, AA.RowMap(), AA.ColMap(), 0); forierr = 0; int* Inds; double* Vals; for (int i = 0; i < NumMyEquations; i++) { forierr += !(AA.ExtractMyRowView(i, NumEntries, Vals, Inds)==0); forierr += !(BV.InsertMyValues(i, NumEntries, Vals, Inds)==0); } BV.FillComplete(false); EPETRA_TEST_ERR(check(BV, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(BV.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing post construction modifications" << endl<< endl; EPETRA_TEST_ERR(!(B.InsertGlobalValues(0, 1, &dble_one, &One)==-2),ierr); // Release all objects delete [] NumNz; delete [] Values; delete [] Indices; delete [] MyGlobalElements; if (verbose1) { // Test ostream << operator (if verbose1) // Construct a Map that puts 2 equations on each PE int NumMyElements1 = 2; int NumMyEquations1 = NumMyElements1; int NumGlobalEquations1 = NumMyEquations1*NumProc; Epetra_Map Map1(-1, NumMyElements1, 0, Comm); // Get update list and number of local equations from newly created Map int * MyGlobalElements1 = new int[Map1.NumMyElements()]; Map1.MyGlobalElements(MyGlobalElements1); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int * NumNz1 = new int[NumMyEquations1]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (int i=0; i<NumMyEquations1; i++) if (MyGlobalElements1[i]==0 || MyGlobalElements1[i] == NumGlobalEquations1-1) NumNz1[i] = 1; else NumNz1[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A1(Copy, Map1, NumNz1); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 double *Values1 = new double[2]; Values1[0] = -1.0; Values1[1] = -1.0; int *Indices1 = new int[2]; double two1 = 2.0; int NumEntries1; forierr = 0; for (int i=0; i<NumMyEquations1; i++) { if (MyGlobalElements1[i]==0) { Indices1[0] = 1; NumEntries1 = 1; } else if (MyGlobalElements1[i] == NumGlobalEquations1-1) { Indices1[0] = NumGlobalEquations1-2; NumEntries1 = 1; } else { Indices1[0] = MyGlobalElements1[i]-1; Indices1[1] = MyGlobalElements1[i]+1; NumEntries1 = 2; } forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], NumEntries1, Values1, Indices1)==0); forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], 1, &two1, MyGlobalElements1+i)>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); delete [] Indices1; delete [] Values1; // Finish up EPETRA_TEST_ERR(!(A1.FillComplete(false)==0),ierr); // Test diagonal extraction function Epetra_Vector checkDiag(Map1); EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag)==0),ierr); forierr = 0; for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==two1); EPETRA_TEST_ERR(forierr,ierr); // Test diagonal replacement method forierr = 0; for (int i=0; i<NumMyEquations1; i++) checkDiag[i]=two1*two1; EPETRA_TEST_ERR(forierr,ierr); EPETRA_TEST_ERR(!(A1.ReplaceDiagonalValues(checkDiag)==0),ierr); Epetra_Vector checkDiag1(Map1); EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag1)==0),ierr); forierr = 0; for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==checkDiag1[i]); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nDiagonal extraction and replacement OK.\n\n" << endl; double orignorm = A1.NormOne(); EPETRA_TEST_ERR(!(A1.Scale(4.0)==0),ierr); EPETRA_TEST_ERR(!(A1.NormOne()!=orignorm),ierr); if (verbose) cout << "\n\nMatrix scale OK.\n\n" << endl; if (verbose) cout << "\n\nPrint out tridiagonal matrix, each part on each processor.\n\n" << endl; cout << A1 << endl; // Release all objects delete [] NumNz1; delete [] MyGlobalElements1; } if (verbose) cout << "\n\n*****Testing LeftScale and RightScale" << endl << endl; int NumMyElements2 = 7; int NumMyRows2 = 1;//This value should not be changed without editing the // code below. Epetra_Map RowMap(-1,NumMyRows2,0,Comm); Epetra_Map ColMap(NumMyElements2,NumMyElements2,0,Comm); // The DomainMap needs to be different from the ColMap for the test to // be meaningful. Epetra_Map DomainMap(NumMyElements2,0,Comm); int NumMyRangeElements2 = 0; // We need to distribute the elements differently for the range map also. if (MyPID % 2 == 0) NumMyRangeElements2 = NumMyRows2*2; //put elements on even number procs if (NumProc % 2 == 1 && MyPID == NumProc-1) NumMyRangeElements2 = NumMyRows2; //If number of procs is odd, put // the last NumMyElements2 elements on the last proc Epetra_Map RangeMap(-1,NumMyRangeElements2,0,Comm); Epetra_CrsMatrix A2(Copy,RowMap,ColMap,NumMyElements2); double * Values2 = new double[NumMyElements2]; int * Indices2 = new int[NumMyElements2]; for (int i=0; i<NumMyElements2; i++) { Values2[i] = i+MyPID; Indices2[i]=i; } A2.InsertMyValues(0,NumMyElements2,Values2,Indices2); A2.FillComplete(DomainMap,RangeMap,false); Epetra_CrsMatrix A2copy(A2); double * RowLeftScaleValues = new double[NumMyRows2]; double * ColRightScaleValues = new double[NumMyElements2]; int RowLoopLength = RowMap.MaxMyGID()-RowMap.MinMyGID()+1; for (int i=0; i<RowLoopLength; i++) RowLeftScaleValues[i] = (i + RowMap.MinMyGID() ) % 2 + 1; // For the column map, all procs own all elements for (int i=0; i<NumMyElements2;i++) ColRightScaleValues[i] = i % 2 + 1; int RangeLoopLength = RangeMap.MaxMyGID()-RangeMap.MinMyGID()+1; double * RangeLeftScaleValues = new double[RangeLoopLength]; int DomainLoopLength = DomainMap.MaxMyGID()-DomainMap.MinMyGID()+1; double * DomainRightScaleValues = new double[DomainLoopLength]; for (int i=0; i<RangeLoopLength; i++) RangeLeftScaleValues[i] = 1.0/((i + RangeMap.MinMyGID() ) % 2 + 1); for (int i=0; i<DomainLoopLength;i++) DomainRightScaleValues[i] = 1.0/((i + DomainMap.MinMyGID() ) % 2 + 1); Epetra_Vector xRow(View,RowMap,RowLeftScaleValues); Epetra_Vector xCol(View,ColMap,ColRightScaleValues); Epetra_Vector xRange(View,RangeMap,RangeLeftScaleValues); Epetra_Vector xDomain(View,DomainMap,DomainRightScaleValues); double A2infNorm = A2.NormInf(); double A2oneNorm = A2.NormOne(); if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr); double A2infNorm1 = A2.NormInf(); double A2oneNorm1 = A2.NormOne(); bool ScalingBroke = false; if (A2infNorm1>2*A2infNorm||A2infNorm1<A2infNorm) { EPETRA_TEST_ERR(-31,ierr); ScalingBroke = true; } if (A2oneNorm1>2*A2oneNorm||A2oneNorm1<A2oneNorm) { EPETRA_TEST_ERR(-32,ierr); ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.RightScale(xCol),ierr); double A2infNorm2 = A2.NormInf(); double A2oneNorm2 = A2.NormOne(); if (A2infNorm2>=2*A2infNorm1||A2infNorm2<=A2infNorm1) { EPETRA_TEST_ERR(-33,ierr); ScalingBroke = true; } if (A2oneNorm2>2*A2oneNorm1||A2oneNorm2<=A2oneNorm1) { EPETRA_TEST_ERR(-34,ierr); ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr); double A2infNorm3 = A2.NormInf(); double A2oneNorm3 = A2.NormOne(); // The last two scaling ops cancel each other out if (A2infNorm3!=A2infNorm1) { EPETRA_TEST_ERR(-35,ierr) ScalingBroke = true; } if (A2oneNorm3!=A2oneNorm1) { EPETRA_TEST_ERR(-36,ierr) ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr); double A2infNorm4 = A2.NormInf(); double A2oneNorm4 = A2.NormOne(); // The 4 scaling ops all cancel out if (A2infNorm4!=A2infNorm) { EPETRA_TEST_ERR(-37,ierr) ScalingBroke = true; } if (A2oneNorm4!=A2oneNorm) { EPETRA_TEST_ERR(-38,ierr) ScalingBroke = true; } // // Now try changing the values underneath and make sure that // telling one process about the change causes NormInf() and // NormOne() to recompute the norm on all processes. // double *values; int num_my_rows = A2.NumMyRows() ; int num_entries; for ( int i=0 ; i< num_my_rows; i++ ) { EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr ); for ( int j = 0 ; j <num_entries; j++ ) { values[j] *= 2.0; } } if ( MyPID == 0 ) A2.SumIntoGlobalValues( 0, 0, 0, 0 ) ; double A2infNorm5 = A2.NormInf(); double A2oneNorm5 = A2.NormOne(); if (A2infNorm5!=2.0 * A2infNorm4) { EPETRA_TEST_ERR(-39,ierr) ScalingBroke = true; } if (A2oneNorm5!= 2.0 * A2oneNorm4) { EPETRA_TEST_ERR(-40,ierr) ScalingBroke = true; } // // Restore the values underneath // for ( int i=0 ; i< num_my_rows; i++ ) { EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr ); for ( int j = 0 ; j <num_entries; j++ ) { values[j] /= 2.0; } } if (verbose1) cout << A2; if (ScalingBroke) { if (verbose) cout << endl << "LeftScale and RightScale tests FAILED" << endl << endl; } else { if (verbose) cout << endl << "LeftScale and RightScale tests PASSED" << endl << endl; } Comm.Barrier(); if (verbose) cout << "\n\n*****Testing InvRowMaxs and InvColMaxs" << endl << endl; if (verbose1) cout << A2 << endl; EPETRA_TEST_ERR(A2.InvRowMaxs(xRow),ierr); EPETRA_TEST_ERR(A2.InvRowMaxs(xRange),ierr); if (verbose1) cout << xRow << endl << xRange << endl; if (verbose) cout << "\n\n*****Testing InvRowSums and InvColSums" << endl << endl; bool InvSumsBroke = false; // Works! EPETRA_TEST_ERR(A2.InvRowSums(xRow),ierr); if (verbose1) cout << xRow; EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr); float A2infNormFloat = A2.NormInf(); if (verbose1) cout << A2 << endl; if (fabs(1.0-A2infNormFloat) > 1.e-5) { EPETRA_TEST_ERR(-41,ierr); InvSumsBroke = true; } // Works int expectedcode = 1; if (Comm.NumProc()>1) expectedcode = 0; EPETRA_TEST_ERR(!(A2.InvColSums(xDomain)==expectedcode),ierr); // This matrix has a single row, the first column has a zero, so a warning is issued. if (verbose1) cout << xDomain << endl; EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr); float A2oneNormFloat2 = A2.NormOne(); if (verbose1) cout << A2; if (fabs(1.0-A2oneNormFloat2)>1.e-5) { EPETRA_TEST_ERR(-42,ierr) InvSumsBroke = true; } // Works! EPETRA_TEST_ERR(A2.InvRowSums(xRange),ierr); if (verbose1) cout << xRange; EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr); float A2infNormFloat2 = A2.NormInf(); // We use a float so that rounding error // will not prevent the sum from being 1.0. if (verbose1) cout << A2; if (fabs(1.0-A2infNormFloat2)>1.e-5) { cout << "InfNorm should be = 1, but InfNorm = " << A2infNormFloat2 << endl; EPETRA_TEST_ERR(-43,ierr); InvSumsBroke = true; } // Doesn't work - may not need this test because column ownership is not unique /* EPETRA_TEST_ERR(A2.InvColSums(xCol),ierr); cout << xCol; EPETRA_TEST_ERR(A2.RightScale(xCol),ierr); float A2oneNormFloat = A2.NormOne(); cout << A2; if (fabs(1.0-A2oneNormFloat)>1.e-5) { EPETRA_TEST_ERR(-44,ierr); InvSumsBroke = true; } */ delete [] ColRightScaleValues; delete [] DomainRightScaleValues; if (verbose) cout << "Begin partial sum testing." << endl; // Test with a matrix that has partial sums for a subset of the rows // on multiple processors. (Except for the serial case, of course.) int NumMyRows3 = 2; // Changing this requires further changes below int * myGlobalElements = new int[NumMyRows3]; for (int i=0; i<NumMyRows3; i++) myGlobalElements[i] = MyPID+i; Epetra_Map RowMap3(NumProc*2, NumMyRows3, myGlobalElements, 0, Comm); int NumMyElements3 = 5; Epetra_CrsMatrix A3(Copy, RowMap3, NumMyElements3); double * Values3 = new double[NumMyElements3]; int * Indices3 = new int[NumMyElements3]; for (int i=0; i < NumMyElements3; i++) { Values3[i] = (int) (MyPID + (i+1)); Indices3[i]=i; } for (int i=0; i<NumMyRows3; i++) { A3.InsertGlobalValues(myGlobalElements[i],NumMyElements3,Values3,Indices3); } Epetra_Map RangeMap3(NumProc+1, 0, Comm); Epetra_Map DomainMap3(NumMyElements3, 0, Comm); EPETRA_TEST_ERR(A3.FillComplete(DomainMap3, RangeMap3,false),ierr); if (verbose1) cout << A3; Epetra_Vector xRange3(RangeMap3,false); Epetra_Vector xDomain3(DomainMap3,false); EPETRA_TEST_ERR(A3.InvRowSums(xRange3),ierr); if (verbose1) cout << xRange3; EPETRA_TEST_ERR(A3.LeftScale(xRange3),ierr); float A3infNormFloat = A3.NormInf(); if (verbose1) cout << A3; if (1.0!=A3infNormFloat) { cout << "InfNorm should be = 1, but InfNorm = " << A3infNormFloat <<endl; EPETRA_TEST_ERR(-61,ierr); InvSumsBroke = true; } // we want to take the transpose of our matrix and fill in different values. int NumMyColumns3 = NumMyRows3; Epetra_Map ColMap3cm(RowMap3); Epetra_Map RowMap3cm(A3.ColMap()); Epetra_CrsMatrix A3cm(Copy,RowMap3cm,ColMap3cm,NumProc+1); double *Values3cm = new double[NumMyColumns3]; int * Indices3cm = new int[NumMyColumns3]; for (int i=0; i<NumMyColumns3; i++) { Values3cm[i] = MyPID + i + 1; Indices3cm[i]= i + MyPID; } for (int ii=0; ii<NumMyElements3; ii++) { A3cm.InsertGlobalValues(ii, NumMyColumns3, Values3cm, Indices3cm); } // The DomainMap and the RangeMap from the last test will work fine for // the RangeMap and DomainMap, respectively, but I will make copies to // avaoid confusion when passing what looks like a DomainMap where we // need a RangeMap and vice vera. Epetra_Map RangeMap3cm(DomainMap3); Epetra_Map DomainMap3cm(RangeMap3); EPETRA_TEST_ERR(A3cm.FillComplete(DomainMap3cm,RangeMap3cm),ierr); if (verbose1) cout << A3cm << endl; // Again, we can copy objects from the last example. //Epetra_Vector xRange3cm(xDomain3); //Don't use at this time Epetra_Vector xDomain3cm(DomainMap3cm,false); EPETRA_TEST_ERR(A3cm.InvColSums(xDomain3cm),ierr); if (verbose1) cout << xDomain3cm << endl; EPETRA_TEST_ERR(A3cm.RightScale(xDomain3cm),ierr); float A3cmOneNormFloat = A3cm.NormOne(); if (verbose1) cout << A3cm << endl; if (1.0!=A3cmOneNormFloat) { cout << "OneNorm should be = 1, but OneNorm = " << A3cmOneNormFloat << endl; EPETRA_TEST_ERR(-62,ierr); InvSumsBroke = true; } if (verbose) cout << "End partial sum testing" << endl; if (verbose) cout << "Begin replicated testing" << endl; // We will now view the shared row as a repliated row, rather than one // that has partial sums of its entries on mulitple processors. // We will reuse much of the data used for the partial sum tesitng. Epetra_Vector xRow3(RowMap3,false); Epetra_CrsMatrix A4(Copy, RowMap3, NumMyElements3); for (int ii=0; ii < NumMyElements3; ii++) { Values3[ii] = (int)((ii*.6)+1.0); } for (int ii=0; ii<NumMyRows3; ii++) { A4.InsertGlobalValues(myGlobalElements[ii],NumMyElements3,Values3,Indices3); } EPETRA_TEST_ERR(A4.FillComplete(DomainMap3, RangeMap3,false),ierr); if (verbose1) cout << A4 << endl; // The next two lines should be expanded into a verifiable test. EPETRA_TEST_ERR(A4.InvRowMaxs(xRow3),ierr); EPETRA_TEST_ERR(A4.InvRowMaxs(xRange3),ierr); if (verbose1) cout << xRow3 << xRange3; EPETRA_TEST_ERR(A4.InvRowSums(xRow3),ierr); if (verbose1) cout << xRow3; EPETRA_TEST_ERR(A4.LeftScale(xRow3),ierr); float A4infNormFloat = A4.NormInf(); if (verbose1) cout << A4; if (2.0!=A4infNormFloat && NumProc != 1) { if (verbose1) cout << "InfNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but InfNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-63,ierr); InvSumsBroke = true; } else if (1.0!=A4infNormFloat && NumProc == 1) { if (verbose1) cout << "InfNorm should be = 1, but InfNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-63,ierr); InvSumsBroke = true; } Epetra_Vector xCol3cm(ColMap3cm,false); Epetra_CrsMatrix A4cm(Copy, RowMap3cm, ColMap3cm, NumProc+1); //Use values from A3cm for (int ii=0; ii<NumMyElements3; ii++) { A4cm.InsertGlobalValues(ii,NumMyColumns3,Values3cm,Indices3cm); } EPETRA_TEST_ERR(A4cm.FillComplete(DomainMap3cm, RangeMap3cm,false),ierr); if (verbose1) cout << A4cm << endl; // The next two lines should be expanded into a verifiable test. EPETRA_TEST_ERR(A4cm.InvColMaxs(xCol3cm),ierr); EPETRA_TEST_ERR(A4cm.InvColMaxs(xDomain3cm),ierr); if (verbose1) cout << xCol3cm << xDomain3cm; EPETRA_TEST_ERR(A4cm.InvColSums(xCol3cm),ierr); if (verbose1) cout << xCol3cm << endl; EPETRA_TEST_ERR(A4cm.RightScale(xCol3cm),ierr); float A4cmOneNormFloat = A4cm.NormOne(); if (verbose1) cout << A4cm << endl; if (2.0!=A4cmOneNormFloat && NumProc != 1) { if (verbose1) cout << "OneNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but OneNorm = " << A4cmOneNormFloat << endl; EPETRA_TEST_ERR(-64,ierr); InvSumsBroke = true; } else if (1.0!=A4cmOneNormFloat && NumProc == 1) { if (verbose1) cout << "OneNorm should be = 1, but OneNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-64,ierr); InvSumsBroke = true; } if (verbose) cout << "End replicated testing" << endl; if (InvSumsBroke) { if (verbose) cout << endl << "InvRowSums tests FAILED" << endl << endl; } else if (verbose) cout << endl << "InvRowSums tests PASSED" << endl << endl; A3cm.PutScalar(2.0); int nnz_A3cm = A3cm.Graph().NumGlobalNonzeros(); double check_frobnorm = sqrt(nnz_A3cm*4.0); double frobnorm = A3cm.NormFrobenius(); bool frobnorm_test_failed = false; if (fabs(check_frobnorm-frobnorm) > 5.e-5) { frobnorm_test_failed = true; } if (frobnorm_test_failed) { if (verbose) std::cout << "Frobenius-norm test FAILED."<<std::endl; EPETRA_TEST_ERR(-65, ierr); } delete [] Values2; delete [] Indices2; delete [] myGlobalElements; delete [] Values3; delete [] Indices3; delete [] Values3cm; delete [] Indices3cm; delete [] RangeLeftScaleValues; delete [] RowLeftScaleValues; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
//========================================================================= // Allows the source and target (\e this) objects to be compared for compatibility, return nonzero if not. int EpetraExt_BlockDiagMatrix::CheckSizes(const Epetra_SrcDistObject& Source){ return &Map() == &Source.Map(); }
void Epetra_IntVector::Print(std::ostream& os) const { int MyPID = Map().Comm().MyPID(); int NumProc = Map().Comm().NumProc(); for (int iproc=0; iproc < NumProc; iproc++) { if (MyPID==iproc) { int NumMyElements1 =Map(). NumMyElements(); int MaxElementSize1 = Map().MaxElementSize(); int * MyGlobalElements1_int = 0; long long * MyGlobalElements1_LL = 0; if(Map().GlobalIndicesInt()) { #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES MyGlobalElements1_int = Map().MyGlobalElements(); #else throw ReportError("Epetra_IntVector::Print: Global indices int but no API for it.",-1); #endif } else if(Map().GlobalIndicesLongLong()) { #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES MyGlobalElements1_LL = Map().MyGlobalElements64(); #else throw ReportError("Epetra_IntVector::Print: Global indices long long but no API for it.",-1); #endif } int * FirstPointInElementList1=0; if (MaxElementSize1!=1) FirstPointInElementList1 = Map().FirstPointInElementList(); if (MyPID==0) { os.width(8); os << " MyPID"; os << " "; os.width(12); if (MaxElementSize1==1) os << "GID "; else os << " GID/Point"; os.width(20); os << "Value "; os << std::endl; } for (int i=0; i < NumMyElements1; i++) { for (int ii=0; ii< Map().ElementSize(i); ii++) { int iii; os.width(10); os << MyPID; os << " "; os.width(10); if (MaxElementSize1==1) { if(MyGlobalElements1_int) os << MyGlobalElements1_int[i] << " "; if(MyGlobalElements1_LL) os << MyGlobalElements1_LL[i] << " "; iii = i; } else { if(MyGlobalElements1_int) os << MyGlobalElements1_int[i]<< "/" << ii << " "; if(MyGlobalElements1_LL) os << MyGlobalElements1_LL[i]<< "/" << ii << " "; iii = FirstPointInElementList1[i]+ii; } os.width(20); os << Values_[iii]; os << std::endl; } } os << std::flush; } // Do a few global ops to give I/O a chance to complete Map().Comm().Barrier(); Map().Comm().Barrier(); Map().Comm().Barrier(); } return; }
void DataDrawer::AddFormat(const char *id, Factory factory) { Mutex::Lock __(sDataDrawer); Map().Add(id, (void *)factory); }
//========================================================================= int EpetraExt_BlockDiagMatrix::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const{ int info; // Sanity Checks int NumVectors=X.NumVectors(); if(NumVectors!=Y.NumVectors()) EPETRA_CHK_ERR(-1); if(!HasComputed_ && (ApplyMode_==AM_INVERT || ApplyMode_==AM_FACTOR)) EPETRA_CHK_ERR(-2); //NTS: MultiVector's MyLength and [] Operators are "points" level operators //not a "block/element" level operators. const int *vlist=DataMap_->FirstPointInElementList(); const int *xlist=Map().FirstPointInElementList(); const int *blocksize=Map().ElementSizeList(); if(ApplyMode_==AM_MULTIPLY || ApplyMode_==AM_INVERT){ // Multiply & Invert mode have the same apply int NumBlocks=NumMyBlocks(); for(int i=0;i<NumBlocks;i++){ int Nb=blocksize[i]; int vidx0=vlist[i]; int xidx0=xlist[i]; for(int j=0;j<NumVectors;j++){ if(Nb==1) { // Optimize for size = 1 Y[j][xidx0]=Values_[vidx0]*X[j][xidx0]; } else if(Nb==2){ // Optimize for size = 2 Y[j][xidx0 ]=Values_[vidx0 ]*X[j][xidx0] + Values_[vidx0+2]*X[j][xidx0+1]; Y[j][xidx0+1]=Values_[vidx0+1]*X[j][xidx0] + Values_[vidx0+3]*X[j][xidx0+1]; } else{ // "Large" Block - Use BLAS //void GEMV (const char TRANS, const int M, const int N, const double ALPHA, const double *A, const int LDA, const double *X, const double BETA, double *Y, const int INCX=1, const int INCY=1) const GEMV('N',Nb,Nb,1.0,&Values_[vidx0],Nb,&X[j][xidx0],0.0,&Y[j][xidx0]); } } } } else{ // Factorization mode has a different apply int NumBlocks=NumMyBlocks(); for(int i=0;i<NumBlocks;i++){ int Nb=blocksize[i]; int vidx0=vlist[i]; int xidx0=xlist[i]; for(int j=0;j<NumVectors;j++){ if(Nb==1) { // Optimize for size = 1 - use the inverse Y[j][xidx0]=Values_[vidx0]*X[j][xidx0]; } else if(Nb==2){ // Optimize for size = 2 - use the inverse Y[j][xidx0 ]=Values_[vidx0 ]*X[j][xidx0] + Values_[vidx0+2]*X[j][xidx0+1]; Y[j][xidx0+1]=Values_[vidx0+1]*X[j][xidx0] + Values_[vidx0+3]*X[j][xidx0+1]; } else{ // "Large" Block - use LAPACK // void GETRS (const char TRANS, const int N, const int NRHS, const double *A, const int LDA, const int *IPIV, double *X, const int LDX, int *INFO) const for(int k=0;k<Nb;k++) Y[j][xidx0+k]=X[j][xidx0+k]; LAPACK.GETRS('N',Nb,1,&Values_[vidx0],Nb,&Pivots_[xidx0],&Y[j][xidx0],Nb,&info); if(info) EPETRA_CHK_ERR(info); } } } } return 0; }
int Drumm1(const Epetra_Map& map, bool verbose) { (void)verbose; //Simple 2-element problem (element as in "finite-element") from //Clif Drumm. Two triangular elements, one per processor, as shown //here: // // *----* // 3|\ 2| // | \ | // | 0\1| // | \| // *----* // 0 1 // //Element 0 on processor 0, element 1 on processor 1. //Processor 0 will own nodes 0,1 and processor 1 will own nodes 2,3. //Each processor will pass a 3x3 element-matrix to Epetra_FECrsMatrix. //After GlobalAssemble(), the matrix should be as follows: // // row 0: 2 1 0 1 //proc 0 row 1: 1 4 1 2 //---------------------------------- // row 2: 0 1 2 1 //proc 1 row 3: 1 2 1 4 // int numProcs = map.Comm().NumProc(); int localProc = map.Comm().MyPID(); if (numProcs != 2) return(0); //so first we'll set up a epetra_test::matrix_data object with //contents that match the above-described matrix. (but the //matrix_data object will have all 4 rows on each processor) int i; int rowlengths[4]; rowlengths[0] = 3; rowlengths[1] = 4; rowlengths[2] = 3; rowlengths[3] = 4; epetra_test::matrix_data matdata(4, rowlengths); for(i=0; i<4; ++i) { for(int j=0; j<matdata.rowlengths()[i]; ++j) { matdata.colindices()[i][j] = j; } } matdata.colindices()[0][2] = 3; matdata.colindices()[2][0] = 1; matdata.colindices()[2][1] = 2; matdata.colindices()[2][2] = 3; double** coefs = matdata.coefs(); coefs[0][0] = 2.0; coefs[0][1] = 1.0; coefs[0][2] = 1.0; coefs[1][0] = 1.0; coefs[1][1] = 4.0; coefs[1][2] = 1.0; coefs[1][3] = 2.0; coefs[2][0] = 1.0; coefs[2][1] = 2.0; coefs[2][2] = 1.0; coefs[3][0] = 1.0; coefs[3][1] = 2.0; coefs[3][2] = 1.0; coefs[3][3] = 4.0; //now we'll load a Epetra_FECrsMatrix with data that matches the //above-described finite-element problem. int indexBase = 0, ierr = 0; int myNodes[4]; double values[9]; values[0] = 2.0; values[1] = 1.0; values[2] = 1.0; values[3] = 1.0; values[4] = 2.0; values[5] = 1.0; values[6] = 1.0; values[7] = 1.0; values[8] = 2.0; int numMyNodes = 2; if (localProc == 0) { myNodes[0] = 0; myNodes[1] = 1; } else { myNodes[0] = 2; myNodes[1] = 3; } Epetra_Map Map(-1, numMyNodes, myNodes, indexBase, map.Comm()); numMyNodes = 3; if (localProc == 0) { myNodes[0] = 0; myNodes[1] = 1; myNodes[2] = 3; } else { myNodes[0] = 1; myNodes[1] = 2; myNodes[2] = 3; } int rowLengths = 3; Epetra_FECrsMatrix A(Copy, Map, rowLengths); EPETRA_TEST_ERR( A.InsertGlobalValues(numMyNodes, myNodes, numMyNodes, myNodes, values, Epetra_FECrsMatrix::ROW_MAJOR),ierr); EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); //now the test is to check whether the FECrsMatrix data matches the //epetra_test::matrix_data object... bool the_same = matdata.compare_local_data(A); if (!the_same) { return(-1); } return(0); }
Teuchos::RCP<Epetra_MultiVector> NetCDFFileIOHandler::Read( const std::vector<std::string>& filenames ) { #ifdef EPETRA_MPI Epetra_MpiComm comm( MPI_COMM_WORLD ); #else Epetra_SerialComm comm; #endif int ncid=0, row_id=0, col_id=0, ss_id=0, num_nod_var_id=0; int i, j, k, col_ptr=0; int rows=0, num_ss=0, num_vars=0, status=0; size_t rows_t=0, num_nod_var_t=0, start2[2],count2[2]; // // Check to see if we have to create a scaling index vector // bool createSSIdx = false; std::vector< std::pair<int,int> > scaling_idx; std::pair<int, int> idx_pair; /* try { scaling_idx = Teuchos::getParameter< std::vector< std::pair<int,int> > >( *params_, "Snapshot Scaling Indices" ); } catch (std::exception &e) { createSSIdx = true; } */ // // Open all the files and check that the snapshots have the same dimensions. // if ( comm.MyPID() == 0 ) { size_t rows0=0, cols0=0, cols_t=0, total_rows=0; std::string temp_filename = in_path + filenames[0]; status = nc_open(temp_filename.c_str(),NC_NOWRITE,&ncid); if (status != NC_NOERR) handle_error(status); // // If the scaling index vector is needed we can create it here. // if (createSSIdx) { idx_pair.first = total_rows; } // // Get information on the number of snapshots in the file. status = nc_inq_dimid(ncid,"row",&row_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,row_id, &rows0); if (status != NC_NOERR) handle_error(status); total_rows += rows0; // // Get information on the snapshot length. status = nc_inq_dimid(ncid,"col",&col_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,col_id, &cols0); if (status != NC_NOERR) handle_error(status); // if (!isInit) { int len_string_id, num_nodes_id, name_nod_var_id; size_t len_string_t, num_nodes_t; // Get maximum variable name length. status=nc_inq_dimid(ncid,"len_string",&len_string_id); if (status != NC_NOERR) handle_error(status); status=nc_inq_dimlen(ncid,len_string_id,&len_string_t); if (status != NC_NOERR) handle_error(status); // Get number of nodes. status=nc_inq_dimid(ncid,"num_nodes",&num_nodes_id); if (status != NC_NOERR) handle_error(status); status=nc_inq_dimlen(ncid,num_nodes_id, &num_nodes_t); if (status != NC_NOERR) handle_error(status); // Get number of nodal variables. status=nc_inq_dimid(ncid,"num_nod_var",&num_nod_var_id); if (status != NC_NOERR) handle_error(status); status=nc_inq_dimlen(ncid,num_nod_var_id,&num_nod_var_t); if (status != NC_NOERR) handle_error(status); len_string = len_string_t; num_nodes = num_nodes_t; num_nod_var = num_nod_var_t; // Read in names of nodal variables. status=nc_inq_varid(ncid,"name_nod_var",&name_nod_var_id); if (status != NC_NOERR) handle_error(status); var_name = new char*[ num_nod_var ]; for (i=0; i<num_nod_var; ++i) var_name[i] = new char[ len_string ]; for (i=0; i<num_nod_var; ++i) { start2[0]=i; start2[1]=0; count2[0]=1; count2[1]=len_string; status=nc_get_vara_text(ncid,name_nod_var_id,start2,count2,var_name[i]); if (status != NC_NOERR) handle_error(status); } // // If the scaling index vector is needed we can set the endpoint here. // if (createSSIdx) { idx_pair.second = total_rows-1; scaling_idx.push_back( idx_pair ); } // Now we are initialized! isInit = true; // Output information. std::cout<<"len_string = "<<len_string<<std::endl; std::cout<<"num_nodes = "<<num_nodes<<std::endl; std::cout<<"num_nod_var = "<<num_nod_var<<std::endl; std::cout<<"var_name = "; for (i=0; i< num_nod_var; ++i) std::cout<<var_name[i]<<" "; std::cout<<std::endl; } // Close first file. status = nc_close(ncid); if (status != NC_NOERR) handle_error(status); // for (i=1; i<(int)filenames.size(); i++) { std::string temp_filename = in_path + filenames[i]; status = nc_open(temp_filename.c_str(),NC_NOWRITE,&ncid); if (status != NC_NOERR) handle_error(status); // // If the scaling index vector is needed we can create it here. // if (createSSIdx) { idx_pair.first = total_rows; } // // Get information on the number of snapshots in the file. status = nc_inq_dimid(ncid,"row",&row_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,row_id, &rows_t); if (status != NC_NOERR) handle_error(status); // // Get information on the snapshot length. status = nc_inq_dimid(ncid,"col",&col_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,col_id, &cols_t); if (status != NC_NOERR) handle_error(status); // // Get number of nodal variables. status=nc_inq_dimid(ncid,"num_nod_var",&num_nod_var_id); if (status != NC_NOERR) handle_error(status); status=nc_inq_dimlen(ncid,num_nod_var_id,&num_nod_var_t); if (status != NC_NOERR) handle_error(status); // // TEUCHOS_TEST_FOR_EXCEPTION(cols_t != cols0 || (int)num_nod_var_t != num_nod_var, std::runtime_error, "Data set in file "+temp_filename+" is of inconsistent size!"); total_rows += rows_t; // // If the scaling index vector is needed we can set the endpoint here. // if (createSSIdx) { idx_pair.second = total_rows-1; scaling_idx.push_back( idx_pair ); } // Close the file. status = nc_close(ncid); if (status != NC_NOERR) handle_error(status); } // Convert from size_t to int. num_ss = total_rows; num_vars = cols0; std::cout<<"Number of snapshots: "<< num_ss << std::endl; std::cout<<"Length of snapshot : "<< num_vars << std::endl; } // Broadcast information about size of snapshot matrix. comm.Broadcast( &num_ss, 1, 0 ); comm.Broadcast( &num_vars, 1, 0 ); // // Sync all other processors on the scaling index vector if necessary // if (createSSIdx) { for (i=0; i<(int)filenames.size(); i++) { if ( comm.MyPID() != 0 ) scaling_idx.push_back( idx_pair ); comm.Broadcast( &scaling_idx[i].first, 1, 0 ); comm.Broadcast( &scaling_idx[i].second, 1, 0 ); } // Set the scaling index vector //params_->set("Snapshot Scaling Indices", scaling_idx); } // // Create maps for new Epetra_MultiVector to hold the snapshots and // temporary Epetra_Vector used by processor 0 to import the information. // Epetra_Map Map( num_vars, 0, comm ); Teuchos::RCP<Epetra_MultiVector> newMV = Teuchos::rcp( new Epetra_MultiVector( Map, num_ss ) ); Epetra_Vector *col_newMV = 0; Epetra_Map *Proc0Map = 0; int *index = 0; float *temp_vec_f = 0; double *temp_vec_d = 0; // if ( comm.MyPID() == 0 ) { Proc0Map = new Epetra_Map( num_vars, num_vars, 0, comm ); temp_vec_f = new float [ num_vars ]; temp_vec_d = new double [ num_vars ]; index = new int[ num_vars ]; for ( i=0; i<num_vars; i++ ) { index[i] = i; } } else { Proc0Map = new Epetra_Map( num_vars, 0, 0, comm ); } // // Create an importer to get this information into the global Epetra_MultiVector // Epetra_Import importer( Map, *Proc0Map ); // // Processor 0 reads each file and then creates a local Epetra_Vector, which will be // imported into the i-th column of the Epetra_MultiVector. // // Read starting with row "start2[0]" for "count2[0]" rows, as the columns vary from // "start2[1]" to "count2[1]", i.e. specifically for this case, read starting with row i // for 1 row, as the columns vary from first column to the last column // start2[1]=0; count2[0]=1; count2[1]=num_vars; col_ptr = 0; // for (i=0; i<(int)filenames.size(); i++) { if ( comm.MyPID() == 0 ) { // Open the next snapshot file; std::string temp_filename = in_path + filenames[i]; status = nc_open(temp_filename.c_str(),NC_NOWRITE,&ncid); if (status != NC_NOERR) handle_error(status); // // Get information on the number of snapshots in the file. status = nc_inq_dimid(ncid,"row",&row_id); if (status != NC_NOERR) handle_error(status); status = nc_inq_dimlen(ncid,row_id, &rows_t); if (status != NC_NOERR) handle_error(status); // Get the pointer for the snapshot matrix status = nc_inq_varid(ncid,"snapshot",&ss_id); if (status != NC_NOERR) handle_error(status); // // Convert from size_t to int. rows = rows_t; } comm.Broadcast( &rows, 1, 0 ); for (j=0; j<rows; j++) { // // Get column of Epetra_MultiVector in terms of Epetra_Vector. // col_newMV = (*newMV)( col_ptr ); // // Let Processor 0 fill in the Epetra_Vector. // if ( comm.MyPID() == 0 ) { // // Read in next snapshot, set pointer to next row containing snapshot in NetCDF file. // start2[0]=j; status=nc_get_vara_float(ncid,ss_id,start2,count2,temp_vec_f); for (k=0; k<num_vars; k++) { temp_vec_d[k] = temp_vec_f[k]; } } // // Create the Proc0Vector with values from temp_vec_d // Epetra_Vector Proc0Vector( View, *Proc0Map, temp_vec_d ); // // Import the information. // col_newMV->Import(Proc0Vector, importer, Add); // // Increment the counter. // col_ptr++; } // // Close this snapshot file. if ( comm.MyPID() == 0 ) { status = nc_close(ncid); if (status != NC_NOERR) handle_error(status); } } // // Clean up delete Proc0Map; if ( index ) delete [] index; if ( temp_vec_f ) delete [] temp_vec_f; if ( temp_vec_d ) delete [] temp_vec_d; // Return. return newMV; }
int Drumm2(const Epetra_Map& map, bool verbose) { //Simple 2-element problem (element as in "finite-element") from //Clif Drumm. Two triangular elements, one per processor, as shown //here: // // *----* // 3|\ 2| // | \ | // | 0\1| // | \| // *----* // 0 1 // //Element 0 on processor 0, element 1 on processor 1. //Processor 0 will own nodes 0,1,3 and processor 1 will own node 2. //Each processor will pass a 3x3 element-matrix to Epetra_FECrsMatrix. //After GlobalAssemble(), the matrix should be as follows: // // row 0: 2 1 0 1 //proc 0 row 1: 1 4 1 2 // row 2: 0 1 2 1 //---------------------------------- //proc 1 row 3: 1 2 1 4 // int numProcs = map.Comm().NumProc(); int localProc = map.Comm().MyPID(); if (numProcs != 2) return(0); int indexBase = 0, ierr = 0; double* values = new double[9]; values[0] = 2.0; values[1] = 1.0; values[2] = 1.0; values[3] = 1.0; values[4] = 2.0; values[5] = 1.0; values[6] = 1.0; values[7] = 1.0; values[8] = 2.0; if (localProc == 0) { int numMyNodes = 3; int* myNodes = new int[numMyNodes]; myNodes[0] = 0; myNodes[1] = 1; myNodes[2] = 3; Epetra_Map Map(-1, numMyNodes, myNodes, indexBase, map.Comm()); int rowLengths = 3; Epetra_FECrsMatrix A(Copy, Map, rowLengths); EPETRA_TEST_ERR( A.InsertGlobalValues(numMyNodes, myNodes, numMyNodes, myNodes, values, Epetra_FECrsMatrix::ROW_MAJOR),ierr); EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); if (verbose) { A.Print(cout); } //now let's make sure we can do a matvec with this matrix. Epetra_Vector x(Map), y(Map); x.PutScalar(1.0); EPETRA_TEST_ERR( A.Multiply(false, x, y), ierr); if (verbose&&localProc==0) { cout << "y = A*x, x=1.0's"<<endl; } if (verbose) { y.Print(cout); } delete [] myNodes; delete [] values; } else { int numMyNodes = 1; int* myNodes = new int[numMyNodes]; myNodes[0] = 2; Epetra_Map Map(-1, numMyNodes, myNodes, indexBase, map.Comm()); int rowLengths = 3; Epetra_FECrsMatrix A(Copy, Map, rowLengths); delete [] myNodes; numMyNodes = 3; myNodes = new int[numMyNodes]; myNodes[0] = 1; myNodes[1] = 2; myNodes[2] = 3; EPETRA_TEST_ERR( A.InsertGlobalValues(numMyNodes, myNodes, numMyNodes, myNodes, values, Epetra_FECrsMatrix::ROW_MAJOR),ierr); EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); EPETRA_TEST_ERR( A.GlobalAssemble(), ierr ); if (verbose) { A.Print(cout); } //now let's make sure we can do a matvec with this matrix. Epetra_Vector x(Map), y(Map); x.PutScalar(1.0); EPETRA_TEST_ERR( A.Multiply(false, x, y), ierr); if (verbose) { y.Print(cout); } delete [] myNodes; delete [] values; } return(0); }
int Drumm3(const Epetra_Map& map, bool verbose) { const Epetra_Comm & Comm = map.Comm(); /* get number of processors and the name of this processor */ int Numprocs = Comm.NumProc(); int MyPID = Comm.MyPID(); if (Numprocs != 2) return(0); int NumGlobalRows = 4; int IndexBase = 0; Epetra_Map Map(NumGlobalRows, IndexBase, Comm); // Construct FECrsMatrix int NumEntriesPerRow = 3; Epetra_FECrsMatrix A(Copy, Map, NumEntriesPerRow); double ElementArea = 0.5; int NumCols = 3; int* Indices = new int[NumCols]; if(MyPID==0) // indices corresponding to element 0 on processor 0 { Indices[0] = 0; Indices[1] = 1; Indices[2] = 3; } else if(MyPID==1) // indices corresponding to element 1 on processor 1 { Indices[0] = 1; Indices[1] = 2; Indices[2] = 3; } double* Values = new double[NumCols*NumCols]; // removal term Values[0] = 2*ElementArea/12.; Values[1] = 1*ElementArea/12.; Values[2] = 1*ElementArea/12.; Values[3] = 1*ElementArea/12.; Values[4] = 2*ElementArea/12.; Values[5] = 1*ElementArea/12.; Values[6] = 1*ElementArea/12.; Values[7] = 1*ElementArea/12.; Values[8] = 2*ElementArea/12.; A.InsertGlobalValues(NumCols, Indices, Values, Epetra_FECrsMatrix::ROW_MAJOR); A.GlobalAssemble(); A.GlobalAssemble(); // A.Print(cout); // Create vectors for CG algorithm Epetra_FEVector* bptr = new Epetra_FEVector(A.RowMap(), 1); Epetra_FEVector* x0ptr = new Epetra_FEVector(A.RowMap(), 1); Epetra_FEVector& b = *bptr; Epetra_FEVector& x0 = *x0ptr; // source terms NumCols = 2; if(MyPID==0) // indices corresponding to element 0 on processor 0 { Indices[0] = 0; Indices[1] = 3; Values[0] = 1./2.; Values[1] = 1./2.; } else { Indices[0] = 1; Indices[1] = 2; Values[0] = 0; Values[1] = 0; } b.SumIntoGlobalValues(NumCols, Indices, Values); b.GlobalAssemble(); if (verbose&&MyPID==0) cout << "b:" << endl; if (verbose) { b.Print(cout); } x0 = b; if (verbose&&MyPID==0) { cout << "x:"<<endl; } if (verbose) { x0.Print(cout); } delete [] Values; delete [] Indices; delete bptr; delete x0ptr; return(0); }
MultiVec<double>* EpetraMultiVec::Clone ( const int numvecs ) const { EpetraMultiVec * ptr_apv = new EpetraMultiVec(Map(), numvecs); return ptr_apv; // safe upcast. }
//========================================================================= void Epetra_MapColoring::Print(std::ostream& os) const { int MyPID = Map().Comm().MyPID(); int NumProc = Map().Comm().NumProc(); if (MyPID==0) os << std::endl << " *****************************************" << std::endl << " Coloring information arranged map element" << std::endl << " *****************************************" << std::endl << std::endl; for (int iproc=0; iproc < NumProc; iproc++) { if (MyPID==iproc) { int NumMyElements1 =Map(). NumMyElements(); if (MyPID==0) { os.width(8); os << " MyPID"; os << " "; os.width(12); os << "GID "; os.width(20); os << "Color "; os << std::endl; } for (int i=0; i < NumMyElements1; i++) { os.width(10); os << MyPID; os << " "; os.width(10); if(Map().GlobalIndicesInt()) { #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES int * MyGlobalElements1 = Map().MyGlobalElements(); os << MyGlobalElements1[i] << " "; #else throw ReportError("Epetra_MapColoring::Print: ERROR, GlobalIndicesInt but no API for it.",-1); #endif } else if(Map().GlobalIndicesLongLong()) { #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES long long * MyGlobalElements1 = Map().MyGlobalElements64(); os << MyGlobalElements1[i] << " "; #else throw ReportError("Epetra_MapColoring::Print: ERROR, GlobalIndicesLongLong but no API for it.",-1); #endif } else throw ReportError("Epetra_MapColoring::Print: ERROR, Don't know map global index type.",-1); os.width(20); os << ElementColors_[i]; os << std::endl; } os << std::flush; } // Do a few global ops to give I/O a chance to complete Map().Comm().Barrier(); Map().Comm().Barrier(); Map().Comm().Barrier(); } if (MyPID==0) os << std::endl << " **************************************" << std::endl << " Coloring information arranged by color" << std::endl << " **************************************" << std::endl << std::endl; {for (int iproc=0; iproc < NumProc; iproc++) { if (MyPID==iproc) { if (NumColors()==0) os << " No colored elements on processor " << MyPID << std::endl; else { os << "Number of colors in map = " << NumColors() << std::endl << "Default color = " << DefaultColor() << std::endl << std::endl; if (MyPID==0) { os.width(8); os << " MyPID"; os << " "; os.width(12); os << "LID "; os.width(20); os << "Color "; os << std::endl; } int * ColorValues = ListOfColors(); for (int ii=0; ii<NumColors(); ii++) { int CV = ColorValues[ii]; int ColorCount = NumElementsWithColor(CV); int * LIDList = ColorLIDList(CV); for (int i=0; i < ColorCount; i++) { os.width(10); os << MyPID; os << " "; os.width(10); os << LIDList[i] << " "; os.width(20); os << CV; os << std::endl; } os << std::flush; } } } // Do a few global ops to give I/O a chance to complete Map().Comm().Barrier(); Map().Comm().Barrier(); Map().Comm().Barrier(); }} return; }
//========================================================================= Epetra_MapColoring::~Epetra_MapColoring(){ if (Allocated_ && Map().NumMyElements()>0) delete [] ElementColors_; if (ListsAreGenerated_) DeleteLists(); }
void DataDrawer::AddFormat(const char *id, Factory factory) { INTERLOCKED_(sDataDrawer) Map().Add(id, (void *)factory); }
void NetCDFFileIOHandler::Write( const Teuchos::RCP<const Epetra_MultiVector>& MV, const std::string& filename ) { #ifdef EPETRA_MPI Epetra_MpiComm comm( MPI_COMM_WORLD ); #else Epetra_SerialComm comm; #endif // // Variables for NetCDF // int status; int ncid, len_string_id, num_nodes_id, num_nod_var_id, row_id, col_id, ss_id, name_nod_var_id; int i,j; int ss_dimids[2]; //size_t start[1],count[1]; size_t start2[2],count2[2]; // // Variables for Epetra // int num_vecs = MV->NumVectors(); int dim = MV->GlobalLength(); Epetra_Map Map( dim, 0, comm ); Epetra_Map* Proc0Map; const Epetra_Vector* col_newMV; // // Create map putting all elements of vector on Processor 0. // if ( comm.MyPID() == 0 ) { Proc0Map = new Epetra_Map( dim, dim, 0, comm ); } else { Proc0Map = new Epetra_Map( dim, 0, 0, comm ); } Epetra_Vector Proc0Vector( *Proc0Map ); // // Create an exporter to get the global Epetra_Vector to a local Epetra_Vector. // Epetra_Export exporter( MV->Map(), *Proc0Map ); // if ( comm.MyPID() == 0 ) { // // Open basis output file and define output variables going into the file. // std::string temp_filename = out_path + filename; status=nc_create(temp_filename.c_str(),NC_CLOBBER,&ncid); if (status != NC_NOERR) handle_error(status); status=nc_def_dim(ncid,"len_string",(long)len_string,&len_string_id); if (status != NC_NOERR) handle_error(status); status=nc_def_dim(ncid,"num_nodes",(long)num_nodes,&num_nodes_id); if (status != NC_NOERR) handle_error(status); status=nc_def_dim(ncid,"num_nod_var",(long)num_nod_var,&num_nod_var_id); if (status != NC_NOERR) handle_error(status); status=nc_def_dim(ncid,"row",NC_UNLIMITED,&row_id); if (status != NC_NOERR) handle_error(status); status=nc_def_dim(ncid,"col",(long)dim,&col_id); if (status != NC_NOERR) handle_error(status); ss_dimids[0]=row_id; ss_dimids[1]=col_id; status=nc_def_var(ncid,"snapshot",NC_FLOAT,2,ss_dimids,&ss_id); if (status != NC_NOERR) handle_error(status); ss_dimids[0]=num_nod_var_id; ss_dimids[1]=len_string_id; status=nc_def_var(ncid,"name_nod_var",NC_CHAR,2,ss_dimids,&name_nod_var_id); if (status != NC_NOERR) handle_error(status); status=nc_enddef(ncid); if (status != NC_NOERR) handle_error(status); } // Initialize data pointers for writing out basis to file. float* temp_vec = 0; if ( comm.MyPID() == 0 ) temp_vec = new float[ dim ]; for (i=0; i<num_vecs; ++i) { // // Get column of Epetra_MultiVector in terms of Epetra_Vector. // col_newMV = (*MV)( i ); // Proc0Vector.Export(*col_newMV, exporter, Insert); // if ( comm.MyPID()==0 ) { start2[0] = i; start2[1] = 0; count2[0] = 1; count2[1] = dim; // // Copy double precision vector to single precision and write out. // for (j=0; j<dim; ++j) temp_vec[j] = Proc0Vector[j]; status=nc_put_vara_float(ncid,ss_id,start2,count2,temp_vec); if (status != NC_NOERR) handle_error(status); } } // Write the list of names of the nodal variables to the Netcdf file */ if ( comm.MyPID() == 0 ) { for(i=0; i<num_nod_var; ++i) { start2[0] = i; start2[1] = 0; count2[0] = 1; count2[1] = strlen(var_name[i]); /* printf("start2=%d %d\n",start2[0],start2[1]); printf("count2=%d %d\n",count2[0],count2[1]); */ status=nc_put_vara_text(ncid,name_nod_var_id,start2,count2,var_name[i]); if (status != NC_NOERR) handle_error(status); } status=nc_close(ncid); if (status != NC_NOERR) handle_error(status); } // Clean up. delete Proc0Map; if (temp_vec) delete [] temp_vec; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc, &argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // set global dimension to 5, could be any number int NumGlobalElements = 5; // create a linear map Epetra_Map Map(NumGlobalElements,0,Comm); // local number of rows int NumMyElements = Map.NumMyElements(); // get update list int * MyGlobalElements = Map.MyGlobalElements( ); // dimension of each block Epetra_IntSerialDenseVector ElementSizeList(NumMyElements); // now construct a funky matrix. Diagonal block of block row i will have // dimension i+1 (don't run this code with too many nodes...). The // dimension of each block row is recordered in ElementSizeList. // Here ElementSizeList is declared as Epetra_IntSerialDenseVector, // but an int array is fine as well. // max_blk keeps trace of the max block dimension int max_blk = 0; for( int i=0 ; i<NumMyElements ; ++i ) { ElementSizeList[i] = 1+MyGlobalElements[i]; if( ElementSizeList[i] > max_blk ) max_blk = ElementSizeList[i]; } // create a block map based on the already declared point map // (used to determine NumMyElements and MyGlobalElements). // The same point map can be used for more block maps, // just change the input value of ElementSizeList Epetra_BlockMap BlockMap(NumGlobalElements,NumMyElements, MyGlobalElements, ElementSizeList.Values(),0,Comm); // create a VBR matrix based on BlockMap Epetra_VbrMatrix A(Copy, BlockMap,2); int MaxBlockSize = max_blk * max_blk*100; int Indices[2]; double* Values; Values = new double[MaxBlockSize]; // cycle over all the local rows. for( int i=0 ; i<NumMyElements ; ++i ) { // get GID of local row int GlobalNode = MyGlobalElements[i]; // all lines but the last one will have to nonzero block-elements Indices[0] = GlobalNode; int NumEntries = 1; if( GlobalNode != NumGlobalElements-1 ) { Indices[1] = GlobalNode+1; NumEntries++; } // with VBR matrices, we have to insert one block at time. // This required two more instructions, one to start this // process (BeginInsertGlobalValues), and another one to // commit the end of submissions (EndSubmitEntries). A.BeginInsertGlobalValues(GlobalNode, NumEntries, Indices); // insert diagonal int BlockRows = ElementSizeList[i]; for( int k=0 ; k<BlockRows * BlockRows ; ++k ) Values[k] = 1.0*i; A.SubmitBlockEntry(Values,BlockRows,BlockRows,BlockRows); // insert off diagonal if any if( GlobalNode != NumGlobalElements-1 ) { int BlockCols = BlockRows+1; for( int k=0 ; k<BlockRows * BlockCols ; ++k ) Values[k] = 1.0*i; A.SubmitBlockEntry(Values,BlockRows,BlockRows,BlockCols); } A.EndSubmitEntries(); } A.FillComplete(); cout << A; delete[] Values; #ifdef HAVE_MPI MPI_Finalize(); #endif return(0); }
int main(int argc, char *argv[]) { #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif bool testFailed; bool boolret; int MyPID = Comm.MyPID(); bool verbose = true; bool debug = false; bool insitu = false; std::string which("SM"); Teuchos::CommandLineProcessor cmdp(false,true); cmdp.setOption("verbose","quiet",&verbose,"Print messages and results."); cmdp.setOption("debug","nodebug",&debug,"Print debugging information."); cmdp.setOption("insitu","exsitu",&insitu,"Perform in situ restarting."); cmdp.setOption("sort",&which,"Targetted eigenvalues (SM,LM,SR,LR,SI,or LI)."); if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) { #ifdef HAVE_MPI MPI_Finalize(); #endif return -1; } typedef double ScalarType; typedef Teuchos::ScalarTraits<ScalarType> SCT; typedef SCT::magnitudeType MagnitudeType; typedef Epetra_MultiVector MV; typedef Epetra_Operator OP; typedef Anasazi::MultiVecTraits<ScalarType,MV> MVT; typedef Anasazi::OperatorTraits<ScalarType,MV,OP> OPT; // Dimension of the matrix int nx = 10; // Discretization points in any one direction. int NumGlobalElements = nx*nx; // Size of matrix nx*nx // Construct a Map that puts approximately the same number of // equations on each processor. Epetra_Map Map(NumGlobalElements, 0, Comm); // Get update list and number of local equations from newly created Map. int NumMyElements = Map.NumMyElements(); std::vector<int> MyGlobalElements(NumMyElements); Map.MyGlobalElements(&MyGlobalElements[0]); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation // on this processor std::vector<int> NumNz(NumMyElements); /* We are building a matrix of block structure: | T -I | |-I T -I | | -I T | | ... -I| | -I T| where each block is dimension nx by nx and the matrix is on the order of nx*nx. The block T is a tridiagonal matrix. */ for (int i=0; i<NumMyElements; i++) { if (MyGlobalElements[i] == 0 || MyGlobalElements[i] == NumGlobalElements-1 || MyGlobalElements[i] == nx-1 || MyGlobalElements[i] == nx*(nx-1) ) { NumNz[i] = 3; } else if (MyGlobalElements[i] < nx || MyGlobalElements[i] > nx*(nx-1) || MyGlobalElements[i]%nx == 0 || (MyGlobalElements[i]+1)%nx == 0) { NumNz[i] = 4; } else { NumNz[i] = 5; } } // Create an Epetra_Matrix Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Epetra_DataAccess::Copy, Map, &NumNz[0]) ); // Diffusion coefficient, can be set by user. // When rho*h/2 <= 1, the discrete convection-diffusion operator has real eigenvalues. // When rho*h/2 > 1, the operator has complex eigenvalues. double rho = 2*(nx+1); // Compute coefficients for discrete convection-diffution operator const double one = 1.0; std::vector<double> Values(4); std::vector<int> Indices(4); double h = one /(nx+1); double h2 = h*h; double c = 5.0e-01*rho/ h; Values[0] = -one/h2 - c; Values[1] = -one/h2 + c; Values[2] = -one/h2; Values[3]= -one/h2; double diag = 4.0 / h2; int NumEntries, info; for (int i=0; i<NumMyElements; i++) { if (MyGlobalElements[i]==0) { Indices[0] = 1; Indices[1] = nx; NumEntries = 2; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[1], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] == nx*(nx-1)) { Indices[0] = nx*(nx-1)+1; Indices[1] = nx*(nx-2); NumEntries = 2; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[1], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] == nx-1) { Indices[0] = nx-2; NumEntries = 1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); Indices[0] = 2*nx-1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[2], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] == NumGlobalElements-1) { Indices[0] = NumGlobalElements-2; NumEntries = 1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); Indices[0] = nx*(nx-1)-1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[2], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] < nx) { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; Indices[2] = MyGlobalElements[i]+nx; NumEntries = 3; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i] > nx*(nx-1)) { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; Indices[2] = MyGlobalElements[i]-nx; NumEntries = 3; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); } else if (MyGlobalElements[i]%nx == 0) { Indices[0] = MyGlobalElements[i]+1; Indices[1] = MyGlobalElements[i]-nx; Indices[2] = MyGlobalElements[i]+nx; NumEntries = 3; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[1], &Indices[0]); assert( info==0 ); } else if ((MyGlobalElements[i]+1)%nx == 0) { Indices[0] = MyGlobalElements[i]-nx; Indices[1] = MyGlobalElements[i]+nx; NumEntries = 2; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[2], &Indices[0]); assert( info==0 ); Indices[0] = MyGlobalElements[i]-1; NumEntries = 1; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; Indices[2] = MyGlobalElements[i]-nx; Indices[3] = MyGlobalElements[i]+nx; NumEntries = 4; info = A->InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]); assert( info==0 ); } // Put in the diagonal entry info = A->InsertGlobalValues(MyGlobalElements[i], 1, &diag, &MyGlobalElements[i]); assert( info==0 ); } // Finish up info = A->FillComplete(); assert( info==0 ); A->SetTracebackMode(1); // Shutdown Epetra Warning tracebacks //************************************ // Start the block Arnoldi iteration //*********************************** // // Variables used for the Block Krylov Schur Method // int nev = 4; int blockSize = 1; int numBlocks = 20; int maxRestarts = 500; //int stepSize = 5; double tol = 1e-8; // Create a sort manager to pass into the block Krylov-Schur solver manager // --> Make sure the reference-counted pointer is of type Anasazi::SortManager<> // --> The block Krylov-Schur solver manager uses Anasazi::BasicSort<> by default, // so you can also pass in the parameter "Which", instead of a sort manager. Teuchos::RCP<Anasazi::SortManager<MagnitudeType> > MySort = Teuchos::rcp( new Anasazi::BasicSort<MagnitudeType>( which ) ); // Set verbosity level int verbosity = Anasazi::Errors + Anasazi::Warnings; if (verbose) { verbosity += Anasazi::FinalSummary + Anasazi::TimingDetails; } if (debug) { verbosity += Anasazi::Debug; } // // Create parameter list to pass into solver manager // Teuchos::ParameterList MyPL; MyPL.set( "Verbosity", verbosity ); MyPL.set( "Sort Manager", MySort ); //MyPL.set( "Which", which ); MyPL.set( "Block Size", blockSize ); MyPL.set( "Num Blocks", numBlocks ); MyPL.set( "Maximum Restarts", maxRestarts ); //MyPL.set( "Step Size", stepSize ); MyPL.set( "Convergence Tolerance", tol ); MyPL.set( "In Situ Restarting", insitu ); // Create an Epetra_MultiVector for an initial vector to start the solver. // Note: This needs to have the same number of columns as the blocksize. Teuchos::RCP<Epetra_MultiVector> ivec = Teuchos::rcp( new Epetra_MultiVector(Map, blockSize) ); ivec->Random(); // Create the eigenproblem. Teuchos::RCP<Anasazi::BasicEigenproblem<double, MV, OP> > MyProblem = Teuchos::rcp( new Anasazi::BasicEigenproblem<double, MV, OP>(A, ivec) ); // Inform the eigenproblem that the operator A is non-Hermitian MyProblem->setHermitian(false); // Set the number of eigenvalues requested MyProblem->setNEV( nev ); // Inform the eigenproblem that you are finishing passing it information boolret = MyProblem->setProblem(); if (boolret != true) { if (verbose && MyPID == 0) { std::cout << "Anasazi::BasicEigenproblem::setProblem() returned with error." << std::endl; } #ifdef HAVE_MPI MPI_Finalize() ; #endif return -1; } // Initialize the Block Arnoldi solver Anasazi::BlockKrylovSchurSolMgr<double, MV, OP> MySolverMgr(MyProblem, MyPL); // Solve the problem to the specified tolerances or length Anasazi::ReturnType returnCode = MySolverMgr.solve(); testFailed = false; if (returnCode != Anasazi::Converged && MyPID==0 && verbose) { testFailed = true; } // Get the Ritz values from the eigensolver std::vector<Anasazi::Value<double> > ritzValues = MySolverMgr.getRitzValues(); // Output computed eigenvalues and their direct residuals if (verbose && MyPID==0) { int numritz = (int)ritzValues.size(); std::cout.setf(std::ios_base::right, std::ios_base::adjustfield); std::cout<<std::endl<< "Computed Ritz Values"<< std::endl; std::cout<< std::setw(16) << "Real Part" << std::setw(16) << "Imag Part" << std::endl; std::cout<<"-----------------------------------------------------------"<<std::endl; for (int i=0; i<numritz; i++) { std::cout<< std::setw(16) << ritzValues[i].realpart << std::setw(16) << ritzValues[i].imagpart << std::endl; } std::cout<<"-----------------------------------------------------------"<<std::endl; } // Get the eigenvalues and eigenvectors from the eigenproblem Anasazi::Eigensolution<ScalarType,MV> sol = MyProblem->getSolution(); std::vector<Anasazi::Value<ScalarType> > evals = sol.Evals; Teuchos::RCP<MV> evecs = sol.Evecs; std::vector<int> index = sol.index; int numev = sol.numVecs; if (numev > 0) { // Compute residuals. Teuchos::LAPACK<int,double> lapack; std::vector<double> normA(numev); // The problem is non-Hermitian. int i=0; std::vector<int> curind(1); std::vector<double> resnorm(1), tempnrm(1); Teuchos::RCP<MV> tempAevec; Teuchos::RCP<const MV> evecr, eveci; Epetra_MultiVector Aevec(Map,numev); // Compute A*evecs OPT::Apply( *A, *evecs, Aevec ); Teuchos::SerialDenseMatrix<int,double> Breal(1,1), Bimag(1,1); while (i<numev) { if (index[i]==0) { // Get a view of the current eigenvector (evecr) curind[0] = i; evecr = MVT::CloneView( *evecs, curind ); // Get a copy of A*evecr tempAevec = MVT::CloneCopy( Aevec, curind ); // Compute A*evecr - lambda*evecr Breal(0,0) = evals[i].realpart; MVT::MvTimesMatAddMv( -1.0, *evecr, Breal, 1.0, *tempAevec ); // Compute the norm of the residual and increment counter MVT::MvNorm( *tempAevec, resnorm ); normA[i] = resnorm[0] / Teuchos::ScalarTraits<MagnitudeType>::magnitude( evals[i].realpart ); i++; } else { // Get a view of the real part of the eigenvector (evecr) curind[0] = i; evecr = MVT::CloneView( *evecs, curind ); // Get a copy of A*evecr tempAevec = MVT::CloneCopy( Aevec, curind ); // Get a view of the imaginary part of the eigenvector (eveci) curind[0] = i+1; eveci = MVT::CloneView( *evecs, curind ); // Set the eigenvalue into Breal and Bimag Breal(0,0) = evals[i].realpart; Bimag(0,0) = evals[i].imagpart; // Compute A*evecr - evecr*lambdar + eveci*lambdai MVT::MvTimesMatAddMv( -1.0, *evecr, Breal, 1.0, *tempAevec ); MVT::MvTimesMatAddMv( 1.0, *eveci, Bimag, 1.0, *tempAevec ); MVT::MvNorm( *tempAevec, tempnrm ); // Get a copy of A*eveci tempAevec = MVT::CloneCopy( Aevec, curind ); // Compute A*eveci - eveci*lambdar - evecr*lambdai MVT::MvTimesMatAddMv( -1.0, *evecr, Bimag, 1.0, *tempAevec ); MVT::MvTimesMatAddMv( -1.0, *eveci, Breal, 1.0, *tempAevec ); MVT::MvNorm( *tempAevec, resnorm ); // Compute the norms and scale by magnitude of eigenvalue normA[i] = lapack.LAPY2( tempnrm[0], resnorm[0] ) / lapack.LAPY2( evals[i].realpart, evals[i].imagpart ); normA[i+1] = normA[i]; i=i+2; } } // Output computed eigenvalues and their direct residuals if (verbose && MyPID==0) { std::cout.setf(std::ios_base::right, std::ios_base::adjustfield); std::cout<<std::endl<< "Actual Residuals"<<std::endl; std::cout<< std::setw(16) << "Real Part" << std::setw(16) << "Imag Part" << std::setw(20) << "Direct Residual"<< std::endl; std::cout<<"-----------------------------------------------------------"<<std::endl; for (int j=0; j<numev; j++) { std::cout<< std::setw(16) << evals[j].realpart << std::setw(16) << evals[j].imagpart << std::setw(20) << normA[j] << std::endl; if ( normA[j] > tol ) { testFailed = true; } } std::cout<<"-----------------------------------------------------------"<<std::endl; } } #ifdef EPETRA_MPI MPI_Finalize(); #endif if (testFailed) { if (verbose && MyPID==0) { std::cout << "End Result: TEST FAILED" << std::endl; } return -1; } // // Default return value // if (verbose && MyPID==0) { std::cout << "End Result: TEST PASSED" << std::endl; } return 0; }
int main(int argc, char *argv[]) { int ierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // Comm.SetTracebackMode(0); // This should shut down any error tracing bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; #ifdef EPETRA_MPI int localverbose = verbose ? 1 : 0; int globalverbose=0; MPI_Allreduce(&localverbose, &globalverbose, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); verbose = (globalverbose>0); #endif int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if (verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << Comm <<endl; // Redefine verbose to only print on PE 0 //if (verbose && rank!=0) verbose = false; int NumMyElements = 4; int NumGlobalElements = NumMyElements*NumProc; int IndexBase = 0; Epetra_Map Map(NumGlobalElements, NumMyElements, IndexBase, Comm); EPETRA_TEST_ERR( Drumm1(Map, verbose),ierr); EPETRA_TEST_ERR( Drumm2(Map, verbose),ierr); EPETRA_TEST_ERR( Drumm3(Map, verbose),ierr); bool preconstruct_graph = false; EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr); preconstruct_graph = true; EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr); EPETRA_TEST_ERR( submatrix_formats(Comm, verbose), ierr); EPETRA_TEST_ERR( rectangular(Comm, verbose), ierr); #ifdef EPETRA_MPI MPI_Finalize(); #endif return ierr; }
//========================================================================= int Epetra_IntVector::CopyAndPermute(const Epetra_SrcDistObject& Source, int NumSameIDs, int NumPermuteIDs, int * PermuteToLIDs, int *PermuteFromLIDs, const Epetra_OffsetIndex * Indexor, Epetra_CombineMode CombineMode) { (void)Indexor; const Epetra_IntVector & A = dynamic_cast<const Epetra_IntVector &>(Source); if( CombineMode != Add && CombineMode != Zero && CombineMode != Insert && CombineMode != Average && CombineMode != AbsMax ) EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero int * From; A.ExtractView(&From); int *To = Values_; int * ToFirstPointInElementList = 0; int * FromFirstPointInElementList = 0; int * FromElementSizeList = 0; int MaxElementSize = Map().MaxElementSize(); bool ConstantElementSize = Map().ConstantElementSize(); if (!ConstantElementSize) { ToFirstPointInElementList = Map().FirstPointInElementList(); FromFirstPointInElementList = A.Map().FirstPointInElementList(); FromElementSizeList = A.Map().ElementSizeList(); } int j, jj, jjj, k; int NumSameEntries; bool Case1 = false; bool Case2 = false; // bool Case3 = false; if (MaxElementSize==1) { Case1 = true; NumSameEntries = NumSameIDs; } else if (ConstantElementSize) { Case2 = true; NumSameEntries = NumSameIDs * MaxElementSize; } else { // Case3 = true; NumSameEntries = FromFirstPointInElementList[NumSameIDs]; } // Short circuit for the case where the source and target vector is the same. if (To==From) NumSameEntries = 0; // Do copy first if (NumSameIDs>0) if (To!=From) { if (CombineMode==Add) for (j=0; j<NumSameEntries; j++) To[j] += From[j]; // Add to existing value else if(CombineMode==Insert) for (j=0; j<NumSameEntries; j++) To[j] = From[j]; else if(CombineMode==AbsMax) for (j=0; j<NumSameEntries; j++) { To[j] = EPETRA_MAX( To[j],From[j]); } // Note: The following form of averaging is not a true average if more that one value is combined. // This might be an issue in the future, but we leave this way for now. else if(CombineMode==Average) for (j=0; j<NumSameEntries; j++) {To[j] += From[j]; To[j] /= 2;} } // Do local permutation next if (NumPermuteIDs>0) { // Point entry case if (Case1) { if (CombineMode==Add) for (j=0; j<NumPermuteIDs; j++) To[PermuteToLIDs[j]] += From[PermuteFromLIDs[j]]; // Add to existing value else if(CombineMode==Insert) for (j=0; j<NumPermuteIDs; j++) To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]]; else if(CombineMode==AbsMax) for (j=0; j<NumPermuteIDs; j++) { To[PermuteToLIDs[j]] = EPETRA_MAX( To[PermuteToLIDs[j]],From[PermuteFromLIDs[j]]); } // Note: The following form of averaging is not a true average if more that one value is combined. // This might be an issue in the future, but we leave this way for now. else if(CombineMode==Average) for (j=0; j<NumPermuteIDs; j++) {To[PermuteToLIDs[j]] += From[PermuteFromLIDs[j]]; To[PermuteToLIDs[j]] /= 2;} } // constant element size case else if (Case2) { if (CombineMode==Add) for (j=0; j<NumPermuteIDs; j++) { jj = MaxElementSize*PermuteToLIDs[j]; jjj = MaxElementSize*PermuteFromLIDs[j]; for (k=0; k<MaxElementSize; k++) To[jj+k] += From[jjj+k]; } else if(CombineMode==Insert) for (j=0; j<NumPermuteIDs; j++) { jj = MaxElementSize*PermuteToLIDs[j]; jjj = MaxElementSize*PermuteFromLIDs[j]; for (k=0; k<MaxElementSize; k++) To[jj+k] = From[jjj+k]; } else if(CombineMode==AbsMax) for (j=0; j<NumPermuteIDs; j++) { jj = MaxElementSize*PermuteToLIDs[j]; jjj = MaxElementSize*PermuteFromLIDs[j]; for (k=0; k<MaxElementSize; k++) To[jj+k] = EPETRA_MAX( To[jj+k],From[jjj+k]); } // Note: The following form of averaging is not a true average if more that one value is combined. // This might be an issue in the future, but we leave this way for now. else if(CombineMode==Average) for (j=0; j<NumPermuteIDs; j++) { jj = MaxElementSize*PermuteToLIDs[j]; jjj = MaxElementSize*PermuteFromLIDs[j]; for (k=0; k<MaxElementSize; k++) {To[jj+k] += From[jjj+k]; To[jj+k] /= 2;} } } // variable element size case else { if (CombineMode==Add) for (j=0; j<NumPermuteIDs; j++) { jj = ToFirstPointInElementList[PermuteToLIDs[j]]; jjj = FromFirstPointInElementList[PermuteFromLIDs[j]]; int ElementSize = FromElementSizeList[PermuteFromLIDs[j]]; for (k=0; k<ElementSize; k++) To[jj+k] += From[jjj+k]; } else if(CombineMode==Insert) for (j=0; j<NumPermuteIDs; j++) { jj = ToFirstPointInElementList[PermuteToLIDs[j]]; jjj = FromFirstPointInElementList[PermuteFromLIDs[j]]; int ElementSize = FromElementSizeList[PermuteFromLIDs[j]]; for (k=0; k<ElementSize; k++) To[jj+k] = From[jjj+k]; } else if(CombineMode==AbsMax) for (j=0; j<NumPermuteIDs; j++) { jj = ToFirstPointInElementList[PermuteToLIDs[j]]; jjj = FromFirstPointInElementList[PermuteFromLIDs[j]]; int ElementSize = FromElementSizeList[PermuteFromLIDs[j]]; for (k=0; k<ElementSize; k++) To[jj+k] = EPETRA_MAX( To[jj+k],From[jjj+k]); } else if(CombineMode==Average) for (j=0; j<NumPermuteIDs; j++) { jj = ToFirstPointInElementList[PermuteToLIDs[j]]; jjj = FromFirstPointInElementList[PermuteFromLIDs[j]]; int ElementSize = FromElementSizeList[PermuteFromLIDs[j]]; for (k=0; k<ElementSize; k++) {To[jj+k] += From[jjj+k]; To[jj+k] /= 2;} } } } return(0); }
//========================================================================= // Print method void EpetraExt_BlockDiagMatrix::Print(std::ostream & os) const{ int MyPID = DataMap_->Comm().MyPID(); int NumProc = DataMap_->Comm().NumProc(); for (int iproc=0; iproc < NumProc; iproc++) { if (MyPID==iproc) { int NumMyElements1 =DataMap_->NumMyElements(); int MaxElementSize1 = DataMap_->MaxElementSize(); int * MyGlobalElements1_int = 0; long long * MyGlobalElements1_LL = 0; #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES if(DataMap_->GlobalIndicesInt()) { MyGlobalElements1_int = DataMap_->MyGlobalElements(); } else #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES if(DataMap_->GlobalIndicesLongLong()) { MyGlobalElements1_LL = DataMap_->MyGlobalElements64(); } else #endif throw "EpetraExt_BlockDiagMatrix::Print: GlobalIndices type unknown"; int * FirstPointInElementList1; if (MaxElementSize1!=1) FirstPointInElementList1 = DataMap_->FirstPointInElementList(); if (MyPID==0) { os.width(8); os << " MyPID"; os << " "; os.width(12); if (MaxElementSize1==1) os << "GID "; else os << " GID/Point"; os.width(20); os << "Values "; os << std::endl; } for (int i=0; i < NumMyElements1; i++) { for (int ii=0; ii< DataMap_->ElementSize(i); ii++) { int iii; os.width(10); os << MyPID; os << " "; os.width(10); if (MaxElementSize1==1) { os << (MyGlobalElements1_int ? MyGlobalElements1_int[i] : MyGlobalElements1_LL[i]) << " "; iii = i; } else { os << (MyGlobalElements1_int ? MyGlobalElements1_int[i] : MyGlobalElements1_LL[i]) << "/" << ii << " "; iii = FirstPointInElementList1[i]+ii; } os.width(20); os << Values_[iii]; os << std::endl; } } os << std::flush; } // Do a few global ops to give I/O a chance to complete Map().Comm().Barrier(); Map().Comm().Barrier(); Map().Comm().Barrier(); } return; }
int main(int argc, char *argv[]) { int ierr = 0, i, forierr = 0; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; Epetra_SerialComm Comm; #endif bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) cout << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 10000; long long NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0LL, Comm); // Get update list and number of local equations from newly created Map vector<long long> MyGlobalElements(Map.NumMyElements()); Map.MyGlobalElements(&MyGlobalElements[0]); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor vector<int> NumNz(NumMyEquations); // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for(i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy, Map, &NumNz[0]); EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 vector<double> Values(2); Values[0] = -1.0; Values[1] = -1.0; vector<long long> Indices(2); double two = 2.0; int NumEntries; forierr = 0; for(i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0])==0); forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i])>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); // Finish up A.FillComplete(); A.OptimizeStorage(); Epetra_JadMatrix JadA(A); Epetra_JadMatrix JadA1(A); Epetra_JadMatrix JadA2(A); // Create vectors for Power method Epetra_Vector q(Map); Epetra_Vector z(Map); z.Random(); Epetra_Vector resid(Map); Epetra_Flops flopcounter; A.SetFlopCounter(flopcounter); q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); JadA.SetFlopCounter(A); JadA1.SetFlopCounter(A); JadA2.SetFlopCounter(A); if (verbose) cout << "=======================================" << endl << "Testing Jad using CrsMatrix as input..." << endl << "=======================================" << endl; A.ResetFlops(); powerMethodTests(A, JadA, Map, q, z, resid, verbose); // Increase diagonal dominance if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n" << endl; if (A.MyGlobalRow(0)) { int numvals = A.NumGlobalEntries(0); vector<double> Rowvals(numvals); vector<long long> Rowinds(numvals); A.ExtractGlobalRowCopy(0, numvals, numvals, &Rowvals[0], &Rowinds[0]); // Get A[0,0] for (i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0; A.ReplaceGlobalValues(0, numvals, &Rowvals[0], &Rowinds[0]); } JadA.UpdateValues(A); A.ResetFlops(); powerMethodTests(A, JadA, Map, q, z, resid, verbose); if (verbose) cout << "================================================================" << endl << "Testing Jad using Jad matrix as input matrix for construction..." << endl << "================================================================" << endl; JadA1.ResetFlops(); powerMethodTests(JadA1, JadA2, Map, q, z, resid, verbose); #ifdef EPETRA_MPI MPI_Finalize() ; #endif return ierr ; }
int main(int argc, char* argv[]) { FILE* MapFile=0; FILE* CallsFile=0; FILE* ObjFile=0; FILE* CodeFile=0; FILE* ProtoFile=0; char Line[MAX_STRING]; char Name[MAX_NAME]; char Command[MAX_NAME]; char File[MAX_STRING]; char AddressString[MAX_STRING]; word Address; bool PrependJPs=FALSE; int i; if(argc>1) if(!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) { Syntax(argv[0]); exit(0); } for(i=1; i<argc; i++) { if(!strcmp(argv[i], "--jp")) { PrependJPs=TRUE; } else if(!strcmp(argv[i], "--code") && i+1<argc) { CodeFile=fopen(argv[++i], "w"); } else if((!strcmp(argv[i], "--input") || !strcmp(argv[i], "-i")) && i+1<argc) { if(!strcmp(argv[++i], "-")) { CallsFile=stdin; } else { CallsFile=fopen(argv[i], "r"); } } else if(!strcmp(argv[i], "--sym") && i+1<argc) { MapFile=fopen(argv[++i], "r"); } else if((!strcmp(argv[i], "--obj") || !strcmp(argv[i], "-o")) && i+1<argc) { ObjFile=fopen(argv[++i], "w"); } } if(!CallsFile || !MapFile || !ObjFile) { fprintf(stderr, "You must specify at least a valid input file, symbols file and object file\n"); Syntax(argv[0]); exit(-1); } if(CodeFile) fprintf(stderr, "Will generate a C source with function wrappers.\n"); fprintf(stderr, "Creating list of functions to be mapped...\n"); FunctionsCount=0; while(!feof(CallsFile)) { fgets(Line, MAX_STRING, CallsFile); sscanf(Line, "%s", Command); if(!strcmp(Command, "prototypes")) { sscanf(Line, "%s %s", Command, File); if(ProtoFile) fclose(ProtoFile); if(!(ProtoFile=fopen(File, "r"))) { fprintf(stderr, "No such prototypes file '%s'.\n", File); exit(-1); } } else { sscanf(Line, "%x %s", &Functions[FunctionsCount].ID, Functions[FunctionsCount].Name); Functions[FunctionsCount].Address=0xFFFF; if(ProtoFile) GetPrototype(ProtoFile, &Functions[FunctionsCount]); if(!feof(CallsFile)) FunctionsCount++; } } fprintf(stderr, "Mapping functions...\n"); while(!feof(MapFile)) { fgets(Line, MAX_STRING, MapFile); if(Line[0]!=';') { sscanf(Line, "%s %s", AddressString, Name); sscanf(&AddressString[3], "%x", &Address); if(Name[0]=='_' && AddressString[2]==':') Map(&Name[1], Address); } } fprintf(stderr, "Sorting list...\n"); SortFunctions(); fprintf(stderr, "Generating output...\n\n"); if(CodeFile) { fprintf(CodeFile, "/* Library source generated by funcmap\n (Copyright (c) 2003 Lorenzo J. Lucchini, <*****@*****.**>)\n\n Every library function saves the address to resume userland execution from\n into HL, then loads the system call number into A, and then makes the call\n by means of a RST08 instruction. */\n\n\n"); fprintf(CodeFile, "/* Declarations */\n\n"); for(i=0; i<FunctionsCount; i++) { fprintf(CodeFile, "%s;\n", Functions[i].Prototype); } fprintf(CodeFile, "\n/* Definitions */ \n"); } for(i=0; i<FunctionsCount; i++) { if(Functions[i].Address==0xFFFF) { fprintf(stderr, "Warning: Unmapped call %03d ('%s')\n", Functions[i].ID, Functions[i].Name); } else { if(CodeFile) { fprintf(CodeFile, "\n%s {\n", Functions[i].Prototype); fprintf(CodeFile, " _asm\n pop hl\n ld a,#0x%02x\n rst 0x08\n _endasm;\n", Functions[i].ID); fprintf(CodeFile, "}\n"); } fprintf(stdout, "Call %03d: '%s' at %04x\n", Functions[i].ID, Functions[i].Name, Functions[i].Address); if(PrependJPs) fprintf(ObjFile, "%c", OP_JP); fprintf(ObjFile, "%c%c", Functions[i].Address&0xff, (Functions[i].Address>>8)&0xff); } } fprintf(stdout, "\n"); return 0; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc, &argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif bool verbose = (Comm.MyPID() == 0); // set global dimension to 5, could be any number int NumGlobalElements = 5; // create a map Epetra_Map Map(NumGlobalElements,0,Comm); // local number of rows int NumMyElements = Map.NumMyElements(); // get update list int * MyGlobalElements = Map.MyGlobalElements( ); // ============= CONSTRUCTION OF THE MATRIX =========================== // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy,Map,3); // Add rows one-at-a-time double *Values = new double[2]; Values[0] = -1.0; Values[1] = -1.0; int *Indices = new int[2]; double two = 2.0; int NumEntries; for( int i=0 ; i<NumMyElements; ++i ) { if (MyGlobalElements[i]==0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalElements-1) { Indices[0] = NumGlobalElements-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } A.InsertGlobalValues(MyGlobalElements[i], NumEntries, Values, Indices); // Put in the diagonal entry A.InsertGlobalValues(MyGlobalElements[i], 1, &two, MyGlobalElements+i); } // Finish up A.FillComplete(); // ================ CONSTRUCTION OF VECTORS ======================= // build up two distributed vectors q and z, and compute // q = A * z Epetra_Vector q(A.RowMap()); Epetra_Vector z(A.RowMap()); // Fill z with 1's z.PutScalar( 1.0 ); // ================ USE OF TIME AND FLOPS ========================= Epetra_Flops counter; A.SetFlopCounter(counter); Epetra_Time timer(Comm); A.Multiply(false, z, q); // Compute q = A*z double elapsed_time = timer.ElapsedTime(); double total_flops =counter.Flops(); if (verbose) cout << "Total ops: " << total_flops << endl; double MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "Total MFLOPs for mat-vec = " << MFLOPs << endl<< endl; double dotProduct; z.SetFlopCounter(counter); timer.ResetStartTime(); z.Dot(q, &dotProduct); total_flops =counter.Flops(); if (verbose) cout << "Total ops: " << total_flops << endl; elapsed_time = timer.ElapsedTime(); if (elapsed_time != 0.0) MFLOPs = (total_flops / elapsed_time) / 1000000.0; else MFLOPs = 0; if (verbose) { cout << "Total MFLOPs for vec-vec = " << MFLOPs << endl<< endl; cout << "q dot z = " << dotProduct << endl; } #ifdef HAVE_MPI MPI_Finalize(); #endif return( 0 ); } /* main */
//========================================================================= int Epetra_IntVector::CopyAndPermute(const Epetra_SrcDistObject& Source, int NumSameIDs, int NumPermuteIDs, int * PermuteToLIDs, int *PermuteFromLIDs, const Epetra_OffsetIndex * Indexor, Epetra_CombineMode CombineMode) { (void)Indexor; const Epetra_IntVector & A = dynamic_cast<const Epetra_IntVector &>(Source); int * From; A.ExtractView(&From); int *To = Values_; int * ToFirstPointInElementList = 0; int * FromFirstPointInElementList = 0; int * FromElementSizeList = 0; int MaxElementSize = Map().MaxElementSize(); bool ConstantElementSize = Map().ConstantElementSize(); if (!ConstantElementSize) { ToFirstPointInElementList = Map().FirstPointInElementList(); FromFirstPointInElementList = A.Map().FirstPointInElementList(); FromElementSizeList = A.Map().ElementSizeList(); } int j, jj, jjj, k; int NumSameEntries; bool Case1 = false; bool Case2 = false; // bool Case3 = false; if (MaxElementSize==1) { Case1 = true; NumSameEntries = NumSameIDs; } else if (ConstantElementSize) { Case2 = true; NumSameEntries = NumSameIDs * MaxElementSize; } else { // Case3 = true; NumSameEntries = FromFirstPointInElementList[NumSameIDs]; } // Short circuit for the case where the source and target vector is the same. if (To==From) NumSameEntries = 0; // Do copy first if (NumSameIDs>0) if (To!=From) { if (CombineMode==Epetra_AddLocalAlso) for (j=0; j<NumSameEntries; j++) To[j] += From[j]; // Add to existing value else for (j=0; j<NumSameEntries; j++) To[j] = From[j]; } // Do local permutation next if (NumPermuteIDs>0) { // Point entry case if (Case1) { if (CombineMode==Epetra_AddLocalAlso) for (j=0; j<NumPermuteIDs; j++) To[PermuteToLIDs[j]] += From[PermuteFromLIDs[j]]; // Add to existing value else for (j=0; j<NumPermuteIDs; j++) To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]]; } // constant element size case else if (Case2) { if (CombineMode==Epetra_AddLocalAlso) for (j=0; j<NumPermuteIDs; j++) { jj = MaxElementSize*PermuteToLIDs[j]; jjj = MaxElementSize*PermuteFromLIDs[j]; for (k=0; k<MaxElementSize; k++) To[jj+k] += From[jjj+k]; } else for (j=0; j<NumPermuteIDs; j++) { jj = MaxElementSize*PermuteToLIDs[j]; jjj = MaxElementSize*PermuteFromLIDs[j]; for (k=0; k<MaxElementSize; k++) To[jj+k] = From[jjj+k]; } } // variable element size case else { if (CombineMode==Epetra_AddLocalAlso) for (j=0; j<NumPermuteIDs; j++) { jj = ToFirstPointInElementList[PermuteToLIDs[j]]; jjj = FromFirstPointInElementList[PermuteFromLIDs[j]]; int ElementSize = FromElementSizeList[PermuteFromLIDs[j]]; for (k=0; k<ElementSize; k++) To[jj+k] += From[jjj+k]; } else for (j=0; j<NumPermuteIDs; j++) { jj = ToFirstPointInElementList[PermuteToLIDs[j]]; jjj = FromFirstPointInElementList[PermuteFromLIDs[j]]; int ElementSize = FromElementSizeList[PermuteFromLIDs[j]]; for (k=0; k<ElementSize; k++) To[jj+k] = From[jjj+k]; } } } return(0); }
int main(int argc, char **argv) { QCoreApplication app(argc, argv); QTextCodec *big5 = QTextCodec::codecForName("Big5-hkscs"); #if 0 QFile f("/home/lars/dev/qt-4.0/util/unicode/data/big5-eten.txt"); f.open(QFile::ReadOnly); while (!f.atEnd()) { QByteArray line = f.readLine(); if (line.startsWith("#")) continue; line.replace("0x", ""); line.replace("U+", ""); line.replace("\t", " "); line = line.simplified(); QList<QByteArray> split = line.split(' '); bool ok; int b5 = split.at(0).toInt(&ok, 16); Q_ASSERT(ok); int uc = split.at(1).toInt(&ok, 16); Q_ASSERT(ok); if (b5 < 0x100) continue; #else QFile f(":/BIG5"); f.open(QFile::ReadOnly); while (!f.atEnd()) { QByteArray line = f.readLine(); if (line.startsWith("CHARMAP")) break; } QSet<uint> b5_ok; QSet<uint> uc_ok; QList<Map> b5_to_uc_map; QList<Map> uc_to_b5_map; while (!f.atEnd()) { QByteArray line = f.readLine(); if (line.startsWith("%")) continue; if (line.startsWith("END CHARMAP")) break; line.replace("/x", ""); line.replace("<U", ""); line.replace(">", ""); line.replace("\t", " "); line = line.simplified(); QList<QByteArray> split = line.split(' '); bool ok; int b5 = split.at(1).toInt(&ok, 16); Q_ASSERT(ok); int uc = split.at(0).toInt(&ok, 16); Q_ASSERT(ok); if (b5 < 0x100 || uc > 0xffff) continue; #endif // qDebug() << hex << "testing: '" << b5 << "' - '" << uc << "'"; QByteArray ba; ba += (char)(uchar)(b5 >> 8); ba += (char)(uchar)(b5 & 0xff); QString s = big5->toUnicode(ba); Q_ASSERT(s.length() == 1); QString s2; s2 = QChar(uc); ba = big5->fromUnicode(s2); Q_ASSERT(ba.length() <= 2); int round; if (ba.length() == 1) round = (int)(uchar)ba[0]; else round = ((int)(uchar)ba[0] << 8) + (int)(uchar)ba[1]; if (b5 != round) uc_to_b5_map += Map(uc, b5); else b5_ok.insert(b5); if (s[0].unicode() != uc) b5_to_uc_map += Map(uc, b5); else uc_ok.insert(uc); }; QList<QByteArray> list; foreach(Map m, b5_to_uc_map) { if (!uc_ok.contains(m.b5)) list += QByteArray(" { 0x" + QByteArray::number(m.b5, 16) + ", 0x" + QByteArray::number(m.uc, 16) + " }\n");; } QByteArray ba; qSort(list); foreach(QByteArray a, list) ba += a; qDebug() << "struct B5Map b5_to_uc_map = {\n" << ba + "\n};"; list = QList<QByteArray>(); foreach(Map m, uc_to_b5_map) if (!b5_ok.contains(m.uc)) list += QByteArray(" { 0x" + QByteArray::number(m.uc, 16) + ", 0x" + QByteArray::number(m.b5, 16) + " }\n");; ba = QByteArray(); qSort(list); foreach(QByteArray a, list) ba += a; qDebug() << "struct B5Map uc_to_b5_map = {\n" << ba + "\n};"; }
//========================================================================= int Epetra_IntVector::UnpackAndCombine(const Epetra_SrcDistObject & Source, int NumImportIDs, int * ImportLIDs, int LenImports, char * Imports, int & SizeOfPacket, Epetra_Distributor & Distor, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex * Indexor) { (void)Source; (void)LenImports; (void)SizeOfPacket; (void)Distor; (void)Indexor; int j, jj, k; if( CombineMode != Add && CombineMode != Zero && CombineMode != Insert && CombineMode != Average && CombineMode != AbsMax ) EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero if (NumImportIDs<=0) return(0); int * To = Values_; int MaxElementSize = Map().MaxElementSize(); bool ConstantElementSize = Map().ConstantElementSize(); int * ToFirstPointInElementList = 0; int * ToElementSizeList = 0; if (!ConstantElementSize) { ToFirstPointInElementList = Map().FirstPointInElementList(); ToElementSizeList = Map().ElementSizeList(); } int * ptr; // Unpack it... ptr = (int *) Imports; // Point entry case if (MaxElementSize==1) { if (CombineMode==Add) for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] += *ptr++; // Add to existing value else if(CombineMode==Insert) for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] = *ptr++; else if(CombineMode==AbsMax) for (j=0; j<NumImportIDs; j++) { To[ImportLIDs[j]] = EPETRA_MAX( To[ImportLIDs[j]],std::abs(*ptr)); ptr++; } // Note: The following form of averaging is not a true average if more that one value is combined. // This might be an issue in the future, but we leave this way for now. else if(CombineMode==Average) for (j=0; j<NumImportIDs; j++) {To[ImportLIDs[j]] += *ptr++; To[ImportLIDs[j]] /= 2;} } // constant element size case else if (ConstantElementSize) { if (CombineMode==Add) { for (j=0; j<NumImportIDs; j++) { jj = MaxElementSize*ImportLIDs[j]; for (k=0; k<MaxElementSize; k++) To[jj+k] += *ptr++; // Add to existing value } } else if(CombineMode==Insert) { for (j=0; j<NumImportIDs; j++) { jj = MaxElementSize*ImportLIDs[j]; for (k=0; k<MaxElementSize; k++) To[jj+k] = *ptr++; } } else if(CombineMode==AbsMax) { for (j=0; j<NumImportIDs; j++) { jj = MaxElementSize*ImportLIDs[j]; for (k=0; k<MaxElementSize; k++) { To[jj+k] = EPETRA_MAX( To[jj+k], std::abs(*ptr)); ptr++; } } } // Note: The following form of averaging is not a true average if more that one value is combined. // This might be an issue in the future, but we leave this way for now. else if(CombineMode==Average) { for (j=0; j<NumImportIDs; j++) { jj = MaxElementSize*ImportLIDs[j]; for (k=0; k<MaxElementSize; k++) { To[jj+k] += *ptr++; To[jj+k] /= 2;} } } } // variable element size case else { int thisSizeOfPacket = MaxElementSize; if (CombineMode==Add) { for (j=0; j<NumImportIDs; j++) { ptr = (int *) Imports + j*thisSizeOfPacket; jj = ToFirstPointInElementList[ImportLIDs[j]]; int ElementSize = ToElementSizeList[ImportLIDs[j]]; for (k=0; k<ElementSize; k++) To[jj+k] += *ptr++; // Add to existing value } } else if(CombineMode==Insert){ for (j=0; j<NumImportIDs; j++) { ptr = (int *) Imports + j*thisSizeOfPacket; jj = ToFirstPointInElementList[ImportLIDs[j]]; int ElementSize = ToElementSizeList[ImportLIDs[j]]; for (k=0; k<ElementSize; k++) To[jj+k] = *ptr++; } } else if(CombineMode==AbsMax){ for (j=0; j<NumImportIDs; j++) { ptr = (int *) Imports + j*thisSizeOfPacket; jj = ToFirstPointInElementList[ImportLIDs[j]]; int ElementSize = ToElementSizeList[ImportLIDs[j]]; for (k=0; k<ElementSize; k++) { To[jj+k] = EPETRA_MAX( To[jj+k], std::abs(*ptr)); ptr++; } } } // Note: The following form of averaging is not a true average if more that one value is combined. // This might be an issue in the future, but we leave this way for now. else if(CombineMode==Average) { for (j=0; j<NumImportIDs; j++) { ptr = (int *) Imports + j*thisSizeOfPacket; jj = ToFirstPointInElementList[ImportLIDs[j]]; int ElementSize = ToElementSizeList[ImportLIDs[j]]; for (k=0; k<ElementSize; k++) { To[jj+k] += *ptr++; To[jj+k] /= 2;} } } } return(0); }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc, &argv); // define an Epetra communicator Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // check number of processes if (Comm.NumProc() != 1) { if (Comm.MyPID() == 0) cerr << "*ERR* can be used only with one process" << endl; #ifdef HAVE_MPI MPI_Finalize(); #endif exit(EXIT_SUCCESS); } // process 0 will read an HB matrix, and store it // in the MSR format given by the arrays bindx and val int N_global; int N_nonzeros; double * val = NULL; int * bindx = NULL; double * x = NULL, * b = NULL, * xexact = NULL; FILE* fp = fopen("../HBMatrices/fidap005.rua", "r"); if (fp == 0) { cerr << "Matrix file not available" << endl; #ifdef HAVE_MPI MPI_Finalize(); #endif exit(EXIT_SUCCESS); } fclose(fp); Trilinos_Util_read_hb("../HBMatrices/fidap005.rua", 0, &N_global, &N_nonzeros, &val, &bindx, &x, &b, &xexact); // assign all the elements to process 0 // (this code can run ONLY with one process, extensions to more // processes will require functions to handle update of ghost nodes) Epetra_Map Map(N_global,0,Comm); MSRMatrix A(Map,bindx,val); // define two vectors Epetra_Vector xxx(Map); Epetra_Vector yyy(Map); xxx.Random(); A.Apply(xxx,yyy); cout << yyy; double norm2; yyy.Norm2(&norm2); cout << norm2 << endl; // free memory allocated by Trilinos_Util_read_hb if (val != NULL) free((void*)val); if (bindx != NULL) free((void*)bindx); if (x != NULL) free((void*)x); if (b != NULL) free((void*)x); if (xexact != NULL) free((void*)xexact);; #ifdef HAVE_MPI MPI_Finalize(); #endif return(EXIT_SUCCESS); } /* main */
void build_test_matrix(Epetra_MpiComm & Comm, int test_number, Epetra_CrsMatrix *&A){ int NumProc = Comm.NumProc(); int MyPID = Comm.MyPID(); if(test_number==1){ // Case 1: Tridiagonal int NumMyEquations = 100; int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0, Comm); // Get update list and number of local equations from newly created Map int* MyGlobalElements = new int[Map.NumMyElements()]; Map.MyGlobalElements(MyGlobalElements); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNz = new int[NumMyEquations]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (int i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix A=new Epetra_CrsMatrix(Copy, Map, NumNz); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 double* Values = new double[2]; Values[0] = -1.0; Values[1] = -1.0; int* Indices = new int[2]; double two = 2.0; int NumEntries; for (int i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } A->InsertGlobalValues(MyGlobalElements[i], NumEntries, Values, Indices); A->InsertGlobalValues(MyGlobalElements[i], 1, &two, MyGlobalElements+i); } A->FillComplete(); // Cleanup delete [] MyGlobalElements; delete [] NumNz; delete [] Values; delete [] Indices; } }
/* ** The Nemesis domain is special - it gets passed ** only half a comment ** and its Pvs are special. */ void Go(Activation_cl *self, VP_clp vp /* IN */, Activation_Reason ar /* IN */ ) { kernel_st *kst = (kernel_st *)self->st; dcb_rw_t *rwp = vp->st; dcb_ro_t *rop = DCB_RW2RO(rwp); ActivationF_cl *actf; TRY { #ifdef __IX86__ ntsc_entkern(); /* There is an NTSC hack that prevents this from being undone. */ #endif /* __IX86__ */ /* Direct all output from Nemesis domain through NTSC (or, on Alpha, direct to the hardware) */ Pvs(err)=Pvs(out)=Pvs(console)=&triv_wr_cl; TRC(printf("Nemesis domain entered.\n")); TRC(printf(" + DCBRO at %p\n", rop)); TRC(printf(" psmask=%qx\n", rop->psmask)); #ifdef __ALPHA__ TRC(printf(" ps=%qx\n", ntsc_rdps())); #endif TRC(printf(" + DCBRW at %p\n", rwp)); TRC(printf(" + Activation clp at %p\n", self)); TRC(printf(" + VP clp at %p\n", vp)); TRC(printf(" + activationsOn=%d\n", VP$ActivationMode(vp))); TRC(printf(" + Activation Reason %d\n", ar)); TRC(printf(" + PVS = %p\n", PVS())); TRC(DUMP_PVS()); { StretchAllocator_clp salloc; StretchAllocator_SizeSeq *sizes; StretchAllocator_StretchSeq *stretches; ThreadsPackage_Stack protoStack; Stretch_clp userStretch; BootDomain_Info *nem_info; ThreadsPackage_clp tp; ThreadF_clp thdf; #ifdef CONFIG_MEMSYS_EXPT SDriverMod_cl *sdmod; StretchTbl_cl *strtab; #define MAX_DESCS 5 Mem_PMemDesc pmem[MAX_DESCS + 1]; Type_Any fany; flink_t *lk; flist_t *cur; int i = 0; /* Create a new stretch driver (physical one for now) */ TRC(printf("Creating initial stretch driver and stretch tab.\n")); sdmod = NAME_FIND("modules>SDriverMod", SDriverMod_clp); strtab = NAME_FIND("sys>StretchTable", StretchTbl_clp); /* Grab the pmem which has been allocated for us by dmgr */ for(lk = rop->finfo.next; lk != &rop->finfo; lk = lk->next) { cur = (flist_t *)lk; pmem[i].start_addr = cur->base; pmem[i].frame_width = cur->fwidth; pmem[i].nframes = cur->npf >> (cur->fwidth - FRAME_WIDTH); pmem[i].attr = 0; if(++i == MAX_DESCS) break; } pmem[i].nframes = 0; /* terminate array */ ANY_INIT(&fany, Frames_clp, rop->frames); Pvs(sdriver) = SDriverMod$NewPhysical(sdmod, vp, Pvs(heap), strtab, pmem, &fany); #endif /* Add our personal frames closure into the sys context */ /* XXX SDE: I'm not convinced that this is a good idea; the Nemesis domain (and all other domains) should have a bit of private namespace for this. I was bitten once by a domain using the Nemesis domain's Frames closure directly because its own hadn't overridden it in the namespace. */ CX_ADD("sys>Frames", rop->frames, Frames_clp); TRC(eprintf (" + Finding Nemesis StretchAllocator\n")); salloc = NAME_FIND("sys>StretchAllocator", StretchAllocator_clp); TRC(eprintf (" + StretchAlloc = %p\n", salloc)); TRC(eprintf (" + Finding parameters\n")); nem_info= NAME_FIND("progs>Nemesis", BootDomain_InfoP); sizes = SEQ_NEW(StretchAllocator_SizeSeq, 3, Pvs(heap)); SEQ_ELEM(sizes, 0) = FRAME_SIZE; /* for guard page */ SEQ_ELEM(sizes, 1) = nem_info->stackWords*sizeof(word_t); SEQ_ELEM(sizes, 2) = nem_info->pHeapWords*sizeof(word_t); TRC(eprintf (" + Allocating Stretches\n")); stretches = STR_NEWLIST_SALLOC(salloc, sizes); protoStack.guard = SEQ_ELEM(stretches, 0); protoStack.stretch = SEQ_ELEM(stretches, 1); userStretch = SEQ_ELEM(stretches, 2); TRC(eprintf (" + Freeing SEQs\n")); SEQ_FREE(sizes); SEQ_FREE(stretches); #ifdef CONFIG_MEMSYS_EXPT /* Bind and map the stack */ { Stretch_Size sz; addr_t stackva; int npages; TRC(printf("+ Binding and mapping stack.\n")); stackva = STR_RANGE(protoStack.stretch, &sz); npages = sz >> PAGE_WIDTH; while(npages--) { StretchDriver$Map(Pvs(sdriver), protoStack.stretch, stackva); stackva += PAGE_SIZE; } } #endif TRC(printf(" + Setting protection\n")); SALLOC_SETGLOBAL(salloc, protoStack.guard, 0); /* XXX PRB Global write is a bit dodgy to say the least! */ SALLOC_SETGLOBAL(salloc, protoStack.stretch, SET_ELEM(Stretch_Right_Read) | SET_ELEM(Stretch_Right_Write) ); SALLOC_SETGLOBAL(salloc, userStretch, SET_ELEM(Stretch_Right_Read) | SET_ELEM(Stretch_Right_Write) ); TRC(printf(" + Finding ThreadsPackage\n")); tp = NAME_FIND("modules>NonPreemptiveThreads",ThreadsPackage_clp); TRC(printf(" + ThreadsPackage = %p\n", tp)); if(!(thdf = ThreadsPackage$New(tp, (addr_t)&NemesisMainThread, (addr_t)kst, &protoStack, userStretch, nem_info->stackWords*sizeof(word_t), (Pervasives_Init *)PVS(), &actf))) { TRC(printf("Nemesis: can't get threads.\n")); ntsc_halt(); } /* Set ourselves up to handle memory faults */ /* first get/set an event channel for fault notification */ rwp->mm_ep = VP$AllocChannel(Pvs(vp)); #if defined(CONFIG_MEMSYS_STD) || defined(CONFIG_MEMSYS_EXPT) { MMNotifyMod_cl *mmnmod; MMNotify_cl *mmnfy; StretchTbl_clp strtable; #ifdef CONFIG_MEMSYS_EXPT /* get the stretch table */ TRC(eprintf (" + Finding StretchTable\n")); strtable = NAME_FIND("sys>StretchTable", StretchTbl_clp); #else strtable = (StretchTbl_cl *)NULL; #endif mmnmod = NAME_FIND("modules>MMNotifyMod", MMNotifyMod_clp); mmnfy = MMNotifyMod$New(mmnmod, vp, Pvs(heap), strtable); CX_ADD("sys>MMNotify", mmnfy, MMNotify_clp); ActivationF$Attach(actf, (ChannelNotify_cl *)mmnfy, rwp->mm_ep); } #endif /* for non expt, we do all this with a mmentry in main thd */ } TRC(printf(" + yielding to main thread.\n")); VP$ActivationsOn(Pvs(vp)); VP$Yield(Pvs(vp)); } CATCH_Context$NotFound(name) { printf("Caught execption Context$NotFound(%s)\n", name); } CATCH_ALL { printf("Caught exception %s\n", exn_ctx.cur_exception); } ENDTRY; /* XXX we are not happy here; for now, just halt. */ printf("\nNemesis: Much bogosity!!! halting.\n"); ntsc_dbgstop(); }