Intel® oneAPI Data Parallel C++
Support for Intel® oneAPI DPC++ Compiler, Intel® oneAPI DPC++ Library, Intel ICX Compiler , Intel® DPC++ Compatibility Tool, and GDB*

error: expression is not assignable

giltirn
Novice
2,572 Views

Hi All,

I have a very simple "view" class

 

class MyBase{
protected:
  size_t sz;
  double* v;
public:
  inline double &operator[](const size_t i){ return v[i]; }
  inline double operator[](const size_t i) const{ return v[i]; }
};

 

that acts as the base class of the MyContainer class (which contains the allocation and non-trivial functionality) in order to get around the burdensome restriction that objects accessed inside kernels must be trivially constructible. The allocation in MyContainer is performed with managed memory.

I have a very simple kernel:

 

      dv[i] = cv[i]*cv[i];

 

where dv and cv are MyBase&  references. This fails to compile under oneapi/2020.12.15.005 on JLSE with the following error:

test_a2a.C:95:13: error: expression is not assignable
dv[i] = cv[i]*cv[i];

The code is obviously correct and compiles if I replace the accelerator loop with a regular for loop.

Attached is the code. To make:

 

test_a2a: test_a2a.C
	dpcpp test_a2a.C -o test_a2a  -fsycl-device-code-split=per_kernel -fsycl-device-lib=all

 

I would appreciate any help.

0 Kudos
6 Replies
giltirn
Novice
2,520 Views

Follow-up: I've been able to bypass the compile error by replacing

inline double &operator[](const size_t i){ return v[i]; }

with

inline double &operator[](const size_t i) const{ return v[i]; }

Thus it seems that the kernel is capturing all variables as const. The above seems like a syntactic abuse of the meaning of a const method to me, is this truly the "blessed" way of writing an accessor in DPC++??

 

0 Kudos
GouthamK_Intel
Moderator
2,479 Views

Hi Christopher,

Thanks for providing the source code and steps to reproduce your issue. We are able to reproduce the error which you are facing. We are working on it internally we will get back to you soon.

However, as mentioned by you after adding const to the operator overloading "expression is not assignable" error was resolved whereas we got another error saying "error: functions that differ only in their return type cannot be overloaded". We can see that you are trying to overload the operator twice. Could you please let us know is there any specific reason behind it? However, when we commented out one of the lines, we are able to compile and run the code successfully.

 inline double &operator[](const size_t i) const{ return v[i]; }
 // inline double operator[](const size_t i) const{ return v[i]; }

when we try to print the values of dv[i]

the first 10 values are as follows.

 

5.26354e-315 0 0 0 4.94066e-324 4.94066e-324 0 4.94066e-324 0 0

 

is this the expected behaviour? If not, please let us know the expected behavior of the code.

 

Regards

Goutham

 

0 Kudos
giltirn
Novice
2,474 Views

Hi Goutham,

I apologize, I should have mentioned that I also removed the other accessor. Adding it back in I see the same error as you.

Regarding the output you quoted, the code provided is a minimal example of the compile issue and wasn't intended to actually do any relevant computation. The contents of the memory are not initialized so random nonsense is what I would expect to see if run.

Best,
Chris

 

0 Kudos
GouthamK_Intel
Moderator
2,443 Views

Hi Christopher,

We are working on your thread internally, we will get back to you soon.


Regards

Goutham


0 Kudos
ErichKeane
Employee
2,399 Views

Hi Chris-

The problem is that dv and cv are being captured in the lambda by 'copy', see here for clarification on how lambda captures work: https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture

Lambda objects (that is, the anonymous type that backs the lambda function) are const-by-default, so all their fields are as well.  In this case, the 'dv[i]' being referred to in the expression in question is actually a sliced copy of 'dv' from the larger scope.  That copy is 'const', since the lambda is const.

Someone with better familiarity with the SYCL library can better clarify the 'right' way to modify host-state from a kernel, but I believe you are supposed to use accessors and buffers for that purpose.

0 Kudos
Alina_S_Intel
Employee
2,250 Views

Mutable lambda could be a solution but it is not allowed by the compiler at this moment.


We will no longer respond to this thread.  

If you require additional assistance from Intel, please start a new thread. Any further interaction in this thread will be considered community only.

Thanks,


0 Kudos
Reply