Changeset 23251
- Timestamp:
- 09/11/18 09:19:05 (7 years ago)
- Location:
- issm/trunk-jpl/src/c
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/classes/FemModel.cpp
r23242 r23251 17 17 #include "../shared/Enum/Enum.h" 18 18 #include "../analyses/analyses.h" 19 20 #if _HAVE_CODIPACK_ 21 #include <sstream> // for output of the CoDiPack tape 22 extern CoDi_global codi_global; 23 #endif 19 24 20 25 /*module includes: {{{*/ … … 1851 1856 dependents=xNew<IssmPDouble>(num_dependents); 1852 1857 1858 #if defined(_HAVE_CODIPACK_) 1859 auto& tape_codi = IssmDouble::getGlobalTape(); 1860 #endif 1861 1853 1862 /*Go through our dependent variables, and compute the response:*/ 1854 1863 for(int i=0;i<dependent_objects->Size();i++){ … … 1856 1865 dep->Responsex(&output_value,this); 1857 1866 if (my_rank==0) { 1858 output_value>>=dependents[i]; 1867 #if defined(_HAVE_CODIPACK_) 1868 tape_codi.registerOutput(output_value); 1869 dependents[i] = output_value.getValue(); 1870 codi_global.output_indices.push_back(output_value.getGradientData()); 1871 #else 1872 output_value>>=dependents[i]; 1873 #endif 1859 1874 } 1860 1875 } -
issm/trunk-jpl/src/c/classes/IoModel.cpp
r23174 r23251 27 27 #include "../shared/io/io.h" 28 28 #include "../shared/shared.h" 29 30 #ifdef _HAVE_CODIPACK_ 31 extern CoDi_global codi_global; 32 #include <sstream> // for output of the CoDiPack tape 33 #endif 29 34 30 35 /*IoConstant class and methods*/ … … 431 436 if(trace || (autodiff && !iscontrol)){ 432 437 433 #ifdef _HAVE_ADOLC_ 438 #ifdef _HAVE_AD_ 439 // FIXME codi here we should be able to execute codi version as normal 434 440 this->FetchData(&num_independent_objects,"md.autodiff.num_independent_objects"); 435 441 if(num_independent_objects){ … … 460 466 #else 461 467 /*if we asked for AD computations, we have a problem!: */ 462 _error_("Cannot carry out AD mode computations without support of ADOLC compiled in!");468 _error_("Cannot carry out AD mode computations without support of ADOLC or CoDiPack compiled in!"); 463 469 #endif 464 470 } … … 1702 1708 if(X) Xcount=*pXcount; 1703 1709 1704 #ifdef _HAVE_AD OLC_ //cannot come here unless you are running AD mode, from DeclaredIndependents:1710 #ifdef _HAVE_AD_ //cannot come here unless you are running AD mode, from DeclaredIndependents: 1705 1711 1706 1712 /*output: */ … … 1719 1725 /*Now, before we even broadcast this to other nodes, declare the scalar as an independent variable!. If we 1720 1726 *have been supplied an X vector, use it instead of what we just read: */ 1721 if(X){ 1722 scalar<<=X[Xcount]; 1723 } 1724 else{ 1725 scalar<<=pscalar; 1726 } 1727 #if defined(_HAVE_CODIPACK_) 1728 // FIXME codi here we just assign instead of using "operator <<=" 1729 if(X){ 1730 scalar=X[Xcount]; 1731 } else { 1732 scalar=pscalar; 1733 } 1734 auto& tape_codi = IssmDouble::getGlobalTape(); 1735 tape_codi.registerInput(scalar); 1736 codi_global.input_indices.push_back(scalar.getGradientData()); 1737 #else 1738 if(X){ 1739 scalar<<=X[Xcount]; 1740 } 1741 else{ 1742 scalar<<=pscalar; 1743 } 1744 #endif 1727 1745 } 1728 1746 … … 1785 1803 /*Now, before we even broadcast this to other nodes, declare the whole matrix as a independent variable! 1786 1804 If we have been supplied an X vector, use it instead of what we just read: */ 1787 if(X){ 1788 for(int i=0;i<M*N;i++) matrix[i]<<=X[Xcount+i]; /*<<= ADOLC overloaded operator to declare independent*/ 1789 } 1790 else{ 1791 for(int i=0;i<M*N;i++) matrix[i]<<=buffer[i]; 1792 } 1805 #if defined(_HAVE_CODIPACK_) 1806 // FIXME codi here we just assign instead of using "operator <<=" 1807 auto& tape_codi = IssmDouble::getGlobalTape(); 1808 if(X){ 1809 for (int i=0;i<M*N;i++) { 1810 matrix[i]=X[Xcount+i]; 1811 tape_codi.registerInput(matrix[i]); 1812 codi_global.input_indices.push_back(matrix[i].getGradientData()); 1813 } 1814 } 1815 else{ 1816 for (int i=0;i<M*N;i++) { 1817 matrix[i]=buffer[i]; 1818 tape_codi.registerInput(matrix[i]); 1819 codi_global.input_indices.push_back(matrix[i].getGradientData()); 1820 } 1821 } 1822 #else /*ADOLC*/ 1823 if(X){ 1824 for(int i=0;i<M*N;i++) matrix[i]<<=X[Xcount+i]; /*<<= ADOLC overloaded operator to declare independent*/ 1825 } 1826 else{ 1827 for(int i=0;i<M*N;i++) matrix[i]<<=buffer[i]; 1828 } 1829 #endif 1793 1830 } 1794 1831 ISSM_MPI_Bcast(matrix,M*N,ISSM_MPI_DOUBLE,0,IssmComm::GetComm()); … … 1798 1835 else _error_("cannot declare the independent variable \"" << data_name << "\" if it's empty!"); 1799 1836 1837 // FIXME codi is that at all relevant to CoDiPack or can we simply assume the same? 1838 1800 1839 /*Add to data as independent*/ 1801 1840 this->AddDataIndependent(new IoData(matrix,code,layout,M,N,data_name)); … … 2562 2601 2563 2602 if(trace || (autodiff && !iscontrol)){ 2564 #ifdef _HAVE_ADOLC_ 2603 2604 #if defined(_HAVE_ADOLC_) 2565 2605 /*Retrieve parameters: */ 2566 2606 this->FetchData(&keep,"md.autodiff.keep"); … … 2579 2619 int skipFileDeletion=1; 2580 2620 trace_on(my_rank,keepTaylors,reCast<size_t>(obufsize),reCast<size_t>(lbufsize),reCast<size_t>(cbufsize),reCast<size_t>(tbufsize),skipFileDeletion); 2621 2622 #elif defined(_HAVE_CODIPACK_) 2623 //fprintf(stderr, "*** Codipack IoModel::StartTrace\n"); 2624 /* 2625 * FIXME codi 2626 * - ADOL-C variant uses fine grained tracing with various arguments 2627 * - ADOL-C variant sets a garbage collection parameter for its tape 2628 * -> These parameters are not read for the CoDiPack ISSM version! 2629 */ 2630 auto& tape_codi = IssmDouble::getGlobalTape(); 2631 tape_codi.setActive(); 2632 #if _AD_TAPE_ALLOC_ 2633 //alloc_profiler.Tag(StartInit, true); 2634 IssmDouble x_t(1.0), y_t(1.0); 2635 tape_codi.registerInput(y_t); 2636 int codi_allocn = 0; 2637 this->FetchData(&codi_allocn, AutodiffTapeAllocEnum); 2638 for(int i = 0;i < codi_allocn;++i) { 2639 x_t = y_t * y_t; 2640 } 2641 /* 2642 std::stringstream out_s; 2643 IssmDouble::getGlobalTape().printStatistics(out_s); 2644 _printf0_("StartTrace::Tape Statistics : TapeAlloc count=[" << codi_allocn << "]\n" << out_s.str()); 2645 */ 2646 tape_codi.reset(); 2647 //alloc_profiler.Tag(FinishInit, true); 2581 2648 #endif 2582 } 2583 2584 } 2585 /*}}}*/ 2649 #endif 2650 } 2651 2652 } 2653 /*}}}*/ -
issm/trunk-jpl/src/c/toolkits/gsl/DenseGslSolve.cpp
r21615 r23251 14 14 #include "../../classes/Params/Parameters.h" 15 15 #include "../adolc/adolcincludes.h" 16 #include "../codipack/codipackincludes.h" 16 17 #include "./gslincludes.h" 17 18 … … 251 252 /*}}}*/ 252 253 #endif 254 255 #ifdef _HAVE_CODIPACK_ 256 void SolverxSeq_codi_b(codi::DataStore* data) {/*{{{*/ 257 IssmDouble::TapeType& tape = IssmDouble::getGlobalTape(); 258 259 IssmDouble::Real* valueATrans; 260 IssmDouble::GradientData* indexATrans; 261 IssmDouble::GradientData* indexB; 262 IssmDouble::Real* valueX; 263 IssmDouble::GradientData* indexX; 264 int n; 265 266 data->getData(valueATrans); 267 data->getData(indexATrans); 268 data->getData(indexB); 269 data->getData(valueX); 270 data->getData(indexX); 271 data->getData(n); 272 273 274 // create the adjoint vector for x and reset the adjoint values on the tape 275 IssmDouble::GradientValue* adjX = xNew<IssmDouble::GradientValue>(n); 276 getVectorAdjoint(tape, indexX, adjX, n); 277 278 IssmDouble::GradientValue* sol = xNew<IssmDouble::GradientValue>(n); 279 SolverxSeq(sol, valueATrans, adjX, n); 280 281 updateVectorAdjoint(tape, indexB, sol, n); 282 for(int i=0; i<n; ++i) { 283 for (int j=0; j<n; ++j) { 284 // we access the transposed matrix here because we stored the indices in a transposed way 285 updateAdjoint(tape, indexATrans[i*n+j], -sol[j]*valueX[i]); 286 } 287 } 288 289 xDelete(sol); 290 xDelete(adjX); 291 } 292 /*}}}*/ 293 void SolverxSeq_codi_delete(codi::DataStore* data) {/*{{{*/ 294 IssmDouble::Real* valueATrans; 295 IssmDouble::GradientData* indexATrans; 296 IssmDouble::GradientData* indexB; 297 IssmDouble::Real* valueX; 298 IssmDouble::GradientData* indexX; 299 int n; 300 301 data->getData(valueATrans); 302 data->getData(indexATrans); 303 data->getData(indexB); 304 data->getData(valueX); 305 data->getData(indexX); 306 data->getData(n); 307 308 xDelete(valueATrans); 309 xDelete(indexATrans); 310 xDelete(indexB); 311 xDelete(valueX); 312 xDelete(indexX); 313 } 314 /*}}}*/ 315 void SolverxSeq(IssmDouble *X,IssmDouble *A,IssmDouble *B,int n, Parameters* parameters){/*{{{*/ 316 IssmDouble::TapeType& tape = IssmDouble::getGlobalTape(); 317 codi::DataStore* dataHandler = NULL; 318 319 if(tape.isActive()) { 320 dataHandler = new codi::DataStore(); 321 322 // create the index vector and the double data for A and B 323 IssmDouble::Real* valueATrans = xNew<IssmDouble::Real>(n*n); 324 IssmDouble::GradientData* indexATrans = xNew<IssmDouble::GradientData>(n*n); 325 326 // read the data for matrix in a transposed fashion 327 for (int i=0; i<n; ++i) { 328 for (int j=0; j<n; ++j) { 329 getPrimalAndGradData(A[i*n+j], valueATrans[j*n+i], indexATrans[j*n+i]); 330 } 331 } 332 333 // read the data from B (primal values are not required vor B 334 IssmDouble::GradientData* indexB = xNew<IssmDouble::GradientData>(n); 335 getVectorGradData(B, indexB, n); 336 337 dataHandler->addData(valueATrans); 338 dataHandler->addData(indexATrans); 339 dataHandler->addData(indexB); 340 } 341 342 // unpack the primal values from the matrix and the vector 343 IssmDouble::Real* valueA = xNew<IssmDouble::Real>(n*n); 344 IssmDouble::Real* valueB = xNew<IssmDouble::Real>(n); 345 // read the data from A and B 346 getVectorPrimal(A, valueA, n*n); 347 getVectorPrimal(B, valueB, n); 348 349 // create the placeholder for X and solve the system 350 IssmDouble::Real* valueX = xNew<IssmDouble::Real>(n); 351 SolverxSeq(valueX, valueA, valueB, n); 352 353 // pack the values into x 354 setVectorPrimal(X, valueX, n); 355 356 if(tape.isActive()) { 357 // create the index vector X and register x as active variables 358 IssmDouble::GradientData* indexX = xNew<IssmDouble::GradientData>(n); 359 registerVector(X, indexX, n); 360 361 dataHandler->addData(valueX); 362 dataHandler->addData(indexX); 363 364 // store other arguments 365 dataHandler->addData(n); 366 367 tape.pushExternalFunction(&SolverxSeq_codi_b, dataHandler, &SolverxSeq_codi_delete); 368 } else { 369 // if the tape is active valueX is stored in the dataHandler and deleted in the reverse sweep 370 xDelete(valueX); 371 } 372 373 xDelete(valueB); 374 xDelete(valueA); 375 } 376 /*}}}*/ 377 void DenseGslSolve(/*output*/ IssmDouble** px,/*stiffness matrix:*/ IssmDouble* Kff, int Kff_M, int Kff_N, /*right hand side load vector: */ IssmDouble* pf, int pf_M, Parameters* parameters){ /*{{{*/ 378 379 /*Intermediary: */ 380 381 if(Kff_N!=pf_M)_error_("Right hand side vector of size " << pf_M << ", when matrix is of size " << Kff_M << "-" << Kff_N << " !"); 382 if(Kff_M!=Kff_N)_error_("Stiffness matrix should be square!"); 383 384 IssmDouble *x = xNew<IssmDouble>(Kff_N,"t"); 385 386 SolverxSeq(x,Kff,pf,Kff_N,parameters); 387 388 /*allocate output pointers: */ 389 *px=x; 390 } 391 /*}}}*/ 392 #endif -
issm/trunk-jpl/src/c/toolkits/mpi/issmmpi.cpp
r20204 r23251 60 60 # endif 61 61 #else 62 # ifdef _HAVE_AD OLC_62 # ifdef _HAVE_AD_ 63 63 if (sendtype==ISSM_MPI_DOUBLE) { 64 64 IssmDouble* activeSendBuf=(IssmDouble*)sendbuf; … … 97 97 #else 98 98 assert(sendcount==recvcounts[0]); // we handle only identical representations 99 # ifdef _HAVE_AD OLC_99 # ifdef _HAVE_AD_ 100 100 if (sendtype==ISSM_MPI_DOUBLE) { 101 101 IssmDouble* activeSendBuf=(IssmDouble*)sendbuf; … … 129 129 # endif 130 130 #else 131 # ifdef _HAVE_ADOLC_131 #ifdef _HAVE_AD_ 132 132 if (datatype==ISSM_MPI_DOUBLE) { 133 133 IssmDouble* activeSendBuf=(IssmDouble*)sendbuf; … … 215 215 int ISSM_MPI_Finalize(void){ /*{{{*/ 216 216 217 int rc=0; 218 #ifdef _HAVE_MPI_ 219 # ifdef _HAVE_AMPI_ 220 rc=AMPI_Finalize_NT(); 221 # else 222 rc=MPI_Finalize(); 223 # endif 224 #endif 217 int rc=0; 218 #ifdef _HAVE_MPI_ 219 #ifdef _HAVE_AMPI_ 220 #ifdef _HAVE_ADJOINTMPI_ 221 rc=AMPI_Finalize(); 222 #else 223 rc=AMPI_Finalize_NT(); 224 #endif 225 #else 226 rc=MPI_Finalize(); 227 #endif 228 #endif 225 229 return rc; 226 230 }/*}}}*/ … … 250 254 # endif 251 255 #else 252 # ifdef _HAVE_AD OLC_256 # ifdef _HAVE_AD_ 253 257 if (sendtype==ISSM_MPI_DOUBLE) { 254 258 IssmDouble* activeSendBuf=(IssmDouble*)sendbuf; … … 290 294 #else 291 295 assert(sendcnt==recvcnts[0]); // we handle only identical representations 292 # ifdef _HAVE_ADOLC_296 #ifdef _HAVE_AD_ 293 297 if (sendtype==ISSM_MPI_DOUBLE) { 294 298 IssmDouble* activeSendBuf=(IssmDouble*)sendbuf; … … 304 308 int ISSM_MPI_Init(int *argc, char ***argv){ /*{{{*/ 305 309 306 int rc=0; 307 #ifdef _HAVE_MPI_ 308 # ifdef _HAVE_AMPI_ 309 rc=AMPI_Init_NT(argc,argv); 310 # else 311 rc=MPI_Init(argc,argv); 312 # endif 313 #endif 310 int rc=0; 311 #ifdef _HAVE_MPI_ 312 #ifdef _HAVE_AMPI_ 313 #ifdef _HAVE_ADJOINTMPI_ 314 rc=AMPI_Init(argc,argv); 315 #else 316 rc=AMPI_Init_NT(argc,argv); 317 #endif 318 #else 319 rc=MPI_Init(argc,argv); 320 #endif 321 #endif 314 322 return rc; 315 323 }/*}}}*/ … … 324 332 source, 325 333 tag, 334 #ifndef _HAVE_ADJOINTMPI_ 326 335 AMPI_FROM_SEND, // as long as there are no other variants 336 #endif 327 337 comm, 328 338 status); … … 365 375 # endif 366 376 #else 367 # ifdef _HAVE_AD OLC_377 # ifdef _HAVE_AD_ 368 378 if (datatype==ISSM_MPI_DOUBLE) { 369 379 IssmDouble* activeSendBuf=(IssmDouble*)sendbuf; … … 402 412 # endif 403 413 #else 404 # ifdef _HAVE_AD OLC_414 # ifdef _HAVE_AD_ 405 415 if (sendtype==ISSM_MPI_DOUBLE) { 406 416 IssmDouble* activeSendBuf=(IssmDouble*)sendbuf; … … 442 452 #else 443 453 assert(sendcnts[0]==recvcnt); // we handle only identical representations 444 # ifdef _HAVE_AD OLC_454 # ifdef _HAVE_AD_ 445 455 if (sendtype==ISSM_MPI_DOUBLE) { 446 456 IssmDouble* activeSendBuf=(IssmDouble*)(sendbuf)+displs[0]; … … 464 474 dest, 465 475 tag, 476 #ifndef _HAVE_ADJOINTMPI_ 466 477 AMPI_TO_RECV, // as long as there are no other variants 478 #endif 467 479 comm); 468 480 # else … … 492 504 #ifdef _HAVE_ADOLC_ 493 505 ensureContiguousLocations(aSize); 506 #else 507 fprintf(stderr, "*** Codipack ISSM_MPI_ContiguousInAdolc()\n"); 494 508 #endif 495 509 }/*}}}*/ -
issm/trunk-jpl/src/c/toolkits/mpi/issmmpi.h
r22585 r23251 19 19 /*Include header files: {{{*/ 20 20 #ifdef _HAVE_AMPI_ 21 #include <ampi/ampi.h> 21 #ifdef _HAVE_ADJOINTMPI_ 22 #include <ampi_tape.hpp> 23 #else 24 #include <ampi/ampi.h> 25 #endif 22 26 #elif _HAVE_PETSC_MPI_ // Petsc now hides there MPI header. It can be reached through Petsc. 23 27 #include <petsc.h> … … 35 39 // data types 36 40 #define ISSM_MPI_CHAR MPI_CHAR 37 #if def _HAVE_AMPI_41 #if defined(_HAVE_AMPI_) 38 42 #define ISSM_MPI_DOUBLE AMPI_ADOUBLE // corresponds to IssmDouble 43 #elif defined(_HAVE_ADJOINTMPI_) 44 #define ISSM_MPI_DOUBLE AMPI_DOUBLE // corresponds to IssmDouble 39 45 #else 40 46 #define ISSM_MPI_DOUBLE MPI_DOUBLE // corresponds to IssmDouble -
issm/trunk-jpl/src/c/toolkits/mumps/MumpsSolve.cpp
r23066 r23251 18 18 #include "../mpi/issmmpi.h" 19 19 #include "../adolc/adolcincludes.h" 20 #include "../codipack/codipackincludes.h" 20 21 #include "../issm/SparseRow.h" 21 22 #include "./mumpsincludes.h" … … 98 99 } 99 100 100 #ifdef _HAVE_AD OLC_101 #ifdef _HAVE_AD_ 101 102 // prototype for active variant 102 103 void MumpsSolve(int n, … … 354 355 355 356 #ifdef _HAVE_ADOLC_ 356 357 int mumpsSolveEDF(int iArrLength, int* iArr, int /* ignored */, IssmPDouble* dp_x, int /* ignored */, IssmPDouble* dp_y) { 357 int mumpsSolveEDF(int iArrLength, int* iArr, int /* ignored */, IssmPDouble* dp_x, int /* ignored */, IssmPDouble* dp_y){/*{{{*/ 358 358 // unpack parameters 359 359 int n=iArr[0]; … … 381 381 xDelete(local_irn); 382 382 return 0; 383 } 384 385 void MumpsSolve(int n,int nnz,int local_nnz,int* irn_loc,int* jcn_loc,IssmDouble *a_loc,IssmDouble *rhs,Parameters* parameters){ 383 }/*}}}*/ 384 void MumpsSolve(int n,int nnz,int local_nnz,int* irn_loc,int* jcn_loc,IssmDouble *a_loc,IssmDouble *rhs,Parameters* parameters){/*{{{*/ 386 385 int packedDimsSparseArrLength=1+1+1+local_nnz+local_nnz; 387 386 int *packedDimsSparseArr=xNew<int>(packedDimsSparseArrLength); … … 425 424 xDelete(pack_A_rhs); 426 425 xDelete(packedDimsSparseArr); 427 } 428 429 int fos_reverse_mumpsSolveEDF(int iArrLength, int* iArr, 430 int m, IssmPDouble *dp_U, 431 int nPlusNz, IssmPDouble *dp_Z, 432 IssmPDouble *dp_x, IssmPDouble *dp_y) { 426 }/*}}}*/ 427 int fos_reverse_mumpsSolveEDF(int iArrLength, int* iArr, int m, IssmPDouble *dp_U, int nPlusNz, IssmPDouble *dp_Z, IssmPDouble *dp_x, IssmPDouble *dp_y) {/*{{{*/ 433 428 // unpack parameters 434 429 int n=iArr[0]; … … 481 476 xDelete(local_irn); 482 477 return 3; 483 } 484 485 #endif 478 }/*}}}*/ 479 #endif 480 481 #ifdef _HAVE_CODIPACK_ 482 void MumpsSolve_codi_b(codi::DataStore* data) {/*{{{*/ 483 IssmDouble::TapeType& tape = IssmDouble::getGlobalTape(); 484 485 IssmDouble::Real* valueATrans; 486 IssmDouble::GradientData* indexATrans; 487 int* irnATrans; 488 int* jcnATrans; 489 IssmDouble::GradientData* indexB; 490 IssmDouble::Real* valueX; 491 IssmDouble::GradientData* indexX; 492 int n; 493 int nnz; 494 int local_nnz; 495 Parameters* parameters; 496 497 data->getData(valueATrans); 498 data->getData(indexATrans); 499 data->getData(irnATrans); 500 data->getData(jcnATrans); 501 data->getData(indexB); 502 data->getData(valueX); 503 data->getData(indexX); 504 data->getData(n); 505 data->getData(nnz); 506 data->getData(local_nnz); 507 data->getData(parameters); 508 509 // create the adjoint vector for x and reset the adjoint values on the tape 510 IssmDouble::GradientValue* adjX = xNew<IssmDouble::GradientValue>(n); 511 getVectorAdjoint(tape, indexX, adjX, n); 512 513 MumpsSolve(n, nnz, local_nnz, irnATrans, jcnATrans, valueATrans, adjX, parameters); 514 // adjX contains now the solution 515 516 updateVectorAdjoint(tape, indexB, adjX, n); 517 for(int i=0; i<local_nnz; ++i) { 518 // we access the transposed matrix here because we stored the indices in a transposed way 519 // -1 is substracted because jcn and irn are stored with fortran indexing 520 updateAdjoint(tape, indexATrans[i], -adjX[jcnATrans[i]-1]*valueX[irnATrans[i]-1]); 521 } 522 523 xDelete(adjX); 524 } 525 /*}}}*/ 526 void MumpsSolve_codi_delete(codi::DataStore* data) {/*{{{*/ 527 IssmDouble::Real* valueATrans; 528 IssmDouble::GradientData* indexATrans; 529 int* irnATrans; 530 int* jcnATrans; 531 IssmDouble::GradientData* indexB; 532 IssmDouble::Real* valueX; 533 IssmDouble::GradientData* indexX; 534 int n; 535 int nnz; 536 int local_nnz; 537 Parameters* parameters; 538 539 data->getData(valueATrans); 540 data->getData(indexATrans); 541 data->getData(irnATrans); 542 data->getData(jcnATrans); 543 data->getData(indexB); 544 data->getData(valueX); 545 data->getData(indexX); 546 data->getData(n); 547 data->getData(nnz); 548 data->getData(local_nnz); 549 data->getData(parameters); 550 551 xDelete(valueATrans); 552 xDelete(indexATrans); 553 xDelete(irnATrans); 554 xDelete(jcnATrans); 555 xDelete(indexB); 556 xDelete(valueX); 557 xDelete(indexX); 558 } 559 /*}}}*/ 560 void MumpsSolve(int n,int nnz,int local_nnz,int* irn_loc,int* jcn_loc,IssmDouble *a_loc,IssmDouble *rhs,Parameters* parameters){/*{{{*/ 561 IssmDouble::TapeType& tape = IssmDouble::getGlobalTape(); 562 codi::DataStore* dataHandler = NULL; 563 564 if(tape.isActive()) { 565 dataHandler = new codi::DataStore(); 566 567 // create the index and double vector for the matrix 568 IssmDouble::Real* valueATrans = xNew<IssmDouble::Real>(local_nnz); 569 IssmDouble::GradientData* indexATrans = xNew<IssmDouble::GradientData>(local_nnz); 570 int* irnATrans = xNew<int>(local_nnz); 571 int* jcnATrans = xNew<int>(local_nnz); 572 573 // read the data for the matrix A in a transposed fashion 574 for (int i=0; i<local_nnz; ++i) { 575 getPrimalAndGradData(a_loc[i], valueATrans[i], indexATrans[i]); 576 irnATrans[i]=jcn_loc[i]; // transposed store 577 jcnATrans[i]=irn_loc[i]; // transposed store 578 } 579 580 // create the index vector for a (primal values are not needed for a) 581 IssmDouble::GradientData* indexB = xNew<IssmDouble::GradientData>(n); 582 getVectorGradData(rhs, indexB, n); 583 584 dataHandler->addData(valueATrans); 585 dataHandler->addData(indexATrans); 586 dataHandler->addData(irnATrans); 587 dataHandler->addData(jcnATrans); 588 dataHandler->addData(indexB); 589 } 590 591 // unpack the primal values from the matrix and the vector 592 IssmDouble::Real* valueA = xNew<IssmDouble::Real>(local_nnz); 593 IssmDouble::Real* valueB = xNew<IssmDouble::Real>(n); 594 // read the data from A and B 595 getVectorPrimal(a_loc, valueA, local_nnz); 596 getVectorPrimal(rhs, valueB, n); 597 598 MumpsSolve(n, nnz, local_nnz, irn_loc, jcn_loc, valueA, valueB, parameters); 599 // valueB contains now the solution 600 601 // pack the values into rhs 602 setVectorPrimal(rhs, valueB, n); 603 604 if(tape.isActive()) { 605 // create the index vector X and register x as active variables 606 IssmDouble::GradientData* indexX = xNew<IssmDouble::GradientData>(n); 607 registerVector(rhs, indexX, n); 608 609 dataHandler->addData(valueB); // contains the values from x 610 dataHandler->addData(indexX); 611 612 // store other arguments 613 dataHandler->addData(n); 614 dataHandler->addData(nnz); 615 dataHandler->addData(local_nnz); 616 dataHandler->addData(parameters); // we assume here that parameters is still intact when the reverse run is called 617 618 tape.pushExternalFunction(&MumpsSolve_codi_b, dataHandler, &MumpsSolve_codi_delete); 619 } else { 620 // if the tape is active valueB is stored in the dataHandler and deleted in the reverse sweep 621 xDelete(valueB); 622 } 623 624 xDelete(valueA); 625 } 626 /*}}}*/ 627 #endif
Note:
See TracChangeset
for help on using the changeset viewer.