Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Register
  • Sign in
  • S sdv-lammps
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 100
    • Issues 100
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Container Registry
    • Terraform modules
  • Monitor
    • Monitor
    • Metrics
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • djurado
  • sdv-lammps
  • Wiki
  • union_int_float_t

union_int_float_t · Changes

Page history
Create union_int_float_t authored Jan 17, 2023 by djurado's avatar djurado
Hide whitespace changes
Inline Side-by-side
union_int_float_t.md 0 → 100644
View page @ 8c4f585f
`PairLJCharmmCoulLong::compute` defines an union type `union_int_float_t` in order to be able with operate with the bits of a 32bit floating point number `rsq` as if it was a 32-bit integer.
Since the `union` construct cannot be used with RISC-V intrinsic data types, an inline assembler block with a `vmv.v.v` instruction was used instead.
the code snippet shows how the data can be successfully moved from a floating point data type to an integer data type.
```c++
__epi_1xf64 vecrsq;
__epi_1xi64 vecitable;
// vecitable <- vecrsq
__asm__ (
"nop\n\t"
"vmv.v.v %0, %1\n\t"
: "=vr" (vecitable)
: "vr" (vecrsq)
);
```
The downside of this `vmv.v.v`method is that it adds a redundant instruction, since is not actually needed to move data from a register to another, it should be enough just to interpret it as another type.
There is an intrinsic that allows converting between mask and integer vector without performing any operation, but not between integer and floating point, although it follows the same underlying principle (conversion between data types with same SEW).
After the conversion, then, some bit manipulation is performed on the result.
This becomes an issue, since in the code it was performed with 32-bit data types, and we use 64-bit data types.
To overcome this, we need to convert the bitmask and the shift value from 32 to 64 bits.
It cannot be done statically, since these values are generated in generated in `pair.cpp:init_bitmap` based to the settings specified in the input, so a small extra piece of code is needed.
Since the extracted bit fields are centered at the start of the mantissa, in order to convert the mask and shift value to 64-bit, it is enough to shift and add `(DBL_MANT_DIG - FLT_MANT_DIG)`, which corresponds to the increase of size of the mantissa when switching from single to double precision.
Here, we show the code snippet with the transformation to the mask and shift value and a representation of the bit manipulation performed.
```
ncoulmask64 = ((long) ncoulmask) << (DBL_MANT_DIG - FLT_MANT_DIG);
ncoulshiftbits64 = ncoulshiftbits + (DBL_MANT_DIG - FLT_MANT_DIG);
```
![lammps_union_mask](uploads/483b72359d0e41d0b754be1518ff2383/lammps_union_mask.png)
\ No newline at end of file
Clone repository

Home

  1. Introduction
  2. Overview
  3. Implementation
    • Specialization
    • Loop-size
    • Managing-code-paths
    • 32-bit and 64-bit data types
  4. Implementation

Sidebar