﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
3336	ParModelica: Cannot pass parallel array as argument to function	Gustaf Thorslund	Mahder Alemseged Gebremedhin	"Looking at the MPARBenchmarkSuite it's not too uncommon to call an ordinary function with parallel arrays as argument. [https://openmodelica.org/svn/OpenModelica/branches/MPARBenchmarkSuite/Parallel/Eigenvalue.mo Eigenvalue.mo] does so (note: it uses the 'parallel' prefix rather than 'parglobal' as currently used by ParModelica to annotate parallel variables).

Here is a small test where parallel variables are passed as argument:
{{{#!mo
package ParArg
  constant Integer nx = 10;

  function mult
    input Real a;
    input Real m[nx];
    output Real result[nx];
  protected
    parglobal Real pa;
    parglobal Real pm[nx];
    parglobal Real presult[nx];
  algorithm
    pa := a;
    pm := m;
    parfor i in 1:nx loop
      presult[i] := pm[i]*pa;
    end parfor;
    result := presult;
  end mult;

  function multParArg
    input Real a;
    parglobal input Real m[nx];
    parglobal output Real result[nx];
  protected
    parglobal Real pa;
  algorithm
    pa := a;
    parfor i in 1:nx loop
      result[i] := m[i]*pa;
    end parfor;
  end multParArg;

  function Test
    input Real a;
    output Real result[nx];
  protected
    Real m[nx] = {i for i in 1:nx};
    Real pm[nx];
  algorithm
    result := mult(10,m);
  end Test;

  function TestParArg
    input Real a;
    output Real result[nx];
  protected
    Real m[nx] = {i for i in 1:nx};
    parglobal Real pm[nx];
    parglobal Real presult[nx];
  algorithm
    pm := m;
    presult := multParArg(10,m);
    result := presult;
  end TestParArg;
end ParArg;
}}}

Here is a script for testing:
{{{#!mo
setCommandLineOptions(""+d=noevalfunc +g=ParModelica -v=1"");
getErrorString();

setDefaultOpenCLDevice(1);
getErrorString();

loadFile(""ParArg.mo"");
getErrorString();

x:=ParArg.Test(5);
getErrorString();

y:=ParArg.TestParArg(5);
getErrorString();
}}}

Here is the result, showing how the second test using parallel variables as argument fails (probably due to wrong code generated):
{{{#!bash
$ omc ParArg.mos
true
""""
true
""""
true
""""
	 :Using flags -I""/home/gusth/src/OpenModelica/build/include/omc/c/""
	OpenCL initialization :        2262.165000 ms
	Kernel Execution      :        0.937000 ms
{10.0,20.0,30.0,40.0,50.0,60.0,70.0,80.0,90.0,100.0}
""""
Error processing file: ParArg.mos
Error: Error building simulator. Build log: g++ -I""/home/gusth/src/OpenModelica/build/include/omc/c""   -fPIC -O0 -falign-functions -march=native   -c -o ParArg_TestParArg.o ParArg_TestParArg.c
ParArg_TestParArg.c: In function ‘device_real_array omc_ParArg_multParArg(threadData_t*, modelica_real, real_array)’:
ParArg_TestParArg.c:139:52: error: call of overloaded ‘ocl_set_kernel_arg(_cl_kernel*&, int&, void*&)’ is ambiguous
   ocl_set_kernel_arg(tmp4, parfor_1_arg_nr, _m.data); ++parfor_1_arg_nr; 
                                                    ^
ParArg_TestParArg.c:139:52: note: candidates are:
In file included from ParArg_TestParArg.h:8:0,
                 from ParArg_TestParArg.c:1:
/home/gusth/src/OpenModelica/build/include/omc/c/ParModelica/explicit/openclrt/omc_ocl_interface.h:84:6: note: void ocl_set_kernel_arg(cl_kernel, int, cl_mem) <near match>
 void ocl_set_kernel_arg(cl_kernel kernel, int arg_nr, cl_mem in_arg);
      ^
/home/gusth/src/OpenModelica/build/include/omc/c/ParModelica/explicit/openclrt/omc_ocl_interface.h:84:6: note:   no known conversion for argument 3 from ‘void*’ to ‘cl_mem {aka _cl_mem*}’
/home/gusth/src/OpenModelica/build/include/omc/c/ParModelica/explicit/openclrt/omc_ocl_interface.h:88:6: note: void ocl_set_kernel_arg(cl_kernel, int, modelica_integer) <near match>
 void ocl_set_kernel_arg(cl_kernel kernel, int arg_nr, modelica_integer in_arg);
      ^
/home/gusth/src/OpenModelica/build/include/omc/c/ParModelica/explicit/openclrt/omc_ocl_interface.h:88:6: note:   no known conversion for argument 3 from ‘void*’ to ‘modelica_integer {aka long int}’
ParArg_TestParArg.c:140:48: error: ‘real_array’ has no member named ‘info_dev’
   ocl_set_kernel_arg(tmp4, parfor_1_arg_nr, _m.info_dev); ++parfor_1_arg_nr; 
                                                ^
ParArg_TestParArg.c: In function ‘void* boxptr_ParArg_multParArg(threadData_t*, modelica_metatype, modelica_metatype)’:
ParArg_TestParArg.c:160:45: error: could not convert ‘_result’ from ‘device_real_array {aka dev_arr}’ to ‘base_array_t {aka base_array_s}’
   out_result = mmc_mk_modelica_array(_result);
                                             ^
make: *** [ParArg_TestParArg] Error 1

# Error encountered! Exiting...
# Please check the error message and the flags.

Execution failed!
}}}"	defect	new	blocker	Future	ParModelica	trunk			
