Reformat. Change indent to 2 spaces and line length to 80.
This commit is contained in:
parent
82824ec020
commit
6f1932cf4f
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
# BasedOnStyle: WebKit
|
# BasedOnStyle: WebKit
|
||||||
AccessModifierOffset: -4
|
AccessModifierOffset: -4
|
||||||
AlignAfterOpenBracket: DontAlign
|
AlignAfterOpenBracket: DontAlign
|
||||||
@ -29,21 +29,21 @@ AttributeMacros:
|
|||||||
BinPackArguments: false
|
BinPackArguments: false
|
||||||
BinPackParameters: false
|
BinPackParameters: false
|
||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
AfterCaseLabel: false
|
AfterCaseLabel: false
|
||||||
AfterClass: false
|
AfterClass: false
|
||||||
AfterControlStatement: Never
|
AfterControlStatement: Never
|
||||||
AfterEnum: false
|
AfterEnum: false
|
||||||
AfterFunction: true
|
AfterFunction: true
|
||||||
AfterNamespace: false
|
AfterNamespace: false
|
||||||
AfterObjCDeclaration: false
|
AfterObjCDeclaration: false
|
||||||
AfterStruct: false
|
AfterStruct: false
|
||||||
AfterUnion: false
|
AfterUnion: false
|
||||||
AfterExternBlock: false
|
AfterExternBlock: false
|
||||||
BeforeCatch: false
|
BeforeCatch: false
|
||||||
BeforeElse: false
|
BeforeElse: false
|
||||||
BeforeLambdaBody: false
|
BeforeLambdaBody: false
|
||||||
BeforeWhile: false
|
BeforeWhile: false
|
||||||
IndentBraces: false
|
IndentBraces: false
|
||||||
SplitEmptyFunction: true
|
SplitEmptyFunction: true
|
||||||
SplitEmptyRecord: true
|
SplitEmptyRecord: true
|
||||||
SplitEmptyNamespace: true
|
SplitEmptyNamespace: true
|
||||||
@ -56,19 +56,18 @@ BreakConstructorInitializersBeforeComma: false
|
|||||||
BreakConstructorInitializers: BeforeComma
|
BreakConstructorInitializers: BeforeComma
|
||||||
BreakAfterJavaFieldAnnotations: false
|
BreakAfterJavaFieldAnnotations: false
|
||||||
BreakStringLiterals: true
|
BreakStringLiterals: true
|
||||||
ColumnLimit: 90
|
ColumnLimit: 80
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
CommentPragmas: "^ IWYU pragma:"
|
||||||
CompactNamespaces: false
|
CompactNamespaces: false
|
||||||
ConstructorInitializerIndentWidth: 4
|
ConstructorInitializerIndentWidth: 4
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
Cpp11BracedListStyle: false
|
Cpp11BracedListStyle: false
|
||||||
DeriveLineEnding: true
|
DeriveLineEnding: true
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
DisableFormat: false
|
DisableFormat: false
|
||||||
EmptyLineAfterAccessModifier: Never
|
EmptyLineAfterAccessModifier: Never
|
||||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
ExperimentalAutoDetectBinPacking: false
|
ExperimentalAutoDetectBinPacking: false
|
||||||
BasedOnStyle: ''
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
AllowAllConstructorInitializersOnNextLine: true
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
FixNamespaceComments: false
|
FixNamespaceComments: false
|
||||||
@ -78,37 +77,37 @@ ForEachMacros:
|
|||||||
- BOOST_FOREACH
|
- BOOST_FOREACH
|
||||||
IfMacros:
|
IfMacros:
|
||||||
- KJ_IF_MAYBE
|
- KJ_IF_MAYBE
|
||||||
IncludeBlocks: Preserve
|
IncludeBlocks: Preserve
|
||||||
IncludeCategories:
|
IncludeCategories:
|
||||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
Priority: 2
|
Priority: 2
|
||||||
SortPriority: 0
|
SortPriority: 0
|
||||||
CaseSensitive: false
|
CaseSensitive: false
|
||||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
Priority: 3
|
Priority: 3
|
||||||
SortPriority: 0
|
SortPriority: 0
|
||||||
CaseSensitive: false
|
CaseSensitive: false
|
||||||
- Regex: '.*'
|
- Regex: ".*"
|
||||||
Priority: 1
|
Priority: 1
|
||||||
SortPriority: 0
|
SortPriority: 0
|
||||||
CaseSensitive: false
|
CaseSensitive: false
|
||||||
IncludeIsMainRegex: '(Test)?$'
|
IncludeIsMainRegex: "(Test)?$"
|
||||||
IncludeIsMainSourceRegex: ''
|
IncludeIsMainSourceRegex: ""
|
||||||
IndentAccessModifiers: false
|
IndentAccessModifiers: false
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
IndentCaseBlocks: false
|
IndentCaseBlocks: false
|
||||||
IndentGotoLabels: true
|
IndentGotoLabels: true
|
||||||
IndentPPDirectives: None
|
IndentPPDirectives: None
|
||||||
IndentExternBlock: AfterExternBlock
|
IndentExternBlock: AfterExternBlock
|
||||||
IndentWidth: 4
|
IndentWidth: 2
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
InsertTrailingCommas: None
|
InsertTrailingCommas: None
|
||||||
JavaScriptQuotes: Leave
|
JavaScriptQuotes: Leave
|
||||||
JavaScriptWrapImports: true
|
JavaScriptWrapImports: true
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
LambdaBodyIndentation: Signature
|
LambdaBodyIndentation: Signature
|
||||||
MacroBlockBegin: ''
|
MacroBlockBegin: ""
|
||||||
MacroBlockEnd: ''
|
MacroBlockEnd: ""
|
||||||
MaxEmptyLinesToKeep: 1
|
MaxEmptyLinesToKeep: 1
|
||||||
NamespaceIndentation: Inner
|
NamespaceIndentation: Inner
|
||||||
ObjCBinPackProtocolList: Auto
|
ObjCBinPackProtocolList: Auto
|
||||||
@ -126,11 +125,11 @@ PenaltyExcessCharacter: 1000000
|
|||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
PenaltyIndentedWhitespace: 0
|
PenaltyIndentedWhitespace: 0
|
||||||
PointerAlignment: Left
|
PointerAlignment: Left
|
||||||
PPIndentWidth: -1
|
PPIndentWidth: -1
|
||||||
ReferenceAlignment: Pointer
|
ReferenceAlignment: Pointer
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
ShortNamespaceLines: 1
|
ShortNamespaceLines: 1
|
||||||
SortIncludes: CaseSensitive
|
SortIncludes: CaseSensitive
|
||||||
SortJavaStaticImport: Before
|
SortJavaStaticImport: Before
|
||||||
SortUsingDeclarations: true
|
SortUsingDeclarations: true
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
@ -147,30 +146,29 @@ SpaceBeforeRangeBasedForLoopColon: true
|
|||||||
SpaceInEmptyBlock: false
|
SpaceInEmptyBlock: false
|
||||||
SpaceInEmptyParentheses: false
|
SpaceInEmptyParentheses: false
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
SpacesInAngles: Never
|
SpacesInAngles: Never
|
||||||
SpacesInConditionalStatement: false
|
SpacesInConditionalStatement: false
|
||||||
SpacesInContainerLiterals: true
|
SpacesInContainerLiterals: true
|
||||||
SpacesInCStyleCastParentheses: false
|
SpacesInCStyleCastParentheses: false
|
||||||
SpacesInLineCommentPrefix:
|
SpacesInLineCommentPrefix:
|
||||||
Minimum: 1
|
Minimum: 1
|
||||||
Maximum: -1
|
Maximum: -1
|
||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
SpaceBeforeSquareBrackets: false
|
SpaceBeforeSquareBrackets: false
|
||||||
BitFieldColonSpacing: Both
|
BitFieldColonSpacing: Both
|
||||||
Standard: Latest
|
Standard: Latest
|
||||||
StatementAttributeLikeMacros:
|
StatementAttributeLikeMacros:
|
||||||
- Q_EMIT
|
- Q_EMIT
|
||||||
StatementMacros:
|
StatementMacros:
|
||||||
- Q_UNUSED
|
- Q_UNUSED
|
||||||
- QT_REQUIRE_VERSION
|
- QT_REQUIRE_VERSION
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
UseCRLF: false
|
UseCRLF: false
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
WhitespaceSensitiveMacros:
|
WhitespaceSensitiveMacros:
|
||||||
- STRINGIZE
|
- STRINGIZE
|
||||||
- PP_STRINGIZE
|
- PP_STRINGIZE
|
||||||
- BOOST_PP_STRINGIZE
|
- BOOST_PP_STRINGIZE
|
||||||
- NS_SWIFT_NAME
|
- NS_SWIFT_NAME
|
||||||
- CF_SWIFT_NAME
|
- CF_SWIFT_NAME
|
||||||
...
|
|
||||||
|
@ -11,26 +11,26 @@
|
|||||||
|
|
||||||
void* allocate(size_t alignment, size_t bytesize)
|
void* allocate(size_t alignment, size_t bytesize)
|
||||||
{
|
{
|
||||||
int errorCode;
|
int errorCode;
|
||||||
void* ptr;
|
void* ptr;
|
||||||
|
|
||||||
errorCode = posix_memalign(&ptr, alignment, bytesize);
|
errorCode = posix_memalign(&ptr, alignment, bytesize);
|
||||||
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
if (errorCode == EINVAL) {
|
if (errorCode == EINVAL) {
|
||||||
fprintf(stderr, "Error: Alignment parameter is not a power of two\n");
|
fprintf(stderr, "Error: Alignment parameter is not a power of two\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
|
||||||
if (errorCode == ENOMEM) {
|
|
||||||
fprintf(stderr, "Error: Insufficient memory to fulfill the request\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (errorCode == ENOMEM) {
|
||||||
if (ptr == NULL) {
|
fprintf(stderr, "Error: Insufficient memory to fulfill the request\n");
|
||||||
fprintf(stderr, "Error: posix_memalign failed!\n");
|
exit(EXIT_FAILURE);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ptr;
|
if (ptr == NULL) {
|
||||||
|
fprintf(stderr, "Error: posix_memalign failed!\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
1037
src/comm.c
1037
src/comm.c
File diff suppressed because it is too large
Load Diff
26
src/comm.h
26
src/comm.h
@ -17,21 +17,21 @@
|
|||||||
enum op { MAX = 0, SUM };
|
enum op { MAX = 0, SUM };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int rank;
|
int rank;
|
||||||
int size;
|
int size;
|
||||||
#if defined(_MPI)
|
#if defined(_MPI)
|
||||||
MPI_Comm comm;
|
MPI_Comm comm;
|
||||||
|
|
||||||
int num_external;
|
int num_external;
|
||||||
int num_send_neighbors;
|
int num_send_neighbors;
|
||||||
int* external_index;
|
int* external_index;
|
||||||
int* external_local_index;
|
int* external_local_index;
|
||||||
int total_to_be_sent;
|
int total_to_be_sent;
|
||||||
int* elements_to_send;
|
int* elements_to_send;
|
||||||
int neighbors[MAX_NUM_NEIGHBOURS];
|
int neighbors[MAX_NUM_NEIGHBOURS];
|
||||||
int recv_length[MAX_NUM_NEIGHBOURS];
|
int recv_length[MAX_NUM_NEIGHBOURS];
|
||||||
int send_length[MAX_NUM_NEIGHBOURS];
|
int send_length[MAX_NUM_NEIGHBOURS];
|
||||||
double* send_buffer;
|
double* send_buffer;
|
||||||
#endif
|
#endif
|
||||||
} Comm;
|
} Comm;
|
||||||
|
|
||||||
|
144
src/main.c
144
src/main.c
@ -17,100 +17,100 @@
|
|||||||
|
|
||||||
CG_FLOAT compute_residual(Solver* s)
|
CG_FLOAT compute_residual(Solver* s)
|
||||||
{
|
{
|
||||||
CG_FLOAT residual = 0.0;
|
CG_FLOAT residual = 0.0;
|
||||||
int n = s->A.nr;
|
int n = s->A.nr;
|
||||||
CG_FLOAT* v1 = s->x;
|
CG_FLOAT* v1 = s->x;
|
||||||
CG_FLOAT* v2 = s->xexact;
|
CG_FLOAT* v2 = s->xexact;
|
||||||
|
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
double diff = fabs(v1[i] - v2[i]);
|
double diff = fabs(v1[i] - v2[i]);
|
||||||
if (diff > residual) residual = diff;
|
if (diff > residual) residual = diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
commReduction(&residual, MAX);
|
commReduction(&residual, MAX);
|
||||||
|
|
||||||
return residual;
|
return residual;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
double timeStart, timeStop;
|
double timeStart, timeStop;
|
||||||
Parameter param;
|
Parameter param;
|
||||||
Solver s;
|
Solver s;
|
||||||
Comm comm;
|
Comm comm;
|
||||||
|
|
||||||
commInit(&comm, argc, argv);
|
commInit(&comm, argc, argv);
|
||||||
initParameter(¶m);
|
initParameter(¶m);
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
if (commIsMaster(&comm)) {
|
if (commIsMaster(&comm)) {
|
||||||
printf("Usage: %s <configFile>\n", argv[0]);
|
printf("Usage: %s <configFile>\n", argv[0]);
|
||||||
}
|
|
||||||
commFinalize(&comm);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readParameter(¶m, argv[1]);
|
|
||||||
|
|
||||||
CG_FLOAT eps = (CG_FLOAT)param.eps;
|
|
||||||
int itermax = param.itermax;
|
|
||||||
initSolver(&s, &comm, ¶m);
|
|
||||||
commMatrixDump(&comm, &s.A);
|
|
||||||
commFinalize(&comm);
|
commFinalize(&comm);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
CG_UINT nrow = s.A.nr;
|
readParameter(¶m, argv[1]);
|
||||||
CG_UINT ncol = s.A.nc;
|
|
||||||
CG_FLOAT* r = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, nrow * sizeof(CG_FLOAT));
|
|
||||||
CG_FLOAT* p = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, ncol * sizeof(CG_FLOAT));
|
|
||||||
CG_FLOAT* Ap = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, nrow * sizeof(CG_FLOAT));
|
|
||||||
CG_FLOAT normr = 0.0;
|
|
||||||
CG_FLOAT rtrans = 0.0, oldrtrans;
|
|
||||||
|
|
||||||
waxpby(nrow, 1.0, s.x, 0.0, s.x, p);
|
CG_FLOAT eps = (CG_FLOAT)param.eps;
|
||||||
spMVM(&s.A, p, Ap);
|
int itermax = param.itermax;
|
||||||
waxpby(nrow, 1.0, s.b, -1.0, Ap, r);
|
initSolver(&s, &comm, ¶m);
|
||||||
|
commMatrixDump(&comm, &s.A);
|
||||||
|
commFinalize(&comm);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
|
CG_UINT nrow = s.A.nr;
|
||||||
|
CG_UINT ncol = s.A.nc;
|
||||||
|
CG_FLOAT* r = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, nrow * sizeof(CG_FLOAT));
|
||||||
|
CG_FLOAT* p = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, ncol * sizeof(CG_FLOAT));
|
||||||
|
CG_FLOAT* Ap = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, nrow * sizeof(CG_FLOAT));
|
||||||
|
CG_FLOAT normr = 0.0;
|
||||||
|
CG_FLOAT rtrans = 0.0, oldrtrans;
|
||||||
|
|
||||||
|
waxpby(nrow, 1.0, s.x, 0.0, s.x, p);
|
||||||
|
spMVM(&s.A, p, Ap);
|
||||||
|
waxpby(nrow, 1.0, s.b, -1.0, Ap, r);
|
||||||
|
ddot(nrow, r, r, &rtrans);
|
||||||
|
|
||||||
|
normr = sqrt(rtrans);
|
||||||
|
|
||||||
|
// initial iteration
|
||||||
|
waxpby(nrow, 1.0, r, 0.0, r, p);
|
||||||
|
|
||||||
|
commExchange(&comm, &s.A, p);
|
||||||
|
spMVM(&s.A, p, Ap);
|
||||||
|
double alpha = 0.0;
|
||||||
|
ddot(nrow, p, Ap, &alpha);
|
||||||
|
alpha = rtrans / alpha;
|
||||||
|
waxpby(nrow, 1.0, s.x, alpha, p, s.x);
|
||||||
|
waxpby(nrow, 1.0, r, -alpha, Ap, r);
|
||||||
|
|
||||||
|
int k;
|
||||||
|
timeStart = getTimeStamp();
|
||||||
|
for (k = 1; k < itermax && normr > eps; k++) {
|
||||||
|
oldrtrans = rtrans;
|
||||||
ddot(nrow, r, r, &rtrans);
|
ddot(nrow, r, r, &rtrans);
|
||||||
|
double beta = rtrans / oldrtrans;
|
||||||
normr = sqrt(rtrans);
|
waxpby(nrow, 1.0, r, beta, p, p);
|
||||||
|
|
||||||
// initial iteration
|
|
||||||
waxpby(nrow, 1.0, r, 0.0, r, p);
|
|
||||||
|
|
||||||
commExchange(&comm, &s.A, p);
|
commExchange(&comm, &s.A, p);
|
||||||
spMVM(&s.A, p, Ap);
|
spMVM(&s.A, p, Ap);
|
||||||
double alpha = 0.0;
|
alpha = 0.0;
|
||||||
ddot(nrow, p, Ap, &alpha);
|
ddot(nrow, p, Ap, &alpha);
|
||||||
alpha = rtrans / alpha;
|
alpha = rtrans / alpha;
|
||||||
waxpby(nrow, 1.0, s.x, alpha, p, s.x);
|
waxpby(nrow, 1.0, s.x, alpha, p, s.x);
|
||||||
waxpby(nrow, 1.0, r, -alpha, Ap, r);
|
waxpby(nrow, 1.0, r, -alpha, Ap, r);
|
||||||
|
}
|
||||||
|
timeStop = getTimeStamp();
|
||||||
|
|
||||||
int k;
|
double residual = compute_residual(&s);
|
||||||
timeStart = getTimeStamp();
|
|
||||||
for (k = 1; k < itermax && normr > eps; k++) {
|
|
||||||
oldrtrans = rtrans;
|
|
||||||
ddot(nrow, r, r, &rtrans);
|
|
||||||
double beta = rtrans / oldrtrans;
|
|
||||||
waxpby(nrow, 1.0, r, beta, p, p);
|
|
||||||
commExchange(&comm, &s.A, p);
|
|
||||||
spMVM(&s.A, p, Ap);
|
|
||||||
alpha = 0.0;
|
|
||||||
ddot(nrow, p, Ap, &alpha);
|
|
||||||
alpha = rtrans / alpha;
|
|
||||||
waxpby(nrow, 1.0, s.x, alpha, p, s.x);
|
|
||||||
waxpby(nrow, 1.0, r, -alpha, Ap, r);
|
|
||||||
}
|
|
||||||
timeStop = getTimeStamp();
|
|
||||||
|
|
||||||
double residual = compute_residual(&s);
|
if (commIsMaster(&comm)) {
|
||||||
|
printf("Solution performed %d iterations and took %.2fs\n",
|
||||||
|
k,
|
||||||
|
timeStop - timeStart);
|
||||||
|
printf("Difference between computed and exact = %f\n", residual);
|
||||||
|
}
|
||||||
|
|
||||||
if (commIsMaster(&comm)) {
|
commFinalize(&comm);
|
||||||
printf("Solution performed %d iterations and took %.2fs\n",
|
return EXIT_SUCCESS;
|
||||||
k,
|
|
||||||
timeStop - timeStart);
|
|
||||||
printf("Difference between computed and exact = %f\n", residual);
|
|
||||||
}
|
|
||||||
|
|
||||||
commFinalize(&comm);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
222
src/matrix.c
222
src/matrix.c
@ -15,154 +15,156 @@
|
|||||||
|
|
||||||
static inline int compareColumn(const void* a, const void* b)
|
static inline int compareColumn(const void* a, const void* b)
|
||||||
{
|
{
|
||||||
const Entry* a_ = (const Entry*)a;
|
const Entry* a_ = (const Entry*)a;
|
||||||
const Entry* b_ = (const Entry*)b;
|
const Entry* b_ = (const Entry*)b;
|
||||||
|
|
||||||
return (a_->col > b_->col) - (a_->col < b_->col);
|
return (a_->col > b_->col) - (a_->col < b_->col);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int compareRow(const void* a, const void* b)
|
static inline int compareRow(const void* a, const void* b)
|
||||||
{
|
{
|
||||||
const Entry* a_ = (const Entry*)a;
|
const Entry* a_ = (const Entry*)a;
|
||||||
const Entry* b_ = (const Entry*)b;
|
const Entry* b_ = (const Entry*)b;
|
||||||
|
|
||||||
return (a_->row > b_->row) - (a_->row < b_->row);
|
return (a_->row > b_->row) - (a_->row < b_->row);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dumpMMMatrix(Entry* mm, int nz)
|
static void dumpMMMatrix(Entry* mm, int nz)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < nz; i++) {
|
for (int i = 0; i < nz; i++) {
|
||||||
printf("%d %d: %f\n", mm[i].row, mm[i].col, mm[i].val);
|
printf("%d %d: %f\n", mm[i].row, mm[i].col, mm[i].val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void matrixRead(Matrix* m, char* filename)
|
void matrixRead(Matrix* m, char* filename)
|
||||||
{
|
{
|
||||||
MM_typecode matcode;
|
MM_typecode matcode;
|
||||||
FILE* f;
|
FILE* f;
|
||||||
int M, N, nz;
|
int M, N, nz;
|
||||||
|
|
||||||
if ((f = fopen(filename, "r")) == NULL) {
|
if ((f = fopen(filename, "r")) == NULL) {
|
||||||
printf("Unable to open file");
|
printf("Unable to open file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mm_read_banner(f, &matcode) != 0) {
|
||||||
|
printf("Could not process Matrix Market banner.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!((mm_is_real(matcode) || mm_is_pattern(matcode) ||
|
||||||
|
mm_is_integer(matcode)) &&
|
||||||
|
mm_is_matrix(matcode) && mm_is_sparse(matcode))) {
|
||||||
|
fprintf(stderr, "Sorry, this application does not support ");
|
||||||
|
fprintf(stderr, "Market Market type: [%s]\n", mm_typecode_to_str(matcode));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compatible_flag = (mm_is_sparse(matcode) &&
|
||||||
|
(mm_is_real(matcode) || mm_is_pattern(matcode) ||
|
||||||
|
mm_is_integer(matcode))) &&
|
||||||
|
(mm_is_symmetric(matcode) || mm_is_general(matcode));
|
||||||
|
bool sym_flag = mm_is_symmetric(matcode);
|
||||||
|
bool pattern_flag = mm_is_pattern(matcode);
|
||||||
|
bool complex_flag = mm_is_complex(matcode);
|
||||||
|
|
||||||
|
if (!compatible_flag) {
|
||||||
|
printf("The matrix market file provided is not supported.\n Reason :\n");
|
||||||
|
if (!mm_is_sparse(matcode)) {
|
||||||
|
printf(" * matrix has to be sparse\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mm_read_banner(f, &matcode) != 0) {
|
if (!mm_is_real(matcode) && !(mm_is_pattern(matcode))) {
|
||||||
printf("Could not process Matrix Market banner.\n");
|
printf(" * matrix has to be real or pattern\n");
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!((mm_is_real(matcode) || mm_is_pattern(matcode) || mm_is_integer(matcode)) &&
|
if (!mm_is_symmetric(matcode) && !mm_is_general(matcode)) {
|
||||||
mm_is_matrix(matcode) && mm_is_sparse(matcode))) {
|
printf(" * matrix has to be either general or symmetric\n");
|
||||||
fprintf(stderr, "Sorry, this application does not support ");
|
|
||||||
fprintf(stderr, "Market Market type: [%s]\n", mm_typecode_to_str(matcode));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compatible_flag = (mm_is_sparse(matcode) &&
|
exit(EXIT_FAILURE);
|
||||||
(mm_is_real(matcode) || mm_is_pattern(matcode) ||
|
}
|
||||||
mm_is_integer(matcode))) &&
|
|
||||||
(mm_is_symmetric(matcode) || mm_is_general(matcode));
|
|
||||||
bool sym_flag = mm_is_symmetric(matcode);
|
|
||||||
bool pattern_flag = mm_is_pattern(matcode);
|
|
||||||
bool complex_flag = mm_is_complex(matcode);
|
|
||||||
|
|
||||||
if (!compatible_flag) {
|
if (mm_read_mtx_crd_size(f, &M, &N, &nz) != 0) {
|
||||||
printf("The matrix market file provided is not supported.\n Reason :\n");
|
exit(EXIT_FAILURE);
|
||||||
if (!mm_is_sparse(matcode)) {
|
}
|
||||||
printf(" * matrix has to be sparse\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mm_is_real(matcode) && !(mm_is_pattern(matcode))) {
|
printf("Read matrix %s with %d non zeroes and %d rows\n", filename, nz, M);
|
||||||
printf(" * matrix has to be real or pattern\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mm_is_symmetric(matcode) && !mm_is_general(matcode)) {
|
m->nr = M;
|
||||||
printf(" * matrix has to be either general or symmetric\n");
|
m->nnz = nz;
|
||||||
}
|
Entry* mm;
|
||||||
|
|
||||||
exit(EXIT_FAILURE);
|
if (sym_flag) {
|
||||||
}
|
mm = (Entry*)allocate(ARRAY_ALIGNMENT, nz * 2 * sizeof(Entry));
|
||||||
|
} else {
|
||||||
|
mm = (Entry*)allocate(ARRAY_ALIGNMENT, nz * sizeof(Entry));
|
||||||
|
}
|
||||||
|
|
||||||
if (mm_read_mtx_crd_size(f, &M, &N, &nz) != 0) {
|
size_t cursor = 0;
|
||||||
exit(EXIT_FAILURE);
|
int row, col;
|
||||||
}
|
double v;
|
||||||
|
|
||||||
printf("Read matrix %s with %d non zeroes and %d rows\n", filename, nz, M);
|
for (size_t i = 0; i < nz; i++) {
|
||||||
|
|
||||||
m->nr = M;
|
if (pattern_flag) {
|
||||||
m->nnz = nz;
|
fscanf(f, "%d %d\n", &row, &col);
|
||||||
Entry* mm;
|
v = 1.;
|
||||||
|
} else if (complex_flag) {
|
||||||
if (sym_flag) {
|
fscanf(f, "%d %d %lg %*g\n", &row, &col, &v);
|
||||||
mm = (Entry*)allocate(ARRAY_ALIGNMENT, nz * 2 * sizeof(Entry));
|
|
||||||
} else {
|
} else {
|
||||||
mm = (Entry*)allocate(ARRAY_ALIGNMENT, nz * sizeof(Entry));
|
fscanf(f, "%d %d %lg\n", &row, &col, &v);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cursor = 0;
|
row--; /* adjust from 1-based to 0-based */
|
||||||
int row, col;
|
col--;
|
||||||
double v;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < nz; i++) {
|
mm[cursor].row = row;
|
||||||
|
mm[cursor].col = col;
|
||||||
|
mm[cursor++].val = v;
|
||||||
|
|
||||||
if (pattern_flag) {
|
if (sym_flag && (row != col)) {
|
||||||
fscanf(f, "%d %d\n", &row, &col);
|
mm[cursor].row = col;
|
||||||
v = 1.;
|
mm[cursor].col = row;
|
||||||
} else if (complex_flag) {
|
mm[cursor++].val = v;
|
||||||
fscanf(f, "%d %d %lg %*g\n", &row, &col, &v);
|
|
||||||
} else {
|
|
||||||
fscanf(f, "%d %d %lg\n", &row, &col, &v);
|
|
||||||
}
|
|
||||||
|
|
||||||
row--; /* adjust from 1-based to 0-based */
|
|
||||||
col--;
|
|
||||||
|
|
||||||
mm[cursor].row = row;
|
|
||||||
mm[cursor].col = col;
|
|
||||||
mm[cursor++].val = v;
|
|
||||||
|
|
||||||
if (sym_flag && (row != col)) {
|
|
||||||
mm[cursor].row = col;
|
|
||||||
mm[cursor].col = row;
|
|
||||||
mm[cursor++].val = v;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
size_t mms = cursor;
|
size_t mms = cursor;
|
||||||
|
|
||||||
// sort by column
|
// sort by column
|
||||||
qsort(mm, mms, sizeof(Entry), compareColumn);
|
qsort(mm, mms, sizeof(Entry), compareColumn);
|
||||||
// dumpMMMatrix(mm, nz);
|
// dumpMMMatrix(mm, nz);
|
||||||
// sort by row
|
// sort by row
|
||||||
mergesort(mm, mms, sizeof(Entry), compareRow);
|
mergesort(mm, mms, sizeof(Entry), compareRow);
|
||||||
// dumpMMMatrix(mm, nz);
|
// dumpMMMatrix(mm, nz);
|
||||||
|
|
||||||
m->rowPtr = (CG_UINT*)allocate(ARRAY_ALIGNMENT, (m->nr + 1) * sizeof(CG_UINT));
|
m->rowPtr = (CG_UINT*)allocate(ARRAY_ALIGNMENT,
|
||||||
m->colInd = (CG_UINT*)allocate(ARRAY_ALIGNMENT, m->nnz * sizeof(CG_UINT));
|
(m->nr + 1) * sizeof(CG_UINT));
|
||||||
m->val = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, m->nnz * sizeof(CG_FLOAT));
|
m->colInd = (CG_UINT*)allocate(ARRAY_ALIGNMENT, m->nnz * sizeof(CG_UINT));
|
||||||
|
m->val = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, m->nnz * sizeof(CG_FLOAT));
|
||||||
|
|
||||||
int* valsPerRow = (int*)allocate(ARRAY_ALIGNMENT, m->nr * sizeof(int));
|
int* valsPerRow = (int*)allocate(ARRAY_ALIGNMENT, m->nr * sizeof(int));
|
||||||
|
|
||||||
for (int i = 0; i < m->nr; i++) {
|
for (int i = 0; i < m->nr; i++) {
|
||||||
valsPerRow[i] = 0;
|
valsPerRow[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mms; i++) {
|
for (int i = 0; i < mms; i++) {
|
||||||
valsPerRow[mm[i].row]++;
|
valsPerRow[mm[i].row]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->rowPtr[0] = 0;
|
m->rowPtr[0] = 0;
|
||||||
|
|
||||||
// convert to CRS format
|
// convert to CRS format
|
||||||
for (int rowID = 0; rowID < m->nr; rowID++) {
|
for (int rowID = 0; rowID < m->nr; rowID++) {
|
||||||
|
|
||||||
m->rowPtr[rowID + 1] = m->rowPtr[rowID] + valsPerRow[rowID];
|
m->rowPtr[rowID + 1] = m->rowPtr[rowID] + valsPerRow[rowID];
|
||||||
|
|
||||||
// loop over all elements in Row
|
// loop over all elements in Row
|
||||||
for (int id = m->rowPtr[rowID]; id < m->rowPtr[rowID + 1]; id++) {
|
for (int id = m->rowPtr[rowID]; id < m->rowPtr[rowID + 1]; id++) {
|
||||||
m->val[id] = (CG_FLOAT)mm[id].val;
|
m->val[id] = (CG_FLOAT)mm[id].val;
|
||||||
m->colInd[id] = (CG_UINT)mm[id].col;
|
m->colInd[id] = (CG_UINT)mm[id].col;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
16
src/matrix.h
16
src/matrix.h
@ -9,17 +9,17 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int row;
|
int row;
|
||||||
int col;
|
int col;
|
||||||
double val;
|
double val;
|
||||||
} Entry;
|
} Entry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CG_UINT nr, nc, nnz; // number of rows, columns and non zeros
|
CG_UINT nr, nc, nnz; // number of rows, columns and non zeros
|
||||||
CG_UINT totalNr, totalNnz; // number of rows and non zeros
|
CG_UINT totalNr, totalNnz; // number of rows and non zeros
|
||||||
CG_UINT startRow, stopRow;
|
CG_UINT startRow, stopRow;
|
||||||
CG_UINT *colInd, *rowPtr; // colum Indices, row Pointer
|
CG_UINT *colInd, *rowPtr; // colum Indices, row Pointer
|
||||||
CG_FLOAT* val;
|
CG_FLOAT* val;
|
||||||
} Matrix;
|
} Matrix;
|
||||||
|
|
||||||
extern void matrixRead(Matrix* m, char* filename);
|
extern void matrixRead(Matrix* m, char* filename);
|
||||||
|
573
src/mmio.c
573
src/mmio.c
@ -11,206 +11,220 @@
|
|||||||
|
|
||||||
#include "mmio.h"
|
#include "mmio.h"
|
||||||
|
|
||||||
int mm_read_unsymmetric_sparse(
|
int mm_read_unsymmetric_sparse(const char* fname,
|
||||||
const char* fname, int* M_, int* N_, int* nz_, double** val_, int** I_, int** J_)
|
int* M_,
|
||||||
|
int* N_,
|
||||||
|
int* nz_,
|
||||||
|
double** val_,
|
||||||
|
int** I_,
|
||||||
|
int** J_)
|
||||||
{
|
{
|
||||||
FILE* f;
|
FILE* f;
|
||||||
MM_typecode matcode;
|
MM_typecode matcode;
|
||||||
int M, N, nz;
|
int M, N, nz;
|
||||||
int i;
|
int i;
|
||||||
double* val;
|
double* val;
|
||||||
int *I, *J;
|
int *I, *J;
|
||||||
|
|
||||||
if ((f = fopen(fname, "r")) == NULL) return -1;
|
if ((f = fopen(fname, "r")) == NULL) return -1;
|
||||||
|
|
||||||
if (mm_read_banner(f, &matcode) != 0) {
|
if (mm_read_banner(f, &matcode) != 0) {
|
||||||
printf("mm_read_unsymetric: Could not process Matrix Market banner ");
|
printf("mm_read_unsymetric: Could not process Matrix Market banner ");
|
||||||
printf(" in file [%s]\n", fname);
|
printf(" in file [%s]\n", fname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(mm_is_real(matcode) && mm_is_matrix(matcode) && mm_is_sparse(matcode))) {
|
if (!(mm_is_real(matcode) && mm_is_matrix(matcode) &&
|
||||||
fprintf(stderr, "Sorry, this application does not support ");
|
mm_is_sparse(matcode))) {
|
||||||
fprintf(stderr, "Market Market type: [%s]\n", mm_typecode_to_str(matcode));
|
fprintf(stderr, "Sorry, this application does not support ");
|
||||||
return -1;
|
fprintf(stderr, "Market Market type: [%s]\n", mm_typecode_to_str(matcode));
|
||||||
}
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* find out size of sparse matrix: M, N, nz .... */
|
/* find out size of sparse matrix: M, N, nz .... */
|
||||||
|
|
||||||
if (mm_read_mtx_crd_size(f, &M, &N, &nz) != 0) {
|
if (mm_read_mtx_crd_size(f, &M, &N, &nz) != 0) {
|
||||||
fprintf(stderr, "read_unsymmetric_sparse(): could not parse matrix size.\n");
|
fprintf(stderr,
|
||||||
return -1;
|
"read_unsymmetric_sparse(): could not parse matrix size.\n");
|
||||||
}
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
*M_ = M;
|
*M_ = M;
|
||||||
*N_ = N;
|
*N_ = N;
|
||||||
*nz_ = nz;
|
*nz_ = nz;
|
||||||
|
|
||||||
/* reseve memory for matrices */
|
/* reseve memory for matrices */
|
||||||
|
|
||||||
I = (int*)malloc(nz * sizeof(int));
|
I = (int*)malloc(nz * sizeof(int));
|
||||||
J = (int*)malloc(nz * sizeof(int));
|
J = (int*)malloc(nz * sizeof(int));
|
||||||
val = (double*)malloc(nz * sizeof(double));
|
val = (double*)malloc(nz * sizeof(double));
|
||||||
|
|
||||||
*val_ = val;
|
*val_ = val;
|
||||||
*I_ = I;
|
*I_ = I;
|
||||||
*J_ = J;
|
*J_ = J;
|
||||||
|
|
||||||
/* NOTE: when reading in doubles, ANSI C requires the use of the "l" */
|
/* NOTE: when reading in doubles, ANSI C requires the use of the "l" */
|
||||||
/* specifier as in "%lg", "%lf", "%le", otherwise errors will occur */
|
/* specifier as in "%lg", "%lf", "%le", otherwise errors will occur */
|
||||||
/* (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15) */
|
/* (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15) */
|
||||||
|
|
||||||
for (i = 0; i < nz; i++) {
|
for (i = 0; i < nz; i++) {
|
||||||
fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]);
|
fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]);
|
||||||
I[i]--; /* adjust from 1-based to 0-based */
|
I[i]--; /* adjust from 1-based to 0-based */
|
||||||
J[i]--;
|
J[i]--;
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_is_valid(MM_typecode matcode)
|
int mm_is_valid(MM_typecode matcode)
|
||||||
{
|
{
|
||||||
if (!mm_is_matrix(matcode)) return 0;
|
if (!mm_is_matrix(matcode)) return 0;
|
||||||
if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0;
|
if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0;
|
||||||
if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0;
|
if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0;
|
||||||
if (mm_is_pattern(matcode) && (mm_is_hermitian(matcode) || mm_is_skew(matcode)))
|
if (mm_is_pattern(matcode) &&
|
||||||
return 0;
|
(mm_is_hermitian(matcode) || mm_is_skew(matcode)))
|
||||||
return 1;
|
return 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_read_banner(FILE* f, MM_typecode* matcode)
|
int mm_read_banner(FILE* f, MM_typecode* matcode)
|
||||||
{
|
{
|
||||||
char line[MM_MAX_LINE_LENGTH];
|
char line[MM_MAX_LINE_LENGTH];
|
||||||
char banner[MM_MAX_TOKEN_LENGTH];
|
char banner[MM_MAX_TOKEN_LENGTH];
|
||||||
char mtx[MM_MAX_TOKEN_LENGTH];
|
char mtx[MM_MAX_TOKEN_LENGTH];
|
||||||
char crd[MM_MAX_TOKEN_LENGTH];
|
char crd[MM_MAX_TOKEN_LENGTH];
|
||||||
char data_type[MM_MAX_TOKEN_LENGTH];
|
char data_type[MM_MAX_TOKEN_LENGTH];
|
||||||
char storage_scheme[MM_MAX_TOKEN_LENGTH];
|
char storage_scheme[MM_MAX_TOKEN_LENGTH];
|
||||||
char* p;
|
char* p;
|
||||||
|
|
||||||
mm_clear_typecode(matcode);
|
mm_clear_typecode(matcode);
|
||||||
|
|
||||||
if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL) return MM_PREMATURE_EOF;
|
if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL) return MM_PREMATURE_EOF;
|
||||||
|
|
||||||
if (sscanf(line, "%s %s %s %s %s", banner, mtx, crd, data_type, storage_scheme) != 5)
|
if (sscanf(line,
|
||||||
return MM_PREMATURE_EOF;
|
"%s %s %s %s %s",
|
||||||
|
banner,
|
||||||
|
mtx,
|
||||||
|
crd,
|
||||||
|
data_type,
|
||||||
|
storage_scheme) != 5)
|
||||||
|
return MM_PREMATURE_EOF;
|
||||||
|
|
||||||
for (p = mtx; *p != '\0'; *p = tolower(*p), p++)
|
for (p = mtx; *p != '\0'; *p = tolower(*p), p++)
|
||||||
; /* convert to lower case */
|
; /* convert to lower case */
|
||||||
for (p = crd; *p != '\0'; *p = tolower(*p), p++)
|
for (p = crd; *p != '\0'; *p = tolower(*p), p++)
|
||||||
;
|
;
|
||||||
for (p = data_type; *p != '\0'; *p = tolower(*p), p++)
|
for (p = data_type; *p != '\0'; *p = tolower(*p), p++)
|
||||||
;
|
;
|
||||||
for (p = storage_scheme; *p != '\0'; *p = tolower(*p), p++)
|
for (p = storage_scheme; *p != '\0'; *p = tolower(*p), p++)
|
||||||
;
|
;
|
||||||
|
|
||||||
/* check for banner */
|
/* check for banner */
|
||||||
if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0)
|
if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0)
|
||||||
return MM_NO_HEADER;
|
return MM_NO_HEADER;
|
||||||
|
|
||||||
/* first field should be "mtx" */
|
/* first field should be "mtx" */
|
||||||
if (strcmp(mtx, MM_MTX_STR) != 0) return MM_UNSUPPORTED_TYPE;
|
if (strcmp(mtx, MM_MTX_STR) != 0) return MM_UNSUPPORTED_TYPE;
|
||||||
mm_set_matrix(matcode);
|
mm_set_matrix(matcode);
|
||||||
|
|
||||||
/* second field describes whether this is a sparse matrix (in coordinate
|
/* second field describes whether this is a sparse matrix (in coordinate
|
||||||
storgae) or a dense array */
|
storgae) or a dense array */
|
||||||
|
|
||||||
if (strcmp(crd, MM_SPARSE_STR) == 0) mm_set_sparse(matcode);
|
if (strcmp(crd, MM_SPARSE_STR) == 0) mm_set_sparse(matcode);
|
||||||
else if (strcmp(crd, MM_DENSE_STR) == 0)
|
else if (strcmp(crd, MM_DENSE_STR) == 0)
|
||||||
mm_set_dense(matcode);
|
mm_set_dense(matcode);
|
||||||
else
|
else
|
||||||
return MM_UNSUPPORTED_TYPE;
|
return MM_UNSUPPORTED_TYPE;
|
||||||
|
|
||||||
/* third field */
|
/* third field */
|
||||||
|
|
||||||
if (strcmp(data_type, MM_REAL_STR) == 0) mm_set_real(matcode);
|
if (strcmp(data_type, MM_REAL_STR) == 0) mm_set_real(matcode);
|
||||||
else if (strcmp(data_type, MM_COMPLEX_STR) == 0)
|
else if (strcmp(data_type, MM_COMPLEX_STR) == 0)
|
||||||
mm_set_complex(matcode);
|
mm_set_complex(matcode);
|
||||||
else if (strcmp(data_type, MM_PATTERN_STR) == 0)
|
else if (strcmp(data_type, MM_PATTERN_STR) == 0)
|
||||||
mm_set_pattern(matcode);
|
mm_set_pattern(matcode);
|
||||||
else if (strcmp(data_type, MM_INT_STR) == 0)
|
else if (strcmp(data_type, MM_INT_STR) == 0)
|
||||||
mm_set_integer(matcode);
|
mm_set_integer(matcode);
|
||||||
else
|
else
|
||||||
return MM_UNSUPPORTED_TYPE;
|
return MM_UNSUPPORTED_TYPE;
|
||||||
|
|
||||||
/* fourth field */
|
/* fourth field */
|
||||||
|
|
||||||
if (strcmp(storage_scheme, MM_GENERAL_STR) == 0) mm_set_general(matcode);
|
if (strcmp(storage_scheme, MM_GENERAL_STR) == 0) mm_set_general(matcode);
|
||||||
else if (strcmp(storage_scheme, MM_SYMM_STR) == 0)
|
else if (strcmp(storage_scheme, MM_SYMM_STR) == 0)
|
||||||
mm_set_symmetric(matcode);
|
mm_set_symmetric(matcode);
|
||||||
else if (strcmp(storage_scheme, MM_HERM_STR) == 0)
|
else if (strcmp(storage_scheme, MM_HERM_STR) == 0)
|
||||||
mm_set_hermitian(matcode);
|
mm_set_hermitian(matcode);
|
||||||
else if (strcmp(storage_scheme, MM_SKEW_STR) == 0)
|
else if (strcmp(storage_scheme, MM_SKEW_STR) == 0)
|
||||||
mm_set_skew(matcode);
|
mm_set_skew(matcode);
|
||||||
else
|
else
|
||||||
return MM_UNSUPPORTED_TYPE;
|
return MM_UNSUPPORTED_TYPE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_write_mtx_crd_size(FILE* f, int M, int N, int nz)
|
int mm_write_mtx_crd_size(FILE* f, int M, int N, int nz)
|
||||||
{
|
{
|
||||||
if (fprintf(f, "%d %d %d\n", M, N, nz) != 3) return MM_COULD_NOT_WRITE_FILE;
|
if (fprintf(f, "%d %d %d\n", M, N, nz) != 3) return MM_COULD_NOT_WRITE_FILE;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_read_mtx_crd_size(FILE* f, int* M, int* N, int* nz)
|
int mm_read_mtx_crd_size(FILE* f, int* M, int* N, int* nz)
|
||||||
{
|
{
|
||||||
char line[MM_MAX_LINE_LENGTH];
|
char line[MM_MAX_LINE_LENGTH];
|
||||||
int num_items_read;
|
int num_items_read;
|
||||||
|
|
||||||
/* set return null parameter values, in case we exit with errors */
|
/* set return null parameter values, in case we exit with errors */
|
||||||
*M = *N = *nz = 0;
|
*M = *N = *nz = 0;
|
||||||
|
|
||||||
/* now continue scanning until you reach the end-of-comments */
|
/* now continue scanning until you reach the end-of-comments */
|
||||||
|
do {
|
||||||
|
if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL) return MM_PREMATURE_EOF;
|
||||||
|
} while (line[0] == '%');
|
||||||
|
|
||||||
|
/* line[] is either blank or has M,N, nz */
|
||||||
|
if (sscanf(line, "%d %d %d", M, N, nz) == 3) return 0;
|
||||||
|
|
||||||
|
else
|
||||||
do {
|
do {
|
||||||
if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL) return MM_PREMATURE_EOF;
|
num_items_read = fscanf(f, "%d %d %d", M, N, nz);
|
||||||
} while (line[0] == '%');
|
if (num_items_read == EOF) return MM_PREMATURE_EOF;
|
||||||
|
} while (num_items_read != 3);
|
||||||
|
|
||||||
/* line[] is either blank or has M,N, nz */
|
return 0;
|
||||||
if (sscanf(line, "%d %d %d", M, N, nz) == 3) return 0;
|
|
||||||
|
|
||||||
else
|
|
||||||
do {
|
|
||||||
num_items_read = fscanf(f, "%d %d %d", M, N, nz);
|
|
||||||
if (num_items_read == EOF) return MM_PREMATURE_EOF;
|
|
||||||
} while (num_items_read != 3);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_read_mtx_array_size(FILE* f, int* M, int* N)
|
int mm_read_mtx_array_size(FILE* f, int* M, int* N)
|
||||||
{
|
{
|
||||||
char line[MM_MAX_LINE_LENGTH];
|
char line[MM_MAX_LINE_LENGTH];
|
||||||
int num_items_read;
|
int num_items_read;
|
||||||
/* set return null parameter values, in case we exit with errors */
|
/* set return null parameter values, in case we exit with errors */
|
||||||
*M = *N = 0;
|
*M = *N = 0;
|
||||||
|
|
||||||
/* now continue scanning until you reach the end-of-comments */
|
/* now continue scanning until you reach the end-of-comments */
|
||||||
|
do {
|
||||||
|
if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL) return MM_PREMATURE_EOF;
|
||||||
|
} while (line[0] == '%');
|
||||||
|
|
||||||
|
/* line[] is either blank or has M,N, nz */
|
||||||
|
if (sscanf(line, "%d %d", M, N) == 2) return 0;
|
||||||
|
|
||||||
|
else /* we have a blank line */
|
||||||
do {
|
do {
|
||||||
if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL) return MM_PREMATURE_EOF;
|
num_items_read = fscanf(f, "%d %d", M, N);
|
||||||
} while (line[0] == '%');
|
if (num_items_read == EOF) return MM_PREMATURE_EOF;
|
||||||
|
} while (num_items_read != 2);
|
||||||
|
|
||||||
/* line[] is either blank or has M,N, nz */
|
return 0;
|
||||||
if (sscanf(line, "%d %d", M, N) == 2) return 0;
|
|
||||||
|
|
||||||
else /* we have a blank line */
|
|
||||||
do {
|
|
||||||
num_items_read = fscanf(f, "%d %d", M, N);
|
|
||||||
if (num_items_read == EOF) return MM_PREMATURE_EOF;
|
|
||||||
} while (num_items_read != 2);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_write_mtx_array_size(FILE* f, int M, int N)
|
int mm_write_mtx_array_size(FILE* f, int M, int N)
|
||||||
{
|
{
|
||||||
if (fprintf(f, "%d %d\n", M, N) != 2) return MM_COULD_NOT_WRITE_FILE;
|
if (fprintf(f, "%d %d\n", M, N) != 2) return MM_COULD_NOT_WRITE_FILE;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -219,47 +233,58 @@ int mm_write_mtx_array_size(FILE* f, int M, int N)
|
|||||||
/* use when I[], J[], and val[]J, and val[] are already allocated */
|
/* use when I[], J[], and val[]J, and val[] are already allocated */
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
||||||
int mm_read_mtx_crd_data(
|
int mm_read_mtx_crd_data(FILE* f,
|
||||||
FILE* f, int M, int N, int nz, int I[], int J[], double val[], MM_typecode matcode)
|
int M,
|
||||||
|
int N,
|
||||||
|
int nz,
|
||||||
|
int I[],
|
||||||
|
int J[],
|
||||||
|
double val[],
|
||||||
|
MM_typecode matcode)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (mm_is_complex(matcode)) {
|
if (mm_is_complex(matcode)) {
|
||||||
for (i = 0; i < nz; i++)
|
for (i = 0; i < nz; i++)
|
||||||
if (fscanf(f, "%d %d %lg %lg", &I[i], &J[i], &val[2 * i], &val[2 * i + 1]) !=
|
if (fscanf(f,
|
||||||
4)
|
"%d %d %lg %lg",
|
||||||
return MM_PREMATURE_EOF;
|
&I[i],
|
||||||
} else if (mm_is_real(matcode)) {
|
&J[i],
|
||||||
for (i = 0; i < nz; i++) {
|
&val[2 * i],
|
||||||
if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]) != 3)
|
&val[2 * i + 1]) != 4)
|
||||||
return MM_PREMATURE_EOF;
|
return MM_PREMATURE_EOF;
|
||||||
}
|
} else if (mm_is_real(matcode)) {
|
||||||
|
for (i = 0; i < nz; i++) {
|
||||||
|
if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]) != 3)
|
||||||
|
return MM_PREMATURE_EOF;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if (mm_is_pattern(matcode)) {
|
else if (mm_is_pattern(matcode)) {
|
||||||
for (i = 0; i < nz; i++)
|
for (i = 0; i < nz; i++)
|
||||||
if (fscanf(f, "%d %d", &I[i], &J[i]) != 2) return MM_PREMATURE_EOF;
|
if (fscanf(f, "%d %d", &I[i], &J[i]) != 2) return MM_PREMATURE_EOF;
|
||||||
} else
|
} else
|
||||||
return MM_UNSUPPORTED_TYPE;
|
return MM_UNSUPPORTED_TYPE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_read_mtx_crd_entry(
|
int mm_read_mtx_crd_entry(
|
||||||
FILE* f, int* I, int* J, double* real, double* imag, MM_typecode matcode)
|
FILE* f, int* I, int* J, double* real, double* imag, MM_typecode matcode)
|
||||||
{
|
{
|
||||||
if (mm_is_complex(matcode)) {
|
if (mm_is_complex(matcode)) {
|
||||||
if (fscanf(f, "%d %d %lg %lg", I, J, real, imag) != 4) return MM_PREMATURE_EOF;
|
if (fscanf(f, "%d %d %lg %lg", I, J, real, imag) != 4)
|
||||||
} else if (mm_is_real(matcode)) {
|
return MM_PREMATURE_EOF;
|
||||||
if (fscanf(f, "%d %d %lg\n", I, J, real) != 3) return MM_PREMATURE_EOF;
|
} else if (mm_is_real(matcode)) {
|
||||||
|
if (fscanf(f, "%d %d %lg\n", I, J, real) != 3) return MM_PREMATURE_EOF;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mm_is_pattern(matcode)) {
|
else if (mm_is_pattern(matcode)) {
|
||||||
if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF;
|
if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF;
|
||||||
} else
|
} else
|
||||||
return MM_UNSUPPORTED_TYPE;
|
return MM_UNSUPPORTED_TYPE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -279,53 +304,54 @@ int mm_read_mtx_crd(char* fname,
|
|||||||
double** val,
|
double** val,
|
||||||
MM_typecode* matcode)
|
MM_typecode* matcode)
|
||||||
{
|
{
|
||||||
int ret_code;
|
int ret_code;
|
||||||
FILE* f;
|
FILE* f;
|
||||||
|
|
||||||
if (strcmp(fname, "stdin") == 0) f = stdin;
|
if (strcmp(fname, "stdin") == 0) f = stdin;
|
||||||
else if ((f = fopen(fname, "r")) == NULL)
|
else if ((f = fopen(fname, "r")) == NULL)
|
||||||
return MM_COULD_NOT_READ_FILE;
|
return MM_COULD_NOT_READ_FILE;
|
||||||
|
|
||||||
if ((ret_code = mm_read_banner(f, matcode)) != 0) return ret_code;
|
if ((ret_code = mm_read_banner(f, matcode)) != 0) return ret_code;
|
||||||
|
|
||||||
if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) && mm_is_matrix(*matcode)))
|
if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) &&
|
||||||
return MM_UNSUPPORTED_TYPE;
|
mm_is_matrix(*matcode)))
|
||||||
|
return MM_UNSUPPORTED_TYPE;
|
||||||
|
|
||||||
if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0) return ret_code;
|
if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0) return ret_code;
|
||||||
|
|
||||||
*I = (int*)malloc(*nz * sizeof(int));
|
*I = (int*)malloc(*nz * sizeof(int));
|
||||||
*J = (int*)malloc(*nz * sizeof(int));
|
*J = (int*)malloc(*nz * sizeof(int));
|
||||||
*val = NULL;
|
*val = NULL;
|
||||||
|
|
||||||
if (mm_is_complex(*matcode)) {
|
if (mm_is_complex(*matcode)) {
|
||||||
*val = (double*)malloc(*nz * 2 * sizeof(double));
|
*val = (double*)malloc(*nz * 2 * sizeof(double));
|
||||||
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode);
|
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode);
|
||||||
if (ret_code != 0) return ret_code;
|
if (ret_code != 0) return ret_code;
|
||||||
} else if (mm_is_real(*matcode)) {
|
} else if (mm_is_real(*matcode)) {
|
||||||
*val = (double*)malloc(*nz * sizeof(double));
|
*val = (double*)malloc(*nz * sizeof(double));
|
||||||
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode);
|
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode);
|
||||||
if (ret_code != 0) return ret_code;
|
if (ret_code != 0) return ret_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mm_is_pattern(*matcode)) {
|
else if (mm_is_pattern(*matcode)) {
|
||||||
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode);
|
ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode);
|
||||||
if (ret_code != 0) return ret_code;
|
if (ret_code != 0) return ret_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f != stdin) fclose(f);
|
if (f != stdin) fclose(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_write_banner(FILE* f, MM_typecode matcode)
|
int mm_write_banner(FILE* f, MM_typecode matcode)
|
||||||
{
|
{
|
||||||
char* str = mm_typecode_to_str(matcode);
|
char* str = mm_typecode_to_str(matcode);
|
||||||
int ret_code;
|
int ret_code;
|
||||||
|
|
||||||
ret_code = fprintf(f, "%s %s\n", MatrixMarketBanner, str);
|
ret_code = fprintf(f, "%s %s\n", MatrixMarketBanner, str);
|
||||||
free(str);
|
free(str);
|
||||||
if (ret_code != 2) return MM_COULD_NOT_WRITE_FILE;
|
if (ret_code != 2) return MM_COULD_NOT_WRITE_FILE;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_write_mtx_crd(char fname[],
|
int mm_write_mtx_crd(char fname[],
|
||||||
@ -337,38 +363,43 @@ int mm_write_mtx_crd(char fname[],
|
|||||||
double val[],
|
double val[],
|
||||||
MM_typecode matcode)
|
MM_typecode matcode)
|
||||||
{
|
{
|
||||||
FILE* f;
|
FILE* f;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (strcmp(fname, "stdout") == 0) f = stdout;
|
if (strcmp(fname, "stdout") == 0) f = stdout;
|
||||||
else if ((f = fopen(fname, "w")) == NULL)
|
else if ((f = fopen(fname, "w")) == NULL)
|
||||||
return MM_COULD_NOT_WRITE_FILE;
|
return MM_COULD_NOT_WRITE_FILE;
|
||||||
|
|
||||||
/* print banner followed by typecode */
|
/* print banner followed by typecode */
|
||||||
fprintf(f, "%s ", MatrixMarketBanner);
|
fprintf(f, "%s ", MatrixMarketBanner);
|
||||||
fprintf(f, "%s\n", mm_typecode_to_str(matcode));
|
fprintf(f, "%s\n", mm_typecode_to_str(matcode));
|
||||||
|
|
||||||
/* print matrix sizes and nonzeros */
|
/* print matrix sizes and nonzeros */
|
||||||
fprintf(f, "%d %d %d\n", M, N, nz);
|
fprintf(f, "%d %d %d\n", M, N, nz);
|
||||||
|
|
||||||
/* print values */
|
|
||||||
if (mm_is_pattern(matcode))
|
|
||||||
for (i = 0; i < nz; i++)
|
|
||||||
fprintf(f, "%d %d\n", I[i], J[i]);
|
|
||||||
else if (mm_is_real(matcode))
|
|
||||||
for (i = 0; i < nz; i++)
|
|
||||||
fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]);
|
|
||||||
else if (mm_is_complex(matcode))
|
|
||||||
for (i = 0; i < nz; i++)
|
|
||||||
fprintf(f, "%d %d %20.16g %20.16g\n", I[i], J[i], val[2 * i], val[2 * i + 1]);
|
|
||||||
else {
|
|
||||||
if (f != stdout) fclose(f);
|
|
||||||
return MM_UNSUPPORTED_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* print values */
|
||||||
|
if (mm_is_pattern(matcode))
|
||||||
|
for (i = 0; i < nz; i++)
|
||||||
|
fprintf(f, "%d %d\n", I[i], J[i]);
|
||||||
|
else if (mm_is_real(matcode))
|
||||||
|
for (i = 0; i < nz; i++)
|
||||||
|
fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]);
|
||||||
|
else if (mm_is_complex(matcode))
|
||||||
|
for (i = 0; i < nz; i++)
|
||||||
|
fprintf(f,
|
||||||
|
"%d %d %20.16g %20.16g\n",
|
||||||
|
I[i],
|
||||||
|
J[i],
|
||||||
|
val[2 * i],
|
||||||
|
val[2 * i + 1]);
|
||||||
|
else {
|
||||||
if (f != stdout) fclose(f);
|
if (f != stdout) fclose(f);
|
||||||
|
return MM_UNSUPPORTED_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
if (f != stdout) fclose(f);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -378,52 +409,52 @@ int mm_write_mtx_crd(char fname[],
|
|||||||
*/
|
*/
|
||||||
char* mm_strdup(const char* s)
|
char* mm_strdup(const char* s)
|
||||||
{
|
{
|
||||||
int len = strlen(s);
|
int len = strlen(s);
|
||||||
char* s2 = (char*)malloc((len + 1) * sizeof(char));
|
char* s2 = (char*)malloc((len + 1) * sizeof(char));
|
||||||
return strcpy(s2, s);
|
return strcpy(s2, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* mm_typecode_to_str(MM_typecode matcode)
|
char* mm_typecode_to_str(MM_typecode matcode)
|
||||||
{
|
{
|
||||||
char buffer[MM_MAX_LINE_LENGTH];
|
char buffer[MM_MAX_LINE_LENGTH];
|
||||||
char* types[4];
|
char* types[4];
|
||||||
char* mm_strdup(const char*);
|
char* mm_strdup(const char*);
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
/* check for MTX type */
|
/* check for MTX type */
|
||||||
if (mm_is_matrix(matcode)) types[0] = MM_MTX_STR;
|
if (mm_is_matrix(matcode)) types[0] = MM_MTX_STR;
|
||||||
else
|
else
|
||||||
error = 1;
|
error = 1;
|
||||||
|
|
||||||
/* check for CRD or ARR matrix */
|
/* check for CRD or ARR matrix */
|
||||||
if (mm_is_sparse(matcode)) types[1] = MM_SPARSE_STR;
|
if (mm_is_sparse(matcode)) types[1] = MM_SPARSE_STR;
|
||||||
else if (mm_is_dense(matcode))
|
else if (mm_is_dense(matcode))
|
||||||
types[1] = MM_DENSE_STR;
|
types[1] = MM_DENSE_STR;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* check for element data type */
|
/* check for element data type */
|
||||||
if (mm_is_real(matcode)) types[2] = MM_REAL_STR;
|
if (mm_is_real(matcode)) types[2] = MM_REAL_STR;
|
||||||
else if (mm_is_complex(matcode))
|
else if (mm_is_complex(matcode))
|
||||||
types[2] = MM_COMPLEX_STR;
|
types[2] = MM_COMPLEX_STR;
|
||||||
else if (mm_is_pattern(matcode))
|
else if (mm_is_pattern(matcode))
|
||||||
types[2] = MM_PATTERN_STR;
|
types[2] = MM_PATTERN_STR;
|
||||||
else if (mm_is_integer(matcode))
|
else if (mm_is_integer(matcode))
|
||||||
types[2] = MM_INT_STR;
|
types[2] = MM_INT_STR;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* check for symmetry type */
|
/* check for symmetry type */
|
||||||
if (mm_is_general(matcode)) types[3] = MM_GENERAL_STR;
|
if (mm_is_general(matcode)) types[3] = MM_GENERAL_STR;
|
||||||
else if (mm_is_symmetric(matcode))
|
else if (mm_is_symmetric(matcode))
|
||||||
types[3] = MM_SYMM_STR;
|
types[3] = MM_SYMM_STR;
|
||||||
else if (mm_is_hermitian(matcode))
|
else if (mm_is_hermitian(matcode))
|
||||||
types[3] = MM_HERM_STR;
|
types[3] = MM_HERM_STR;
|
||||||
else if (mm_is_skew(matcode))
|
else if (mm_is_skew(matcode))
|
||||||
types[3] = MM_SKEW_STR;
|
types[3] = MM_SKEW_STR;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sprintf(buffer, "%s %s %s %s", types[0], types[1], types[2], types[3]);
|
sprintf(buffer, "%s %s %s %s", types[0], types[1], types[2], types[3]);
|
||||||
return mm_strdup(buffer);
|
return mm_strdup(buffer);
|
||||||
}
|
}
|
||||||
|
31
src/mmio.h
31
src/mmio.h
@ -64,8 +64,8 @@ int mm_is_valid(MM_typecode matcode); /* too complex for a macro */
|
|||||||
#define mm_set_skew(typecode) ((*typecode)[3] = 'K')
|
#define mm_set_skew(typecode) ((*typecode)[3] = 'K')
|
||||||
#define mm_set_hermitian(typecode) ((*typecode)[3] = 'H')
|
#define mm_set_hermitian(typecode) ((*typecode)[3] = 'H')
|
||||||
|
|
||||||
#define mm_clear_typecode(typecode) \
|
#define mm_clear_typecode(typecode) \
|
||||||
((*typecode)[0] = (*typecode)[1] = (*typecode)[2] = ' ', (*typecode)[3] = 'G')
|
((*typecode)[0] = (*typecode)[1] = (*typecode)[2] = ' ', (*typecode)[3] = 'G')
|
||||||
|
|
||||||
#define mm_initialize_typecode(typecode) mm_clear_typecode(typecode)
|
#define mm_initialize_typecode(typecode) mm_clear_typecode(typecode)
|
||||||
|
|
||||||
@ -83,14 +83,14 @@ int mm_is_valid(MM_typecode matcode); /* too complex for a macro */
|
|||||||
|
|
||||||
MM_matrix_typecode: 4-character sequence
|
MM_matrix_typecode: 4-character sequence
|
||||||
|
|
||||||
ojbect sparse/ data storage dense
|
ojbect sparse/ data
|
||||||
type scheme
|
storage dense type scheme
|
||||||
|
|
||||||
string position: [0] [1] [2] [3]
|
string position: [0] [1] [2] [3]
|
||||||
|
|
||||||
Matrix typecode: M(atrix) C(oord) R(eal) G(eneral)
|
Matrix typecode: M(atrix) C(oord) R(eal) G(eneral)
|
||||||
A(array) C(omplex)
|
A(array)
|
||||||
H(ermitian) P(attern) S(ymmetric) I(nteger) K(kew)
|
C(omplex) H(ermitian) P(attern) S(ymmetric) I(nteger) K(kew)
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
@ -118,12 +118,23 @@ int mm_write_mtx_crd(char fname[],
|
|||||||
int J[],
|
int J[],
|
||||||
double val[],
|
double val[],
|
||||||
MM_typecode matcode);
|
MM_typecode matcode);
|
||||||
int mm_read_mtx_crd_data(
|
int mm_read_mtx_crd_data(FILE* f,
|
||||||
FILE* f, int M, int N, int nz, int I[], int J[], double val[], MM_typecode matcode);
|
int M,
|
||||||
|
int N,
|
||||||
|
int nz,
|
||||||
|
int I[],
|
||||||
|
int J[],
|
||||||
|
double val[],
|
||||||
|
MM_typecode matcode);
|
||||||
int mm_read_mtx_crd_entry(
|
int mm_read_mtx_crd_entry(
|
||||||
FILE* f, int* I, int* J, double* real, double* img, MM_typecode matcode);
|
FILE* f, int* I, int* J, double* real, double* img, MM_typecode matcode);
|
||||||
|
|
||||||
int mm_read_unsymmetric_sparse(
|
int mm_read_unsymmetric_sparse(const char* fname,
|
||||||
const char* fname, int* M_, int* N_, int* nz_, double** val_, int** I_, int** J_);
|
int* M_,
|
||||||
|
int* N_,
|
||||||
|
int* nz_,
|
||||||
|
double** val_,
|
||||||
|
int** I_,
|
||||||
|
int** J_);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,61 +11,61 @@
|
|||||||
|
|
||||||
void initParameter(Parameter* param)
|
void initParameter(Parameter* param)
|
||||||
{
|
{
|
||||||
param->filename = "generate";
|
param->filename = "generate";
|
||||||
param->nx = 100;
|
param->nx = 100;
|
||||||
param->ny = 100;
|
param->ny = 100;
|
||||||
param->nz = 1000;
|
param->nz = 1000;
|
||||||
param->itermax = 1000;
|
param->itermax = 1000;
|
||||||
param->eps = 0.0001;
|
param->eps = 0.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
void readParameter(Parameter* param, const char* filename)
|
void readParameter(Parameter* param, const char* filename)
|
||||||
{
|
{
|
||||||
FILE* fp = fopen(filename, "r");
|
FILE* fp = fopen(filename, "r");
|
||||||
char line[MAXLINE];
|
char line[MAXLINE];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
fprintf(stderr, "Could not open parameter file: %s\n", filename);
|
fprintf(stderr, "Could not open parameter file: %s\n", filename);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!feof(fp)) {
|
while (!feof(fp)) {
|
||||||
line[0] = '\0';
|
line[0] = '\0';
|
||||||
fgets(line, MAXLINE, fp);
|
fgets(line, MAXLINE, fp);
|
||||||
for (i = 0; line[i] != '\0' && line[i] != '#'; i++)
|
for (i = 0; line[i] != '\0' && line[i] != '#'; i++)
|
||||||
;
|
;
|
||||||
line[i] = '\0';
|
line[i] = '\0';
|
||||||
|
|
||||||
char* tok = strtok(line, " ");
|
char* tok = strtok(line, " ");
|
||||||
char* val = strtok(NULL, " ");
|
char* val = strtok(NULL, " ");
|
||||||
|
|
||||||
#define PARSE_PARAM(p, f) \
|
#define PARSE_PARAM(p, f) \
|
||||||
if (strncmp(tok, #p, sizeof(#p) / sizeof(#p[0]) - 1) == 0) { \
|
if (strncmp(tok, #p, sizeof(#p) / sizeof(#p[0]) - 1) == 0) { \
|
||||||
param->p = f(val); \
|
param->p = f(val); \
|
||||||
}
|
}
|
||||||
#define PARSE_STRING(p) PARSE_PARAM(p, strdup)
|
#define PARSE_STRING(p) PARSE_PARAM(p, strdup)
|
||||||
#define PARSE_INT(p) PARSE_PARAM(p, atoi)
|
#define PARSE_INT(p) PARSE_PARAM(p, atoi)
|
||||||
#define PARSE_REAL(p) PARSE_PARAM(p, atof)
|
#define PARSE_REAL(p) PARSE_PARAM(p, atof)
|
||||||
|
|
||||||
if (tok != NULL && val != NULL) {
|
if (tok != NULL && val != NULL) {
|
||||||
PARSE_INT(nx);
|
PARSE_INT(nx);
|
||||||
PARSE_INT(ny);
|
PARSE_INT(ny);
|
||||||
PARSE_INT(nz);
|
PARSE_INT(nz);
|
||||||
PARSE_INT(itermax);
|
PARSE_INT(itermax);
|
||||||
PARSE_REAL(eps);
|
PARSE_REAL(eps);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printParameter(Parameter* param)
|
void printParameter(Parameter* param)
|
||||||
{
|
{
|
||||||
printf("Parameters\n");
|
printf("Parameters\n");
|
||||||
printf("Geometry data:\n");
|
printf("Geometry data:\n");
|
||||||
printf("\tPoints (x, y, z): %d, %d, %d\n", param->nx, param->ny, param->nz);
|
printf("\tPoints (x, y, z): %d, %d, %d\n", param->nx, param->ny, param->nz);
|
||||||
printf("Iterative solver parameters:\n");
|
printf("Iterative solver parameters:\n");
|
||||||
printf("\tMax iterations: %d\n", param->itermax);
|
printf("\tMax iterations: %d\n", param->itermax);
|
||||||
printf("\tepsilon (stopping tolerance) : %f\n", param->eps);
|
printf("\tepsilon (stopping tolerance) : %f\n", param->eps);
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
#define __PARAMETER_H_
|
#define __PARAMETER_H_
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* filename;
|
char* filename;
|
||||||
int nx, ny, nz;
|
int nx, ny, nz;
|
||||||
int itermax;
|
int itermax;
|
||||||
double eps;
|
double eps;
|
||||||
} Parameter;
|
} Parameter;
|
||||||
|
|
||||||
void initParameter(Parameter*);
|
void initParameter(Parameter*);
|
||||||
|
@ -13,36 +13,36 @@ static int _current;
|
|||||||
|
|
||||||
void initProgress(double end)
|
void initProgress(double end)
|
||||||
{
|
{
|
||||||
_end = end;
|
_end = end;
|
||||||
_current = 0;
|
_current = 0;
|
||||||
|
|
||||||
printf("[ ]");
|
printf("[ ]");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printProgress(double current)
|
void printProgress(double current)
|
||||||
{
|
{
|
||||||
int new = (int)rint((current / _end) * 10.0);
|
int new = (int)rint((current / _end) * 10.0);
|
||||||
|
|
||||||
if (new > _current) {
|
if (new > _current) {
|
||||||
char progress[11];
|
char progress[11];
|
||||||
_current = new;
|
_current = new;
|
||||||
progress[0] = 0;
|
progress[0] = 0;
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
if (i < _current) {
|
if (i < _current) {
|
||||||
sprintf(progress + strlen(progress), "#");
|
sprintf(progress + strlen(progress), "#");
|
||||||
} else {
|
} else {
|
||||||
sprintf(progress + strlen(progress), " ");
|
sprintf(progress + strlen(progress), " ");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
printf("\r[%s]", progress);
|
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
printf("\r[%s]", progress);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopProgress()
|
void stopProgress()
|
||||||
{
|
{
|
||||||
printf("\n");
|
printf("\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
256
src/solver.c
256
src/solver.c
@ -13,139 +13,143 @@
|
|||||||
#include "solver.h"
|
#include "solver.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static void matrixGenerate(Parameter* p, Solver* s, Comm* c, bool use_7pt_stencil)
|
static void matrixGenerate(
|
||||||
|
Parameter* p, Solver* s, Comm* c, bool use_7pt_stencil)
|
||||||
{
|
{
|
||||||
int size = c->size;
|
int size = c->size;
|
||||||
int rank = c->rank;
|
int rank = c->rank;
|
||||||
|
|
||||||
CG_UINT local_nrow = p->nx * p->ny * p->nz;
|
CG_UINT local_nrow = p->nx * p->ny * p->nz;
|
||||||
CG_UINT local_nnz = 27 * local_nrow;
|
CG_UINT local_nnz = 27 * local_nrow;
|
||||||
|
|
||||||
CG_UINT total_nrow = local_nrow * size;
|
CG_UINT total_nrow = local_nrow * size;
|
||||||
CG_UINT total_nnz = 27 * total_nrow;
|
CG_UINT total_nnz = 27 * total_nrow;
|
||||||
|
|
||||||
int start_row = local_nrow * rank;
|
int start_row = local_nrow * rank;
|
||||||
int stop_row = start_row + local_nrow - 1;
|
int stop_row = start_row + local_nrow - 1;
|
||||||
|
|
||||||
if (commIsMaster(c)) {
|
if (commIsMaster(c)) {
|
||||||
if (use_7pt_stencil) {
|
if (use_7pt_stencil) {
|
||||||
printf("Generate 7pt matrix with ");
|
printf("Generate 7pt matrix with ");
|
||||||
} else {
|
} else {
|
||||||
printf("Generate 27pt matrix with ");
|
printf("Generate 27pt matrix with ");
|
||||||
}
|
|
||||||
printf("%d total rows and %d nonzeros\n", (int)total_nrow, (int)local_nnz);
|
|
||||||
}
|
}
|
||||||
|
printf("%d total rows and %d nonzeros\n", (int)total_nrow, (int)local_nnz);
|
||||||
|
}
|
||||||
|
|
||||||
s->A.val = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, local_nnz * sizeof(CG_FLOAT));
|
s->A.val = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, local_nnz * sizeof(CG_FLOAT));
|
||||||
s->A.colInd = (CG_UINT*)allocate(ARRAY_ALIGNMENT, local_nnz * sizeof(CG_UINT));
|
s->A.colInd = (CG_UINT*)allocate(ARRAY_ALIGNMENT,
|
||||||
s->A.rowPtr = (CG_UINT*)allocate(ARRAY_ALIGNMENT, (local_nrow + 1) * sizeof(CG_UINT));
|
local_nnz * sizeof(CG_UINT));
|
||||||
s->x = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, local_nrow * sizeof(CG_FLOAT));
|
s->A.rowPtr = (CG_UINT*)allocate(ARRAY_ALIGNMENT,
|
||||||
s->b = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, local_nrow * sizeof(CG_FLOAT));
|
(local_nrow + 1) * sizeof(CG_UINT));
|
||||||
s->xexact = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, local_nrow * sizeof(CG_FLOAT));
|
s->x = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, local_nrow * sizeof(CG_FLOAT));
|
||||||
|
s->b = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT, local_nrow * sizeof(CG_FLOAT));
|
||||||
|
s->xexact = (CG_FLOAT*)allocate(ARRAY_ALIGNMENT,
|
||||||
|
local_nrow * sizeof(CG_FLOAT));
|
||||||
|
|
||||||
CG_FLOAT* curvalptr = s->A.val;
|
CG_FLOAT* curvalptr = s->A.val;
|
||||||
CG_UINT* curindptr = s->A.colInd;
|
CG_UINT* curindptr = s->A.colInd;
|
||||||
CG_UINT* currowptr = s->A.rowPtr;
|
CG_UINT* currowptr = s->A.rowPtr;
|
||||||
CG_FLOAT* x = s->x;
|
CG_FLOAT* x = s->x;
|
||||||
CG_FLOAT* b = s->b;
|
CG_FLOAT* b = s->b;
|
||||||
CG_FLOAT* xexact = s->xexact;
|
CG_FLOAT* xexact = s->xexact;
|
||||||
|
|
||||||
CG_UINT nnzglobal = 0;
|
CG_UINT nnzglobal = 0;
|
||||||
int nx = p->nx, ny = p->ny, nz = p->nz;
|
int nx = p->nx, ny = p->ny, nz = p->nz;
|
||||||
CG_UINT cursor = 0;
|
CG_UINT cursor = 0;
|
||||||
|
|
||||||
*currowptr++ = 0;
|
*currowptr++ = 0;
|
||||||
|
|
||||||
for (int iz = 0; iz < nz; iz++) {
|
for (int iz = 0; iz < nz; iz++) {
|
||||||
for (int iy = 0; iy < ny; iy++) {
|
for (int iy = 0; iy < ny; iy++) {
|
||||||
for (int ix = 0; ix < nx; ix++) {
|
for (int ix = 0; ix < nx; ix++) {
|
||||||
|
|
||||||
int curlocalrow = iz * nx * ny + iy * nx + ix;
|
int curlocalrow = iz * nx * ny + iy * nx + ix;
|
||||||
int currow = start_row + iz * nx * ny + iy * nx + ix;
|
int currow = start_row + iz * nx * ny + iy * nx + ix;
|
||||||
int nnzrow = 0;
|
int nnzrow = 0;
|
||||||
|
|
||||||
for (int sz = -1; sz <= 1; sz++) {
|
for (int sz = -1; sz <= 1; sz++) {
|
||||||
for (int sy = -1; sy <= 1; sy++) {
|
for (int sy = -1; sy <= 1; sy++) {
|
||||||
for (int sx = -1; sx <= 1; sx++) {
|
for (int sx = -1; sx <= 1; sx++) {
|
||||||
|
|
||||||
int curcol = currow + sz * nx * ny + sy * nx + sx;
|
int curcol = currow + sz * nx * ny + sy * nx + sx;
|
||||||
// Since we have a stack of nx by ny by nz domains
|
// Since we have a stack of nx by ny by nz domains
|
||||||
// , stacking in the z direction, we check to see
|
// , stacking in the z direction, we check to see
|
||||||
// if sx and sy are reaching outside of the domain,
|
// if sx and sy are reaching outside of the domain,
|
||||||
// while the check for the curcol being valid is
|
// while the check for the curcol being valid is
|
||||||
// sufficient to check the z values
|
// sufficient to check the z values
|
||||||
if ((ix + sx >= 0) && (ix + sx < nx) && (iy + sy >= 0) &&
|
if ((ix + sx >= 0) && (ix + sx < nx) && (iy + sy >= 0) &&
|
||||||
(iy + sy < ny) && (curcol >= 0 && curcol < total_nrow)) {
|
(iy + sy < ny) && (curcol >= 0 && curcol < total_nrow)) {
|
||||||
// This logic will skip over point that are not part of a
|
// This logic will skip over point that are not part of a
|
||||||
// 7-pt stencil
|
// 7-pt stencil
|
||||||
if (!use_7pt_stencil ||
|
if (!use_7pt_stencil || (sz * sz + sy * sy + sx * sx <= 1)) {
|
||||||
(sz * sz + sy * sy + sx * sx <= 1)) {
|
if (curcol == currow) {
|
||||||
if (curcol == currow) {
|
*curvalptr++ = 27.0;
|
||||||
*curvalptr++ = 27.0;
|
} else {
|
||||||
} else {
|
*curvalptr++ = -1.0;
|
||||||
*curvalptr++ = -1.0;
|
}
|
||||||
}
|
*curindptr++ = curcol;
|
||||||
*curindptr++ = curcol;
|
nnzrow++;
|
||||||
nnzrow++;
|
}
|
||||||
}
|
}
|
||||||
}
|
} // end sx loop
|
||||||
} // end sx loop
|
} // end sy loop
|
||||||
} // end sy loop
|
} // end sz loop
|
||||||
} // end sz loop
|
|
||||||
|
|
||||||
*currowptr = *(currowptr - 1) + nnzrow;
|
*currowptr = *(currowptr - 1) + nnzrow;
|
||||||
currowptr++;
|
currowptr++;
|
||||||
nnzglobal += nnzrow;
|
nnzglobal += nnzrow;
|
||||||
x[curlocalrow] = 0.0;
|
x[curlocalrow] = 0.0;
|
||||||
b[curlocalrow] = 27.0 - ((CG_FLOAT)(nnzrow - 1));
|
b[curlocalrow] = 27.0 - ((CG_FLOAT)(nnzrow - 1));
|
||||||
xexact[curlocalrow] = 1.0;
|
xexact[curlocalrow] = 1.0;
|
||||||
} // end ix loop
|
} // end ix loop
|
||||||
} // end iy loop
|
} // end iy loop
|
||||||
} // end iz loop
|
} // end iz loop
|
||||||
|
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
printf("Process %d of %d has %d rows\n", rank, size, local_nrow);
|
printf("Process %d of %d has %d rows\n", rank, size, local_nrow);
|
||||||
printf("Global rows %d through %d\n", start_row, stop_row);
|
printf("Global rows %d through %d\n", start_row, stop_row);
|
||||||
printf("%d nonzeros\n", start_row, stop_row);
|
printf("%d nonzeros\n", start_row, stop_row);
|
||||||
#endif /* ifdef VERBOSE */
|
#endif /* ifdef VERBOSE */
|
||||||
|
|
||||||
s->A.startRow = start_row;
|
s->A.startRow = start_row;
|
||||||
s->A.stopRow = stop_row;
|
s->A.stopRow = stop_row;
|
||||||
s->A.totalNr = total_nrow;
|
s->A.totalNr = total_nrow;
|
||||||
s->A.totalNnz = total_nnz;
|
s->A.totalNnz = total_nnz;
|
||||||
s->A.nr = local_nrow;
|
s->A.nr = local_nrow;
|
||||||
s->A.nc = local_nrow;
|
s->A.nc = local_nrow;
|
||||||
s->A.nnz = local_nnz;
|
s->A.nnz = local_nnz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initSolver(Solver* s, Comm* c, Parameter* p)
|
void initSolver(Solver* s, Comm* c, Parameter* p)
|
||||||
{
|
{
|
||||||
if (!strcmp(p->filename, "generate")) {
|
if (!strcmp(p->filename, "generate")) {
|
||||||
matrixGenerate(p, s, c, false);
|
matrixGenerate(p, s, c, false);
|
||||||
} else if (!strcmp(p->filename, "generate7P")) {
|
} else if (!strcmp(p->filename, "generate7P")) {
|
||||||
matrixGenerate(p, s, c, true);
|
matrixGenerate(p, s, c, true);
|
||||||
} else {
|
} else {
|
||||||
matrixRead(&s->A, p->filename);
|
matrixRead(&s->A, p->filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void spMVM(Matrix* m, const CG_FLOAT* restrict x, CG_FLOAT* restrict y)
|
void spMVM(Matrix* m, const CG_FLOAT* restrict x, CG_FLOAT* restrict y)
|
||||||
{
|
{
|
||||||
CG_UINT numRows = m->nr;
|
CG_UINT numRows = m->nr;
|
||||||
CG_UINT* rowPtr = m->rowPtr;
|
CG_UINT* rowPtr = m->rowPtr;
|
||||||
CG_UINT* colInd = m->colInd;
|
CG_UINT* colInd = m->colInd;
|
||||||
CG_FLOAT* val = m->val;
|
CG_FLOAT* val = m->val;
|
||||||
|
|
||||||
for (size_t rowID = 0; rowID < numRows; rowID++) {
|
for (size_t rowID = 0; rowID < numRows; rowID++) {
|
||||||
CG_FLOAT tmp = y[rowID];
|
CG_FLOAT tmp = y[rowID];
|
||||||
|
|
||||||
// loop over all elements in row
|
// loop over all elements in row
|
||||||
for (size_t rowEntry = rowPtr[rowID]; rowEntry < rowPtr[rowID + 1]; rowEntry++) {
|
for (size_t rowEntry = rowPtr[rowID]; rowEntry < rowPtr[rowID + 1];
|
||||||
tmp += val[rowEntry] * x[colInd[rowEntry]];
|
rowEntry++) {
|
||||||
}
|
tmp += val[rowEntry] * x[colInd[rowEntry]];
|
||||||
|
|
||||||
y[rowID] = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
y[rowID] = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void waxpby(const CG_UINT n,
|
void waxpby(const CG_UINT n,
|
||||||
@ -155,19 +159,19 @@ void waxpby(const CG_UINT n,
|
|||||||
const CG_FLOAT* restrict y,
|
const CG_FLOAT* restrict y,
|
||||||
CG_FLOAT* const w)
|
CG_FLOAT* const w)
|
||||||
{
|
{
|
||||||
if (alpha == 1.0) {
|
if (alpha == 1.0) {
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
w[i] = x[i] + beta * y[i];
|
w[i] = x[i] + beta * y[i];
|
||||||
}
|
|
||||||
} else if (beta == 1.0) {
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
|
||||||
w[i] = alpha * x[i] + y[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
|
||||||
w[i] = alpha * x[i] + beta * y[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if (beta == 1.0) {
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
w[i] = alpha * x[i] + y[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
w[i] = alpha * x[i] + beta * y[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ddot(const CG_UINT n,
|
void ddot(const CG_UINT n,
|
||||||
@ -175,18 +179,18 @@ void ddot(const CG_UINT n,
|
|||||||
const CG_FLOAT* restrict y,
|
const CG_FLOAT* restrict y,
|
||||||
CG_FLOAT* restrict result)
|
CG_FLOAT* restrict result)
|
||||||
{
|
{
|
||||||
CG_FLOAT sum = 0.0;
|
CG_FLOAT sum = 0.0;
|
||||||
|
|
||||||
if (y == x) {
|
if (y == x) {
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
sum += x[i] * x[i];
|
sum += x[i] * x[i];
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
|
||||||
sum += x[i] * y[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
sum += x[i] * y[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
commReduction(&sum, SUM);
|
commReduction(&sum, SUM);
|
||||||
*result = sum;
|
*result = sum;
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Matrix A;
|
Matrix A;
|
||||||
CG_FLOAT* x;
|
CG_FLOAT* x;
|
||||||
CG_FLOAT* b;
|
CG_FLOAT* b;
|
||||||
CG_FLOAT* xexact;
|
CG_FLOAT* xexact;
|
||||||
} Solver;
|
} Solver;
|
||||||
|
|
||||||
void initSolver(Solver* s, Comm* c, Parameter*);
|
void initSolver(Solver* s, Comm* c, Parameter*);
|
||||||
|
12
src/timing.c
12
src/timing.c
@ -7,14 +7,14 @@
|
|||||||
|
|
||||||
double getTimeStamp(void)
|
double getTimeStamp(void)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
return (double)ts.tv_sec + (double)ts.tv_nsec * 1.e-9;
|
return (double)ts.tv_sec + (double)ts.tv_nsec * 1.e-9;
|
||||||
}
|
}
|
||||||
|
|
||||||
double getTimeResolution(void)
|
double getTimeResolution(void)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_getres(CLOCK_MONOTONIC, &ts);
|
clock_getres(CLOCK_MONOTONIC, &ts);
|
||||||
return (double)ts.tv_sec + (double)ts.tv_nsec * 1.e-9;
|
return (double)ts.tv_sec + (double)ts.tv_nsec * 1.e-9;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user