Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • sac2c sac2c
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 397
    • Issues 397
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 12
    • Merge requests 12
  • Deployments
    • Deployments
    • Releases
  • Wiki
    • Wiki
  • External wiki
    • External wiki
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar
  • sac-group
  • sac2csac2c
  • Issues
  • #2467
Closed
Open
Created Apr 23, 2025 by Thomas Koopman@thomasDeveloper

WLUR unrolls with-loops that are too large when using structs

Compiler at commit 5d970304cb7c3f44c98244fe53e7ca99d2bc66e3

In the following program particles.x = {iv -> _sel_VxA_(iv, particles.x) + _sel_VxA_(iv, particles.angle)}; is compiled correctly, but particles.y = {iv -> _sel_VxA_(iv, particles.y) + _sel_VxA_(iv, particles.angle)}; is completely unrolled, which it should not be. This happens in SSAWLUnroll.c

inline double +(double a, double b) { return _add_SxS_(a, b); }

double sum(double[d:shp] x)
{
  return with {
          (_mul_SxV_(0, shp) <= iv < shp): _sel_VxA_(iv, x);
         }: fold(+, 0d);
}

struct Particle {
  double x;
  double y;
  double angle;
};

inline
struct Particle[n]
step_particles(struct Particle[n] particles)
{
  particles.x = {iv -> _sel_VxA_(iv, particles.x) + _sel_VxA_(iv, particles.angle)};
  particles.y = {iv -> _sel_VxA_(iv, particles.y) + _sel_VxA_(iv, particles.angle)};

	return particles;
}

int main() {
	particle_count  = 20;
	
	particles = {iv -> Particle {.x     = 0d,
                               .y     = 100d,
                               .angle = 0.0}
                   | iv < [particle_count]};
	
  for (i = 0; _lt_SxS_(i, 10); i = _add_SxS_(i, 1)) {
	  particles = step_particles(particles);
  }
	
	return _toi_S_(sum(particles.x));
}

When dissolving the structs manually, there is no such problem

inline double +(double a, double b) { return _add_SxS_(a, b); }

double sum(double[d:shp] x)
{
  return with {
          (_mul_SxV_(0, shp) <= iv < shp): _sel_VxA_(iv, x);
         }: fold(+, 0d);
}

inline
double[n], double[n], double[n]
step_particles(double[n] particles_x, double[n] particles_y, double[n] particles_angle)
{
  particles_x = {iv -> _sel_VxA_(iv, particles_x) + _sel_VxA_(iv, particles_angle)};
  particles_y = {iv -> _sel_VxA_(iv, particles_y) + _sel_VxA_(iv, particles_angle)};

	return (particles_x, particles_y, particles_angle);
}

int main() {
	particle_count  = 20;
	
  particles_x     = {iv -> 0d | iv < [particle_count]};
  particles_y     = {iv -> 0d | iv < [particle_count]};
  particles_angle = {iv -> 0d | iv < [particle_count]};
	
  for (i = 0; _lt_SxS_(i, 10); i = _add_SxS_(i, 1)) {
	  particles_x, particles_y, particles_angle = step_particles(particles_x, particles_y, particles_angle);
  }
	
	return _toi_S_(sum(particles_x));
}
Edited Apr 25, 2025 by Thomas Koopman
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking