Следующий код не компилируется. Сообщения об ошибках:
Ошибка 1:
error C3930: 'foo' : no overloaded function has restriction specifiers that are compatible with the ambient context ''
Ошибка 2:
error C2660: 'f1' : function does not take 0 arguments
Ошибка 3:
IntelliSense: amp-restricted function "int foo() restrict(amp)" (declared at line 5) must be called from an amp-restricted function
Программа:
#include <amp.h>
#include <iostream>
using namespace std;
int foo() restrict(amp) { return 5; }
int f1(int x = foo()) restrict(amp) {
return x;
}
int main()
{
using namespace concurrency;
int a[10] = {0};
array_view<int> av(10, a);
parallel_for_each(av.extent, [=](index<1> i) restrict(amp) {
av[i] = f1();
});
for(unsigned i=0; i<10; ++i) {
cout << av[i] << "\n";
}
return 0;
}
Странно, когда я удаляю restrict(amp)
на foo()
и заменить вызов f1()
в лямбде с, скажем, 5
, программа компилируется нормально. Итак, каковы правила вызова функций в аргументах по умолчанию для функций amp?
MSDN Форум ответ к вопросу.
Семантика выбранных нами аргументов по умолчанию согласуется с общей предпосылкой C ++, заключающейся в том, что синтаксический анализ программы выполняется за один проход слева направо (несмотря на несколько существенных исключений из этого правила, в частности, функций-членов) — поэтому, поскольку спецификатор ограничения читается после объявления параметра функции, любые вызовы функций, расположенные в выражениях аргументов по умолчанию, связаны в соответствии с «внешней» спецификацией ограничения, к лучшему или к худшему. Другими словами, вы читаете программу с самого начала с ограничением cpu «active» (потому что оно используется по умолчанию) и переключаетесь на ограничение X для всего, что находится между «restrict (X)» и «}», закрывая соответствующую область.
Других решений пока нет …