Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OpenMP] Nim symbol interpolation support #9365

Open
mratsim opened this issue Oct 14, 2018 · 3 comments

Comments

Projects
None yet
4 participants
@mratsim
Copy link
Collaborator

commented Oct 14, 2018

Similar to emit pragma it would be very useful to have Nim symbol interpolation support in OpenMP annotations.

Currently the following code:

import sequtils, macros

var x = toSeq(1..1000)

let ompsize = x.len
let ompthreshold = 800

for i in `||`(0, x.len - 1, "if(`ompthreshold` < `ompsize`)"):
  x[i] += 2

echo x[0]

Generates:

// ... removing seq initialization
	T7_ = (x_wFAR9b1Cy8ShaaTQG2FH9c7g ? x_wFAR9b1Cy8ShaaTQG2FH9c7g->Sup.len : 0);
	ompsize_89bqUwA9bOswTIcWIVyaG9cfw = T7_;
	ompthreshold_XaMtJe9ajIFJ9btvwMO3AaEw = ((NI) 800);
	T8_ = (x_wFAR9b1Cy8ShaaTQG2FH9c7g ? x_wFAR9b1Cy8ShaaTQG2FH9c7g->Sup.len : 0);
	#pragma omp parallel for if(`ompthreshold` < `ompsize`)
for (i = ((NI) 0); i <= (NI)(T8_ - ((NI) 1)); ++i)	{
		x_wFAR9b1Cy8ShaaTQG2FH9c7g->data[i] += ((NI) 2);
	}
	nimZeroMem((void*)T10_, sizeof(tyArray_nHXaesL0DJZHyVS07ARPRA));
	T10_[0] = nimIntToStr(x_wFAR9b1Cy8ShaaTQG2FH9c7g->data[((NI) 0)]);
	echoBinSafe(T10_, 1);
@alaviss

This comment has been minimized.

Copy link
Contributor

commented Oct 14, 2018

I think you should substitute ompthreshold and ompsize in the C code with their actual name...

@mratsim

This comment has been minimized.

Copy link
Collaborator Author

commented Oct 14, 2018

@alaviss I can't easily, that's the whole point of the feature request.

@mratsim

This comment has been minimized.

Copy link
Collaborator Author

commented Oct 14, 2018

Here is a workaround for 0.19 that will also mangles names in case of nested OpenMP loops.

In templates exportc doesn't catch the constants #9366 hence the omp_suffix proc must keep track of the last suffix generated.

# omp_mangling.nim
import random
from strutils import toHex

var mangling_rng {.compileTime.} = initRand(0x1337DEEDBEAF)
var current_suffix {.compileTime.} = ""

proc omp_suffix*(genNew: static bool = false): static string =
  ## genNew:
  ##   if false, return the last suffix
  ##   else return a fresh one

  if genNew:
    current_suffix = mangling_rng.rand(high(uint32)).toHex
  result = current_suffix
# omp_threshold.nim

import sequtils, macros
import ../laser/openmp/omp_mangling

var x = toSeq(1..1000)

template plus2(s: var seq[int]) =
  const
    suffix = omp_suffix(genNew = true)
    ompsize_Csym = "ompsize_" & suffix
    ompthreshold_Csym = "ompthreshold_" & suffix
    ompAnnotation = "if(" & ompthreshold_Csym & " < " & ompsize_Csym & ")"

  # We can't use {.exportc: ompsize_Csym.} directly due to #9366
  let ompsize {.exportc: "ompsize_" & omp_suffix(genNew = false).}= x.len
  let ompthreshold {.exportc: "ompthreshold_" & omp_suffix(genNew = false).}= 800

  for i in `||`(0, x.len - 1, ompAnnotation):
    x[i] += 2

plus2(x)
plus2(x)

echo x[0]

Generated C code

// ...........
	T7_ = (x_wFAR9b1Cy8ShaaTQG2FH9c7g ? x_wFAR9b1Cy8ShaaTQG2FH9c7g->Sup.len : 0);
	ompsize_00000000CB2E7BAE = T7_;
	ompthreshold_00000000CB2E7BAE = ((NI) 800);
	T8_ = (x_wFAR9b1Cy8ShaaTQG2FH9c7g ? x_wFAR9b1Cy8ShaaTQG2FH9c7g->Sup.len : 0);
	#pragma omp parallel for if(ompthreshold_00000000CB2E7BAE < ompsize_00000000CB2E7BAE)
for (i = ((NI) 0); i <= (NI)(T8_ - ((NI) 1)); ++i)	{
		x_wFAR9b1Cy8ShaaTQG2FH9c7g->data[i] += ((NI) 2);
	}
	T10_ = (x_wFAR9b1Cy8ShaaTQG2FH9c7g ? x_wFAR9b1Cy8ShaaTQG2FH9c7g->Sup.len : 0);
	ompsize_000000009280FB6D = T10_;
	ompthreshold_000000009280FB6D = ((NI) 800);
	T11_ = (x_wFAR9b1Cy8ShaaTQG2FH9c7g ? x_wFAR9b1Cy8ShaaTQG2FH9c7g->Sup.len : 0);
	#pragma omp parallel for if(ompthreshold_000000009280FB6D < ompsize_000000009280FB6D)
for (i_2 = ((NI) 0); i_2 <= (NI)(T11_ - ((NI) 1)); ++i_2)	{
		x_wFAR9b1Cy8ShaaTQG2FH9c7g->data[i_2] += ((NI) 2);
	}
	nimZeroMem((void*)T13_, sizeof(tyArray_nHXaesL0DJZHyVS07ARPRA));
	T13_[0] = nimIntToStr(x_wFAR9b1Cy8ShaaTQG2FH9c7g->data[((NI) 0)]);
	echoBinSafe(T13_, 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.