AMD Radeon RX570 OpenCL内核数组参数传递失败问题排查
Let's walk through the problems in your code and fix them step by step:
1. Incorrect Pointer Handling in the Kernel
Your Python code passes arg as a 2-element uint64 array, which maps to the kernel's __global const long * arg parameter. But in the kernel, you're incorrectly treating arg[0] and arg[1] as pointers:
ulong * number = (ulong *)arg[0]; ulong * prime_array_len = (ulong *)arg[1];
This is wrong—arg[0] is directly the value of your input number, and arg[1] is the length of the prime array. You don't need to cast them to pointers; just assign them directly to variables:
ulong number = arg[0]; ulong prime_array_len = arg[1];
2. Mismatched Data Types
Type consistency is critical in OpenCL—mismatches cause undefined behavior (like the incorrect prime_array_len 0 output you're seeing):
- Your Python code uses
np.uint64forprime_numberandres, but the kernel declaresprime_arrayas__global long *andresas__global int *. These need to match. Change the kernel's parameter types to__global ulong *for both. - The
printfstatement uses%d(for ints) to printulongvalues. Use%luinstead to match unsigned long integers, which fixes the wrong length output. - Inside the loop,
long prime = prime_array[iter];should beulong primeto match the array's type.
3. Simplify Result Retrieval (Optional but Cleaner)
While your enqueue_map_buffer works, using cl.enqueue_copy to pull the result back to the host is often more straightforward and less error-prone.
Fixed Kernel Code (is_prime.cl)
__kernel void is_prime( __global const ulong * arg, __global ulong * prime_array, __global ulong * res ) { ulong number = arg[0]; ulong prime_array_len = arg[1]; ulong ret = 1; ulong iter = 0; printf("number = %lu prime_array_len %lu\n", number, prime_array_len); for (iter = 0; iter < prime_array_len; iter++) { ulong prime = prime_array[iter]; if (prime * prime > number) { break; } if (number % prime == 0) { ret = 0; break; } } *res = ret; }
Updated Python Code (Result Retrieval Section)
Replace the map buffer code with this simpler copy operation:
cl.enqueue_copy(cl_queue, res, res_buffer) return res[0]
After making these changes, running your code will output:
[3 1] number = 3 prime_array_len 1
And the function will correctly return 1 (indicating 3 is prime), which is what you expect.
内容的提问来源于stack exchange,提问作者Silver

