Skip to content

Use 'const' pointers in kernel APIs.#722

Merged
fgvanzee merged 15 commits intomasterfrom
const_kernel_apis
Feb 20, 2023
Merged

Use 'const' pointers in kernel APIs.#722
fgvanzee merged 15 commits intomasterfrom
const_kernel_apis

Conversation

@fgvanzee
Copy link
Copy Markdown
Member

@fgvanzee fgvanzee commented Feb 10, 2023

Details:

  • Qualified all input-only data pointers in the various kernel APIs with the const keyword while also removing restrict from those kernel APIs. (Use of restrict was maintained in kernel implementations, where appropriate.) This affected the function pointer types defined for all of the kernels, their prototypes, and the reference and optimized kernel definitions' signatures.
  • Templatized the definitions of copys_mxn and xpbys_mxn static inline functions.
  • Minor whitespace and style changes (e.g. combining local variable declaration and initialization into a single statement).
  • Removed some unused kernel code left in old directories.
  • In common.mk, grep for "#include" instead of "\#include". Not sure why the backslash is suddenly giving a "grep: warning: stray \ before #" message, but removing the backslash seems to fix the issue.

@devinamatthews Note that this does not yet contain the switchover to void*. I wanted to do it in two phases in case anything went wrong.

Details:
- Qualified all input-only data pointers in the various kernel APIs with
  the 'const' keyword while also removing 'restrict' from those kernel
  APIs. (Use of 'restrict' was maintained in kernel implementations,
  where appropriate.) This affected the function pointer types defined
  for all of the kernels, their prototypes, and the reference and
  optimized kernel definitions' signatures.
- Templatized the definitions of copys_mxn and xpbys_mxn static inline
  functions.
- Minor whitespace and style changes (e.g. combining local variable
  declaration and initialization into a single statement).
- Removed some unused kernel code left in 'old' directories.
- In common.mk, grep for "#include" instead of "\#include". Not sure why
  the backslash is suddenly giving a "grep: warning: stray \ before #"
  message, but removing the backslash seems to fix the issue.
@fgvanzee fgvanzee self-assigned this Feb 10, 2023
@leekillough
Copy link
Copy Markdown
Collaborator

If I may respectfully ask, what is the reason for removing restrict, and why wasn't const already used for pointers to read-only data?

@devinamatthews
Copy link
Copy Markdown
Member

Re restrict, it's not really needed in the function prototypes or typedefs, since it only has an effect on the generated code when used in the definition. True, one could argue it serves a purpose as defining a user contract, but it's not quite nuanced enough to do that precisely for the kernels anyways. It is still used when writing kernel definitions usually.

Re const, the codebase didn't use const at all until I started putting it in a year ago or so. This is just an evolution of those efforts.

@leekillough
Copy link
Copy Markdown
Collaborator

leekillough commented Feb 10, 2023

A caller is not affected by knowing whether two declared pointer parameters are aliased (or declared restrict), unless one of them is read-only (pointer to const) and the other is read-write, and the caller reads the read-only one before and after the call, and because it knows of the restrict in the parameter declaration, it can assume that the read-only one was not affected during the call. But that only occurs in a very small number of real cases.

I am glad you're updating the appropriate use of const where it wasn't used before.

[edit: emphasis in italics]

@devinamatthews
Copy link
Copy Markdown
Member

A caller is not affected by knowing whether two declared pointer parameters are aliased (or declared restrict), unless one of them is read-only (pointer to const) and the other is read-write, and the caller reads the read-only one before and after the call, and because it knows of the restrict in the parameter declaration, it can assume that the read-only one was not affected during the call. But that only occurs in a very small number of real cases.

Well, restrict on an interface is only a pinky-swear to the compiler. The implementation can ignore that restriction (same with const).

@leekillough
Copy link
Copy Markdown
Collaborator

Also, the caller can only assume that the const * restrict addressed parameter was not modified if its address was not "exposed" globally or through some other less restrictive call elsewhere (so-called "address exposed"). So the benefit of restrict is highly restricted.

Except in the innermost kernels, I agree that the utility of restrict is limited.

@fgvanzee
Copy link
Copy Markdown
Member Author

fgvanzee commented Feb 10, 2023

For anyone not following the Discord discussion, these CI tests are failing because I removed the \ from:

REF_KER_HEADERS := $(shell $(GREP) "\#include" $(REF_KER_SRC) | ... )

in common.mk because as of grep 3.8, that backslash is causing the following warning:

grep: warning: stray \ before #" message

The warning is obviously undesired, but even more undesired is the build system breaking altogether. So I'm trying to figure out a way to satisfy both pre- and post-3.8 greps.

I tried switching from double to single quotes around #include, but that didn't work.

@leekillough
Copy link
Copy Markdown
Collaborator

I believe that # must be escaped because otherwise gmake assumes it's the start of the comment and ignores the rest of the line, obviously leading to a syntax error.

@fgvanzee
Copy link
Copy Markdown
Member Author

fgvanzee commented Feb 10, 2023

I believe that # must be escaped because otherwise gmake assumes it's the start of the comment and ignores the rest of the line, obviously leading to a syntax error.

That kind of makes sense, but GNU make works as expected with:

REF_KER_HEADERS := $(shell $(GREP) "#include" $(REF_KER_SRC) | ... )

when using grep 3.8. (Double vs single quotes doesn't seem to matter here.) So... I dunno.

@fgvanzee
Copy link
Copy Markdown
Member Author

While I don't like it, the only band-aid I could think of is to redirect stderr to /dev/null for that particular command sequence. (See #723.)

@fgvanzee
Copy link
Copy Markdown
Member Author

fgvanzee commented Feb 11, 2023

@nisanthmp Please try compiling the power kernels in this commit PR to make sure I didn't break anything. If you get any errors (or warnings), please report them here so I can fix them.

@nisanthmp
Copy link
Copy Markdown
Contributor

@fgvanzee
I'm getting the following errors:

In file included from kernels/power10/3/vector_int_macros.h:37,
from kernels/power10/3/bli_sgemm_power10_mma.c:35:
kernels/power10/3/bli_sgemm_power10_mma.c: In function ‘bli_sgemm_power10_mma_8x16’:
./frame/include//bli_edge_case_macro_defs.h:50:54: error: ‘cs_c’ undeclared (first use in this function); did you mean ‘_cs_c’?
50 | PASTEMAC(ch,ctype) _ct[ BLIS_STACK_BUF_MAX_SIZE
| ^~~~
./frame/include//bli_edge_case_macro_defs.h:78:9: note: in expansion of macro ‘GEMM_UKR_SETUP_CT_PRE’
78 | const bool _use_ct = ( row_major ? cs_c != 1 : rs_c != 1 ) ||
| ^~~~~~~~~~~~~~~~~~~~~
kernels/power10/3/bli_sgemm_power10_mma.c:77:5: note: in expansion of macro ‘GEMM_UKR_SETUP_CT’
77 | GEMM_UKR_SETUP_CT( s, 8, 16, true );
| ^~~~~~~~~~~~~~~~~
compilation terminated due to -Wfatal-errors.
make: *** [Makefile:695: obj/power/kernels/power10/3/bli_sgemm_power10_mma.o] Error 1
make: *** Waiting for unfinished jobs....
In file included from kernels/power10/3/vector_int_macros.h:37,
from kernels/power10/3/bli_dgemm_power10_mma.c:36:
kernels/power10/3/bli_dgemm_power10_mma.c: In function ‘bli_dgemm_power10_mma_8x8’:
./frame/include//bli_edge_case_macro_defs.h:50:54: error: ‘cs_c’ undeclared (first use in this function); did you mean ‘_cs_c’?
50 | PASTEMAC(ch,ctype) _ct[ BLIS_STACK_BUF_MAX_SIZE
| ^~~~
./frame/include//bli_edge_case_macro_defs.h:78:9: note: in expansion of macro ‘GEMM_UKR_SETUP_CT_PRE’
78 | const bool _use_ct = ( row_major ? cs_c != 1 : rs_c != 1 ) ||
| ^~~~~~~~~~~~~~~~~~~~~
kernels/power10/3/bli_dgemm_power10_mma.c:84:5: note: in expansion of macro ‘GEMM_UKR_SETUP_CT’
84 | GEMM_UKR_SETUP_CT( d, 8, 8, true );
| ^~~~~~~~~~~~~~~~~
compilation terminated due to -Wfatal-errors.

Details:
- Thanks to Nisanth M P for helping to validate changes to the power10
  microkernels.
@fgvanzee
Copy link
Copy Markdown
Member Author

Thank you, @nisanthmp. I think I've fixed the errors that you reported. Could you please confirm there are no others?

@nisanthmp
Copy link
Copy Markdown
Contributor

@fgvanzee There are no other compilation errors when configured for power family, ie power9 and power10 configurations

@fgvanzee
Copy link
Copy Markdown
Member Author

@fgvanzee There are no other compilation errors when configured for power family, ie power9 and power10 configurations

Wonderful. Thanks for your help!

@fgvanzee fgvanzee merged commit 93c63d1 into master Feb 20, 2023
@fgvanzee fgvanzee deleted the const_kernel_apis branch February 20, 2023 17:14
@angsch
Copy link
Copy Markdown
Collaborator

angsch commented Feb 21, 2023

Cosmetics: Some of the non-reference kernels received bonus \. For example:

void bli_dgemm_armsve_asm_2vx10_unindexed
(
dim_t m, \
dim_t n, \
dim_t k, \
const double* alpha, \
const double* a, \
const double* b, \
const double* beta, \
double* c, inc_t rs_c0, inc_t cs_c0, \
auxinfo_t* data, \
const cntx_t* cntx \

angsch added a commit to angsch/blis that referenced this pull request Feb 21, 2023
angsch added a commit to angsch/blis that referenced this pull request Feb 24, 2023
angsch added a commit to angsch/blis that referenced this pull request Mar 25, 2023
ct-clmsn pushed a commit to ct-clmsn/blis that referenced this pull request Jul 29, 2023
Details:
- Qualified all input-only data pointers in the various kernel APIs with
  the 'const' keyword while also removing 'restrict' from those kernel
  APIs. (Use of 'restrict' was maintained in kernel implementations,
  where appropriate.) This affected the function pointer types defined
  for all of the kernels, their prototypes, and the reference and
  optimized kernel definitions' signatures.
- Templatized the definitions of copys_mxn and xpbys_mxn static inline
  functions.
- Minor whitespace and style changes (e.g. combining local variable
  declaration and initialization into a single statement).
- Removed some unused kernel code left in 'old' directories.
- Thanks to Nisanth M P for helping to validate changes to the power10
  microkernels.
fgvanzee added a commit that referenced this pull request May 21, 2024
Details:
- Updated common.mk so that when --disable-shared option is given to
  configure:
  1. The -fPIC compiler flag is omitted from the individual
     configuration family members' CPICFLAGS variables (which are
     initialized in each subconfig's make_defs.mk file); and
  2. The BUILD_SYMFLAGS variable, which contains compiler flags needed
     to control the symbol export behavior, is left blank.
- The net result of these changes is that flags specific to shared
  library builds are only used when a shared library is actually
  scheduled to be built. Thanks to Nick Knight for reporting this issue.
- CREDITS file update.
- (cherry picked from commit 5f84130)

Updated configure to pass all shellcheck checks. (#729)

Details:
- Modified configure so that it passes all 'shellcheck' checks,
  disabling ones which we violate but which are just stylistic, or are
  special cases in our code.
- Miscellaneous other minor changes, such as rearranged redirections in
  long sed/perl pipes to look more natural.
- Whitespace tweaks.
- (cherry picked from 72c37eb)

Fixed bugs in scal2v ref kernel when alpha == 1. (#728)

Details:
- Fixed a typo bug in ref_kernels/1/bli_scal2v_ref.c where the
  conditional that was supposed to be checking for cases when alpha is
  equal to 1.0 (so that copyv could be used instead of scal2v) was
  instead erroneously comparing alpha against 0.0.
- Fixed another bug in the same function whereby BLIS_NO_CONJUGATE was
  erroneously being passed into copyv instead of the kernel's conjx
  parameter. This second bug was inert, however, due to the first bug
  since the "alpha == 0.0" case was already being handled, resulting in
  the code block never executing.
- (cherry picked from 60f3634)

Use 'void*' datatypes in kernel APIs. (#727)

Details:
- Migrated all kernel APIs to use void* pointers instead of float*,
  double*, scomplex*, and dcomplex* pointers. This allows us to define
  many fewer kernel function pointer types, which also makes it much
  easier to know which function pointer type to use at any given time.
  (For example, whereas before there was ?axpyv_ker_ft, ?axpyv_ker_vft,
  and axpyv_ker_vft, now there is just axpyv_ker_ft, which is equivalent
  so what axpyv_ker_vft used to be.)
- Refactored how kernel function prototypes and kernel function types
  are defined so as to reduce redundant code. Specifically, the
  function signatures (excluding cntx_t* and, in the case of level-3
  microkernels, auxinfo_t*) are defined in new headers named, for
  example, bli_l1v_ker_params.h. Those signatures are reused via macro
  instantiation when defining both kernel prototypes and kernel function
  types. This will hopefully make it a little easier to update, add, and
  manage kernel APIs going forward.
- Updated all reference kernels according to the aforementioned switch
  to void* pointers.
- Updated all optimzied kernels according to the aforementioned switch
  to void* pointers. This sometimes required renaming variables,
  inserting typecasting so that pointer arithmetic could continue to
  function as intended, and related tweaks.
- Updated sandbox/gemmlike according to the aforementioned switch to
  void* pointers.
- Renamed:
  - frame/1/bli_l1v_ft_ker.h    -> frame/1/bli_l1v_ker_ft.h
  - frame/1f/bli_l1f_ft_ker.h   -> frame/1f/bli_l1f_ker_ft.h
  - frame/1m/bli_l1m_ft_ker.h   -> frame/1m/bli_l1m_ker_ft.h
  - frame/3/bli_l1m_ft_ukr.h    -> frame/3/bli_l1m_ukr_ft.h
  - frame/3/bli_l3_sup_ft_ker.h -> frame/3/bli_l3_sup_ker_ft.h
  to better align with naming of neighboring files.
- Added the missing "void* params" argument to bli_?packm_struc_cxk() in
  frame/1m/packm/bli_packm_struc_cxk.c. This argument is being passed
  into the function from bli_packm_blk_var1(), but wasn't being "caught"
  by the function definition itself. The function prototype for
  bli_?packm_struc_cxk() also needed updating.
- Reordered the last two parameters in bli_?packm_struc_cxk().
  (Previously, the "void* params" was passed in after the
  "const cntx_t* cntx", although because of the above bug the params
  argument wasn't actually present in the function definition.)
- (cherry picked from fab18dc)

Use 'const' pointers in kernel APIs. (#722)

Details:
- Qualified all input-only data pointers in the various kernel APIs with
  the 'const' keyword while also removing 'restrict' from those kernel
  APIs. (Use of 'restrict' was maintained in kernel implementations,
  where appropriate.) This affected the function pointer types defined
  for all of the kernels, their prototypes, and the reference and
  optimized kernel definitions' signatures.
- Templatized the definitions of copys_mxn and xpbys_mxn static inline
  functions.
- Minor whitespace and style changes (e.g. combining local variable
  declaration and initialization into a single statement).
- Removed some unused kernel code left in 'old' directories.
- Thanks to Nisanth M P for helping to validate changes to the power10
  microkernels.
- (cherry picked from 93c63d1)
fgvanzee added a commit that referenced this pull request May 22, 2024
Details:
- Updated common.mk so that when --disable-shared option is given to
  configure:
  1. The -fPIC compiler flag is omitted from the individual
     configuration family members' CPICFLAGS variables (which are
     initialized in each subconfig's make_defs.mk file); and
  2. The BUILD_SYMFLAGS variable, which contains compiler flags needed
     to control the symbol export behavior, is left blank.
- The net result of these changes is that flags specific to shared
  library builds are only used when a shared library is actually
  scheduled to be built. Thanks to Nick Knight for reporting this issue.
- CREDITS file update.
- (cherry picked from 5f84130)

Updated configure to pass all shellcheck checks. (#729)

Details:
- Modified configure so that it passes all 'shellcheck' checks,
  disabling ones which we violate but which are just stylistic, or are
  special cases in our code.
- Miscellaneous other minor changes, such as rearranged redirections in
  long sed/perl pipes to look more natural.
- Whitespace tweaks.
- (cherry picked from 72c37eb)

Fixed bugs in scal2v ref kernel when alpha == 1. (#728)

Details:
- Fixed a typo bug in ref_kernels/1/bli_scal2v_ref.c where the
  conditional that was supposed to be checking for cases when alpha is
  equal to 1.0 (so that copyv could be used instead of scal2v) was
  instead erroneously comparing alpha against 0.0.
- Fixed another bug in the same function whereby BLIS_NO_CONJUGATE was
  erroneously being passed into copyv instead of the kernel's conjx
  parameter. This second bug was inert, however, due to the first bug
  since the "alpha == 0.0" case was already being handled, resulting in
  the code block never executing.
- (cherry picked from 60f3634)

Use 'void*' datatypes in kernel APIs. (#727)

Details:
- Migrated all kernel APIs to use void* pointers instead of float*,
  double*, scomplex*, and dcomplex* pointers. This allows us to define
  many fewer kernel function pointer types, which also makes it much
  easier to know which function pointer type to use at any given time.
  (For example, whereas before there was ?axpyv_ker_ft, ?axpyv_ker_vft,
  and axpyv_ker_vft, now there is just axpyv_ker_ft, which is equivalent
  so what axpyv_ker_vft used to be.)
- Refactored how kernel function prototypes and kernel function types
  are defined so as to reduce redundant code. Specifically, the
  function signatures (excluding cntx_t* and, in the case of level-3
  microkernels, auxinfo_t*) are defined in new headers named, for
  example, bli_l1v_ker_params.h. Those signatures are reused via macro
  instantiation when defining both kernel prototypes and kernel function
  types. This will hopefully make it a little easier to update, add, and
  manage kernel APIs going forward.
- Updated all reference kernels according to the aforementioned switch
  to void* pointers.
- Updated all optimzied kernels according to the aforementioned switch
  to void* pointers. This sometimes required renaming variables,
  inserting typecasting so that pointer arithmetic could continue to
  function as intended, and related tweaks.
- Updated sandbox/gemmlike according to the aforementioned switch to
  void* pointers.
- Renamed:
  - frame/1/bli_l1v_ft_ker.h    -> frame/1/bli_l1v_ker_ft.h
  - frame/1f/bli_l1f_ft_ker.h   -> frame/1f/bli_l1f_ker_ft.h
  - frame/1m/bli_l1m_ft_ker.h   -> frame/1m/bli_l1m_ker_ft.h
  - frame/3/bli_l1m_ft_ukr.h    -> frame/3/bli_l1m_ukr_ft.h
  - frame/3/bli_l3_sup_ft_ker.h -> frame/3/bli_l3_sup_ker_ft.h
  to better align with naming of neighboring files.
- Added the missing "void* params" argument to bli_?packm_struc_cxk() in
  frame/1m/packm/bli_packm_struc_cxk.c. This argument is being passed
  into the function from bli_packm_blk_var1(), but wasn't being "caught"
  by the function definition itself. The function prototype for
  bli_?packm_struc_cxk() also needed updating.
- Reordered the last two parameters in bli_?packm_struc_cxk().
  (Previously, the "void* params" was passed in after the
  "const cntx_t* cntx", although because of the above bug the params
  argument wasn't actually present in the function definition.)
- (cherry picked from fab18dc)

Use 'const' pointers in kernel APIs. (#722)

Details:
- Qualified all input-only data pointers in the various kernel APIs with
  the 'const' keyword while also removing 'restrict' from those kernel
  APIs. (Use of 'restrict' was maintained in kernel implementations,
  where appropriate.) This affected the function pointer types defined
  for all of the kernels, their prototypes, and the reference and
  optimized kernel definitions' signatures.
- Templatized the definitions of copys_mxn and xpbys_mxn static inline
  functions.
- Minor whitespace and style changes (e.g. combining local variable
  declaration and initialization into a single statement).
- Removed some unused kernel code left in 'old' directories.
- Thanks to Nisanth M P for helping to validate changes to the power10
  microkernels.
- (cherry picked from 93c63d1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants