Opened 10 years ago

Closed 9 years ago

Last modified 9 years ago

#3336 closed defect (fixed)

ParModelica: Cannot pass parallel array as argument to function

Reported by: Gustaf Thorslund Owned by: Mahder Alemseged Gebremedhin
Priority: blocker Milestone: 1.9.4
Component: ParModelica Version: trunk
Keywords: Cc:

Description (last modified by Gustaf Thorslund)

Looking at the MPARBenchmarkSuite it's not too uncommon to call an ordinary function with parallel arrays as argument. 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:

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 mpm[nx];
    parglobal output Real mpresult[nx];
  protected
    parglobal Real pa;
  algorithm
    pa := a;
    parfor i in 1:nx loop
      mpresult[i] := mpm[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(a,m);
  end Test;

  function TestParArg
    input Real a;
    output Real result[nx];
  protected
    Real m[nx] = {i for i in 1:nx};
    parglobal Real pa;
    parglobal Real pm[nx];
    parglobal Real presult[nx];
  algorithm
    pa := a;
    pm := m;
    presult := multParArg(pa,pm);
    result := presult;
  end TestParArg;
end ParArg;

Here is a script for testing:

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):

Error processing file: ParArg.mos
Error: Error building simulator. Build log: g++ -I"/home/gustaf/src/OpenModelica/build/include/omc/c"   -fPIC -O0 -march=native   -c -o ParArg_TestParArg.o ParArg_TestParArg.c
ParArg_TestParArg.c: In function ‘real_array omc_ParArg_TestParArg(threadData_t*, modelica_real)’:
ParArg_TestParArg.c:41:66: error: could not convert ‘_pm’ from ‘device_real_array {aka dev_arr} to ‘real_array {aka base_array_s}   copy_real_array_data(omc_ParArg_multParArg(threadData, _pa, _pm), &_presult);
                                                                  ^
ParArg_TestParArg.c: In function ‘device_real_array omc_ParArg_multParArg(threadData_t*, modelica_real, real_array)’:
ParArg_TestParArg.c:142:54: error: call of overloaded ‘ocl_set_kernel_arg(_cl_kernel*&, int&, void*&) is ambiguous
   ocl_set_kernel_arg(tmp4, parfor_1_arg_nr, _mpm.data); ++parfor_1_arg_nr; 
                                                      ^
ParArg_TestParArg.c:142:54: note: candidates are:
In file included from ParArg_TestParArg.h:8:0,
                 from ParArg_TestParArg.c:1:
/home/gustaf/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/gustaf/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/gustaf/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/gustaf/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:143:50: error: ‘real_array’ has no member named ‘info_dev’
   ocl_set_kernel_arg(tmp4, parfor_1_arg_nr, _mpm.info_dev); ++parfor_1_arg_nr; 
                                                  ^
ParArg_TestParArg.c: In function ‘void* boxptr_ParArg_multParArg(threadData_t*, modelica_metatype, modelica_metatype)’:
ParArg_TestParArg.c:163:49: error: could not convert ‘_mpresult’ from ‘device_real_array {aka dev_arr} to ‘base_array_t {aka base_array_s}   out_mpresult = mmc_mk_modelica_array(_mpresult);
                                                 ^
ParArg_TestParArg.makefile:18: recipe for target 'ParArg_TestParArg' failed
make: *** [ParArg_TestParArg] Error 1

# Error encountered! Exiting...
# Please check the error message and the flags.

Execution failed!

Change History (5)

comment:1 by Gustaf Thorslund, 10 years ago

Description: modified (diff)

comment:2 by Mahder Alemseged Gebremedhin, 9 years ago

Resolution: fixed
Status: newclosed

comment:3 by Dietmar Winkler, 9 years ago

Milestone: Future1.9.4

Sorting these closed tickets away from "Future". Since they were closed after the last 1.9.3 release, it's very likely that they should have been part of the 1.9.4 release.

comment:4 by Martin Sjölund, 9 years ago

Milestone: 1.9.41.9.4-1.9.x

Milestone renamed

comment:5 by Martin Sjölund, 9 years ago

Milestone: 1.9.4-1.9.x1.9.4

Milestone renamed

Note: See TracTickets for help on using tickets.