Skip to content

Commit 5a2d39d

Browse files
authored
Add _work (#15)
* preparation * errors in the doc :/ * API change * doc
1 parent 2aea158 commit 5a2d39d

27 files changed

+1275
-1263
lines changed

docs/about.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
## Overview
66

7+
**Note:** This project is in its early stages, and the API is not yet stable and may undergo changes.
8+
79
### Motivation
810

911
Using scaLAPACK directly in C presents several challenges:
@@ -19,8 +21,6 @@ This project addresses the first two issues by providing:
1921

2022
The third issue (documentation) remains an ongoing challenge, reflecting a broader trend in netlib's projects that rely heavily on aging user guides and systematic function design.
2123

22-
**Note:** This project is in its early stages, and the API is not yet stable and may undergo changes.
23-
2424
For more information on how to use scaLAPACKe in practice, including common caveats, refer to the [Quickstart Guide](dev/quickstart.md).
2525
A more beginner-friendly introduction to (sca)LAPACK(e) is also available [here](dev/tutorial.md).
2626

docs/dev/quickstart.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ The middle-level interface requires all the headers and wrappers files provided
9696
```
9797

9898
The naming convention for this interface is as follows: take the Fortran routine name, convert it to lowercase, and prepend it with `SCALAPACKE_`.
99-
For example, the Fortran routine `PDGEMM` becomes `SCALAPACKE_pdgemm`.
99+
If the routine requires an auxiliary workspace (`WORK`, `RWORK`, `IWORK`, etc), the suffix `_work` should be added.
100+
For example, the Fortran routine [`PDGEMM`](https://netlib.org/scalapack/explore-html/d6/da2/pdgemm___8c_source.html) becomes `SCALAPACKE_pdgemm`, and [`PDSYEV`](https://netlib.org/scalapack/explore-html/d0/d1a/pdsyev_8f_source.html) becomes `SCALAPACKE_pdsyev_work`.
100101

101102
The `INFO` parameter found in the Fortran subroutine is omitted in scaLAPACKe.
102103
Instead, the `lapack_int` return value of the function is set to the value that `INFO` would have returned.

docs/dev/tutorial.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ We will therefore make two calls: one to request the ideal size, the second to a
527527
```c
528528
// request the size of `WORK` by setting `LWORK` to -1
529529
double tmpw;
530-
SCALAPACKE_pdsyev(
530+
SCALAPACKE_pdsyev_work(
531531
"N", "U", N,
532532
loc_A, 1, 1, desc_A,
533533
w,
@@ -539,14 +539,19 @@ lapack_int lwork = (lapack_int) tmpw;
539539
// compute the eigenvalues, stored in `w`
540540
double* w = calloc(N, sizeof(double ));
541541
double* work = calloc(lwork, sizeof(double ));
542-
SCALAPACKE_pdsyev(
542+
SCALAPACKE_pdsyev_work(
543543
"N", "U", N,
544544
loc_A, 1, 1, desc_A, // input matrix
545545
w,
546546
NULL, 1, 1, desc_A, // eigenvectors
547547
work, lwork);
548548
```
549549

550+
!!! info
551+
552+
The `_work` suffix indicates that the workspace should be explicitly created.
553+
In the future, there might be a version that automatically allocate and free the workspace(s), following [LAPACKe](https://netlib.org/lapack/lapacke.html).
554+
550555
### 4. Release!
551556

552557
![](https://media1.tenor.com/m/rFwzdbMTeAoAAAAd/card-captor-sakura-anime.gif)

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This project provides a set of headers and wrappers designed to facilitate the use of [ScaLAPACK](https://www.netlib.org/scalapack/) and its components, [PBLAS](https://netlib.org/scalapack/pblas_qref.html) and [BLACS](https://netlib.org/blacs/), in C.
44

5-
Like [LAPACKE](https://netlib.org/lapack/lapacke.html), they are lightweight wrappers that streamline the integration of ScaLAPACK functionalities into C applications, [in a predictable way](dev/quickstart.md).
5+
Like [LAPACKe](https://netlib.org/lapack/lapacke.html), they are lightweight wrappers that streamline the integration of ScaLAPACK functionalities into C applications, [in a predictable way](dev/quickstart.md).
66

77
Below is an example of using the wrapper to perform eigenvalue and eigenvector computations with `PDSYEV`:
88

include/pblas.h

Lines changed: 10 additions & 10 deletions
Large diffs are not rendered by default.

include/scalapack.h

Lines changed: 47 additions & 47 deletions
Large diffs are not rendered by default.

include/scalapacke.h

Lines changed: 486 additions & 486 deletions
Large diffs are not rendered by default.

include/scalapacke_pblas.h

Lines changed: 10 additions & 10 deletions
Large diffs are not rendered by default.

scalapacke_files_create/base.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
INT_TYPE = 'lapack_int'
1313
COMPLEX_TYPE = 'lapack_complex_float'
1414
COMPLEX16_TYPE = 'lapack_complex_double'
15+
LOWLEVEL_SUFFIX = '_'
16+
MIDLEVEL_WRK_SUFFIX = '_work'
17+
1518

1619
# pattern
1720
PATTERN_C_FUNC = re.compile(r'(?P<rtype>\w+) (?P<name>\w+)\((?P<params>.*)\)')
@@ -72,19 +75,31 @@ def to_complex(self):
7275

7376

7477
class Declaration:
78+
"""
79+
Store a declaration.
80+
Its arguments are all pointers.
81+
"""
82+
7583
def __init__(self, name: str, return_type: str, arguments: List[DeclArgument]):
7684
self.name = name
7785
self.return_type = return_type
7886
self.arguments = arguments
7987

80-
def to_extern_c_decl(self) -> str:
88+
self.has_work = any('WORK' in a.name for a in self.arguments)
89+
90+
def to_low_level_decl(self) -> str:
91+
"""Low-level API
92+
"""
8193
return 'extern {} {}({});'.format(
8294
self.return_type,
83-
self.name,
95+
self.name + LOWLEVEL_SUFFIX,
8496
', '.join(a.to_c_arg() for a in self.arguments)
8597
)
8698

87-
def to_aliased_decl(self) -> str:
99+
def to_mid_level_decl(self) -> str:
100+
"""Mid-level API
101+
"""
102+
88103
arguments = self.arguments
89104
return_type = self.return_type
90105

@@ -98,11 +113,13 @@ def to_aliased_decl(self) -> str:
98113
return '{} {}{}({});'.format(
99114
return_type,
100115
PREFIX,
101-
self.name[:-1],
116+
self.name + (MIDLEVEL_WRK_SUFFIX if self.has_work else ''),
102117
', '.join(a.aliase().to_c_arg() for a in arguments)
103118
)
104119

105-
def to_aliased_wrapper(self) -> str:
120+
def to_mid_level_wrapper(self) -> str:
121+
"""Mid-level API
122+
"""
106123
name = self.name
107124
has_info = False
108125
arguments = self.arguments
@@ -117,7 +134,7 @@ def to_aliased_wrapper(self) -> str:
117134
r = '{} {}{}({}) {{\n'.format(
118135
return_type,
119136
PREFIX,
120-
name[:-1],
137+
name + (MIDLEVEL_WRK_SUFFIX if self.has_work else ''),
121138
', '.join(a.aliase().to_c_arg() for a in arguments),
122139
)
123140

@@ -126,7 +143,7 @@ def to_aliased_wrapper(self) -> str:
126143

127144
r += ' {}{}({}{});\n'.format(
128145
'return ' if self.return_type != 'void' else '',
129-
name,
146+
name + LOWLEVEL_SUFFIX,
130147
', '.join('{}{}'.format('&' if x.aliasable() else '', x.name) for x in arguments),
131148
', &INFO' if has_info else ''
132149
)

scalapacke_files_create/create_cblacs.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
]
2828

2929
# pattern
30-
PATTERN_C_FUNC = re.compile(r'(?P<rtype>\w+) (?P<name>\w+)\((?P<args>.*)\)')
30+
PATTERN_C_FUNC = re.compile(r'(?P<rtype>\w+) (?P<name>\w+)_\((?P<args>.*)\)')
3131
PATTERN_C_ARG = re.compile(r'(?P<type>\w+) ?(?P<ptr>\*)? ?(?P<name>\w+)')
3232
PATTERN_ARG_DOC = re.compile(r'\s{1,3}\*\s{1,3}(?P<name>\w*)\s+\((?P<intent>.*)\)(?P<extra>.*)?')
3333

@@ -39,64 +39,64 @@ def _p(inp: str, r: int = 0) -> DeclArgument:
3939

4040
BLACS_DECLS = [
4141
# blacs*() functions do not come with a documentation, so manually handle them
42-
Declaration('blacs_abort_', 'void', [_p('{}* ConTxt'.format(INT_TYPE)), _p('{}* ErrNo'.format(INT_TYPE))]),
43-
Declaration('blacs_barrier_', 'void', [_p('{}* ConTxt'.format(INT_TYPE)), _p('char* scope')]),
44-
Declaration('blacs_exit_', 'void', [_p('{}* NotDone'.format(INT_TYPE))]),
45-
Declaration('blacs_freebuff_', 'void', [_p('{}* ConTxt'.format(INT_TYPE)), _p('{}* wait'.format(INT_TYPE))]),
46-
Declaration('blacs_get_', 'void', [
42+
Declaration('blacs_abort', 'void', [_p('{}* ConTxt'.format(INT_TYPE)), _p('{}* ErrNo'.format(INT_TYPE))]),
43+
Declaration('blacs_barrier', 'void', [_p('{}* ConTxt'.format(INT_TYPE)), _p('char* scope')]),
44+
Declaration('blacs_exit', 'void', [_p('{}* NotDone'.format(INT_TYPE))]),
45+
Declaration('blacs_freebuff', 'void', [_p('{}* ConTxt'.format(INT_TYPE)), _p('{}* wait'.format(INT_TYPE))]),
46+
Declaration('blacs_get', 'void', [
4747
_p('{}* ConTxt'.format(INT_TYPE), ),
4848
_p('{}* what'.format(INT_TYPE)),
4949
_p('{}* val'.format(INT_TYPE), 1)
5050
]),
51-
Declaration('blacs_gridexit_', 'void', [_p('{}* ConTxt'.format(INT_TYPE))]),
52-
Declaration('blacs_gridinfo_', 'void', [
51+
Declaration('blacs_gridexit', 'void', [_p('{}* ConTxt'.format(INT_TYPE))]),
52+
Declaration('blacs_gridinfo', 'void', [
5353
_p('{}* ConTxt'.format(INT_TYPE)),
5454
_p('{}* nprow'.format(INT_TYPE), 1),
5555
_p('{}* npcol'.format(INT_TYPE), 1),
5656
_p('{}* myrow'.format(INT_TYPE), 1),
5757
_p('{}* mycol'.format(INT_TYPE), 1)
5858
]),
59-
Declaration('blacs_gridinit_', 'void', [
59+
Declaration('blacs_gridinit', 'void', [
6060
_p('{}* ConTxt'.format(INT_TYPE), 1),
6161
_p('char* order'),
6262
_p('{}* nprow'.format(INT_TYPE),),
6363
_p('{}* npcol'.format(INT_TYPE)),
6464
]),
65-
Declaration('blacs_gridmap_', 'void', [
65+
Declaration('blacs_gridmap', 'void', [
6666
_p('{}* ConTxt'.format(INT_TYPE), 1),
6767
_p('{}* usermap'.format(INT_TYPE), 1),
6868
_p('{}* ldup'.format(INT_TYPE)),
6969
_p('{}* nprow0'.format(INT_TYPE)),
7070
_p('{}* npcol0'.format(INT_TYPE)),
7171
]),
72-
Declaration('blacs_pcoord_', 'void', [
72+
Declaration('blacs_pcoord', 'void', [
7373
_p('{}* ConTxt'.format(INT_TYPE)),
7474
_p('{}* nodenum'.format(INT_TYPE)),
7575
_p('{}* prow'.format(INT_TYPE), 1),
7676
_p('{}* pcol'.format(INT_TYPE), 1)
7777
]),
78-
Declaration('blacs_pinfo_', 'void', [
78+
Declaration('blacs_pinfo', 'void', [
7979
_p('{}* mypnum'.format(INT_TYPE), 1),
8080
_p('{}* nprocs'.format(INT_TYPE), 1),
8181
]),
82-
Declaration('blacs_pnum_', 'lapack_int', [
82+
Declaration('blacs_pnum', 'lapack_int', [
8383
_p('{}* ConTxt'.format(INT_TYPE)),
8484
_p('{}* prow'.format(INT_TYPE)),
8585
_p('{}* pcol'.format(INT_TYPE))
8686
]),
87-
Declaration('blacs_set_', 'void', [
87+
Declaration('blacs_set', 'void', [
8888
_p('{}* ConTxt'.format(INT_TYPE)),
8989
_p('{}* what'.format(INT_TYPE)),
9090
_p('{}* val'.format(INT_TYPE), 1)
9191
]),
92-
Declaration('blacs_setup_', 'void', [
92+
Declaration('blacs_setup', 'void', [
9393
_p('{}* mypnum'.format(INT_TYPE), 1),
9494
_p('{}* nprocs'.format(INT_TYPE), 1),
9595
]),
96-
Declaration('blacs2sys_handle_', 'MPI_Comm', [
96+
Declaration('blacs2sys_handle', 'MPI_Comm', [
9797
_p('{}* BlacsCtxt'.format(INT_TYPE))
9898
]),
99-
Declaration('sys2blacs_handle_', INT_TYPE, [
99+
Declaration('sys2blacs_handle', INT_TYPE, [
100100
_p('MPI_Comm* SysCtxt')
101101
]),
102102
]

scalapacke_files_create/create_scalapack.py

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,16 @@ def _mkargs_trmr2d(ctype: str):
146146

147147

148148
DECLS_REDIST = [
149-
Declaration('pcgemr2d_', 'void', _mkargs_gemr2d('{}*'.format(COMPLEX_TYPE))),
150-
Declaration('pdgemr2d_', 'void', _mkargs_gemr2d('double*')),
151-
Declaration('pigemr2d_', 'void', _mkargs_gemr2d('{}*'.format(INT_TYPE))),
152-
Declaration('psgemr2d_', 'void', _mkargs_gemr2d('float*')),
153-
Declaration('pzgemr2d_', 'void', _mkargs_gemr2d('{}*'.format(COMPLEX16_TYPE))),
154-
Declaration('pctrmr2d_', 'void', _mkargs_trmr2d('{}*'.format(COMPLEX_TYPE))),
155-
Declaration('pdtrmr2d_', 'void', _mkargs_trmr2d('double*')),
156-
Declaration('pitrmr2d_', 'void', _mkargs_trmr2d('{}*'.format(INT_TYPE))),
157-
Declaration('pstrmr2d_', 'void', _mkargs_trmr2d('float*')),
158-
Declaration('pztrmr2d_', 'void', _mkargs_trmr2d('{}*'.format(COMPLEX16_TYPE))),
149+
Declaration('pcgemr2d', 'void', _mkargs_gemr2d('{}*'.format(COMPLEX_TYPE))),
150+
Declaration('pdgemr2d', 'void', _mkargs_gemr2d('double*')),
151+
Declaration('pigemr2d', 'void', _mkargs_gemr2d('{}*'.format(INT_TYPE))),
152+
Declaration('psgemr2d', 'void', _mkargs_gemr2d('float*')),
153+
Declaration('pzgemr2d', 'void', _mkargs_gemr2d('{}*'.format(COMPLEX16_TYPE))),
154+
Declaration('pctrmr2d', 'void', _mkargs_trmr2d('{}*'.format(COMPLEX_TYPE))),
155+
Declaration('pdtrmr2d', 'void', _mkargs_trmr2d('double*')),
156+
Declaration('pitrmr2d', 'void', _mkargs_trmr2d('{}*'.format(INT_TYPE))),
157+
Declaration('pstrmr2d', 'void', _mkargs_trmr2d('float*')),
158+
Declaration('pztrmr2d', 'void', _mkargs_trmr2d('{}*'.format(COMPLEX16_TYPE))),
159159
]
160160

161161

@@ -172,7 +172,7 @@ def find_f_decl(lines: List[str]) -> Declaration:
172172

173173
args_list.append(DeclArgument(arg_name, arg_ctype, is_array=arg_is_array))
174174

175-
return Declaration(name.lower() + '_', rtype, args_list)
175+
return Declaration(name.lower(), rtype, args_list)
176176

177177

178178
def find_decl(path: pathlib.Path) -> Declaration:
@@ -244,17 +244,6 @@ def find_decl(path: pathlib.Path) -> Declaration:
244244
if 'workspace' in match_arg_doc['intent'].lower():
245245
# `WORK`
246246
arg.is_output = True
247-
if match_arg_doc['extra'] is not None:
248-
if 'complex' in match_arg_doc['extra'].lower():
249-
arg.is_complex = True
250-
arg.to_complex()
251-
# normally, that is useless, since the parser already recognize arrays
252-
if 'array' in match_arg_doc['extra'].lower():
253-
arg.is_array = True
254-
if 'pointer into the local' in match_arg_doc['extra'].lower():
255-
arg.is_array = True
256-
if 'pointer into local' in match_arg_doc['extra'].lower():
257-
arg.is_array = True
258247

259248
try:
260249
for a in ARG_FOLLOW[path.name][arg_name]:

scalapacke_files_create/templates/blacs.h.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extern "C" {
1111
/* Declarations
1212
*/
1313
{%- for declaration in declarations_f %}
14-
{{ declaration.to_extern_c_decl() }}
14+
{{ declaration.to_low_level_decl() }}
1515
{%- endfor %}
1616

1717
#ifdef __cplusplus

scalapacke_files_create/templates/pblas.h.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extern "C" {
1010
/* Declarations
1111
*/
1212
{%- for declaration in declarations_f %}
13-
{{ declaration.to_extern_c_decl() }}
13+
{{ declaration.to_low_level_decl() }}
1414
{%- endfor %}
1515

1616
#ifdef __cplusplus

scalapacke_files_create/templates/scalapack.h.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extern "C" {
1010
/* Declarations
1111
*/
1212
{%- for declaration in declarations_f %}
13-
{{ declaration.to_extern_c_decl() }}
13+
{{ declaration.to_low_level_decl() }}
1414
{%- endfor %}
1515

1616
#endif // HEADER_SCALAPACK_H
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "scalapacke.h"
22

33
{% for declaration in declarations_f %}
4-
{{ declaration.to_aliased_wrapper() }}
4+
{{ declaration.to_mid_level_wrapper() }}
55
{% endfor %}

scalapacke_files_create/templates/scalapacke.h.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extern "C" {
1010
/* Declarations
1111
*/
1212
{%- for declaration in declarations_f %}
13-
{{ declaration.to_aliased_decl() }}
13+
{{ declaration.to_mid_level_decl() }}
1414
{%- endfor %}
1515

1616
#ifdef __cplusplus
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "scalapacke_blacs.h"
22

33
{% for declaration in declarations_f %}
4-
{{ declaration.to_aliased_wrapper() }}
4+
{{ declaration.to_mid_level_wrapper() }}
55
{% endfor %}

scalapacke_files_create/templates/scalapacke_blacs.h.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extern "C" {
1010
/* Declarations
1111
*/
1212
{%- for declaration in declarations_f %}
13-
{{ declaration.to_aliased_decl() }}
13+
{{ declaration.to_mid_level_decl() }}
1414
{%- endfor %}
1515

1616
#ifdef __cplusplus
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include "scalapacke_pblas.h"
22

33
{% for declaration in declarations_f %}
4-
{{ declaration.to_aliased_wrapper() }}
4+
{{ declaration.to_mid_level_wrapper() }}
55
{% endfor %}

scalapacke_files_create/templates/scalapacke_pblas.h.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extern "C" {
1010
/* Declarations
1111
*/
1212
{%- for declaration in declarations_f %}
13-
{{ declaration.to_aliased_decl() }}
13+
{{ declaration.to_mid_level_decl() }}
1414
{%- endfor %}
1515

1616
#ifdef __cplusplus

0 commit comments

Comments
 (0)