#for-loop #parallel-processing #dpc
# #для цикла #параллельная обработка #dpc
Вопрос:
Здравствуйте, я пытаюсь распараллелить два моих цикла с помощью DPC , но это выдает ОШИБКУ LLVM: внутренняя ошибка SPIRV. Я не знаю почему, не могли бы вы, ребята, помочь мне разобраться в проблеме?
char* rsa_decrypt_without_private_key(const long long* message, const unsigned long message_size, const struct public_key_class* pub)
{
struct private_key_class unknownpriv[1];
long long p, q, phi_max, e, d;
p = public_prime;
q = pub->modulus / p;
phi_max = (p - 1) * (q - 1);
e = powl(2, 8) 1;
d = ExtEuclid(phi_max, e);
while (d < 0) {
d = d phi_max;
}
unknownpriv->modulus = pub->modulus;
unknownpriv->exponent = d;
if (message_size % sizeof(long long) != 0) {
fprintf(stderr, "Error: message_size is not divisible by %d, so cannot be output of rsa_encryptn", (int)sizeof(long long));
return NULL;
}
char* decrypted = (char*) malloc(message_size / sizeof(long long));
char* temp = (char*) malloc(message_size);
if ((decrypted == NULL) || (temp == NULL)) {
fprintf(stderr, "Error: Heap allocation failed.n");
return NULL;
}
buffer<char, 1> A(decrypted, range<1>{ message_size / sizeof(long long)});
buffer<char, 1> B(temp, range<1>{ message_size });
auto R = range<1>{ message_size / 8 };
queue z;
z.submit([amp;](handleramp; h) {
auto out = B.get_access<access::mode::write>(h);
h.parallel_for(R, [=](id<1> i) {
out[i] = rsa_modExp(message[i], unknownpriv->exponent, unknownpriv->modulus);
});
});
z.submit([amp;](handleramp; h) {
auto out = A.get_access<access::mode::write>(h);
auto in = B.get_access<access::mode::read>(h);
h.parallel_for(R, [=](id<1> i) {
out[i] = in[i];
});
});
/*
for (i = 0; i < message_size / 8; i ) {
temp[i] = rsa_modExp(message[i], unknownpriv->exponent, unknownpriv->modulus);
}
for (i = 0; i < message_size / 8; i ) {
decrypted[i] = temp[i];
}*/
free(temp);
return decrypted;
}
Ответ №1:
Поскольку вы пытаетесь вызвать функцию (rsa_modExp) внутри parallel_for kernel, вам нужно убедиться, что функция присутствует в той же единице преобразования.
Когда мы хотим вызвать функции внутри ядра, которые определены в другой трансляционной единице, эти функции должны быть помечены символом SYCL_EXTERNAL . Без этого атрибута компилятор будет компилировать функцию только для использования вне кода устройства (что делает незаконным вызов этой внешней функции из кода устройства).
Ссылка на книгу DPC для дальнейшего ознакомления: https://www.apress.com/us/book/9781484255735 (Глава 13)