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
Open

[OpenMP] Nim symbol interpolation support #9365

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

Comments

@mratsim
Copy link
Collaborator

mratsim 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
Copy link
Collaborator

alaviss commented Oct 14, 2018

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

@mratsim
Copy link
Collaborator Author

mratsim commented Oct 14, 2018

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

@mratsim
Copy link
Collaborator Author

mratsim 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
Labels
Projects
None yet
Development

No branches or pull requests

4 participants