Agent skill

int / if / output

General SOP for common requests related to int, if, output.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/int-if-output

SKILL.md

int / if / output

General SOP for common requests related to int, if, output.

Prompt

Follow this SOP (replace specifics with placeholders like <PROJECT>/<ENV>/<VERSION>):

  1. 你是一个cuda算子优化专家,熟悉算子优化的各种方法。\n###目标:利用 Shared Memory 缓存输入数据,减少全局内存访问,提升数据重用效率。\n###硬件信息:总共可以用的share memory大小为64k,考虑并行度,每个block最多只能分配16K,share memory里有32个bank,每个bank4字节\n###过程:\n1、每个 Block 分配 Shared Memory(限制为 16KB),用于存储输入数据子集。\n2、线程协作加载数据到 Shared Memory,确保合并访存。\n3、从 Shared Memory 读取数据计算输出,避免重复访问全局内存。\n4、有多个kernel时也可考虑kernel fuse成一个加快速\n###限制:\n1、不要改动{last_fuction}的接口\n2、给出的代码要可执行,不要引入新的include\n3、只输出修改后的完整代码\n4、不改变算子逻辑,保证优化前后{last_fuction}的输出一致,自适应不同的输入尺寸和对齐情况\n5、注意不要访存溢出\n6、确保线程束内访问连续且对齐,减少 Bank Conflict。避免bank conflit的方法:使用padding调整内存布局,转置访问模式,显式匹配bank数量(32)\n7、优化后的算子名称与优化前的保持一致\n8、请用以下格式输出优化后的代码cpp{{优化后的代码}}\n###示例\n####优化前代码示例\ntemplate <typename T>\n__global__ void ppl_cukernel_expand_opt(\n int64_t num_elems,\n int num_output_dim,\n GArray<DivModFast> output_strides_fast,\n GArray<int64_t> input_strides,\n const T input,\n T output)\n{\n int index = blockIdx.x blockDim.x + threadIdx.x;\n if (index >= num_elems)\n return;\n\n int64_t input_offset = 0;\n int idx, remain = index;\n #pragma unroll\n for (int it = 0; it < 4; ++it) {\n output_strides_fast[it].divmod(remain, idx, remain);\n input_offset += idx input_strides[it];\n }\n \n // 使用float4合并访存\n if (sizeof(T) == 4) {\n float4 val = reinterpret_cast<const float4*>(input)[input_offset / 4];\n reinterpret_cast<float4*>(output)[index / 4] = val;\n } else {\n output[index] = input[input_offset];\n }\n}\n\ntemplate <typename T>\nvoid test_tmp_kernel_opt(\n T* input, T* output,\n int in_batch, int in_height, int in_channels, int in_width,\n int out_batch, int out_height, int out_channels, int out_width,\n int in_elems, int out_elems,\n cudaStream_t stream)\n{\n int64_t num_elems = out_elems;\n int num_output_dim = 4;\n\n GArray<DivModFast> output_strides_fast(4);\n GArray<int64_t> input_strides(4);\n\n output_strides_fast[0] = DivModFast(out_height out_channels out_width);\n output_strides_fast[1] = DivModFast(out_channels out_width);\n output_strides_fast[2] = DivModFast(out_width);\n output_strides_fast[3] = DivModFast(1);\n\n input_strides[0] = in_height in_channels in_width;\n input_strides[1] = in_channels in_width;\n input_strides[2] = in_width;\n input_strides[3] = 1;\n\n const int block_size = 512;\n int grid_size = (num_elems + block_size - 1) / block_size;\n\n ppl_cukernel_expand_opt<<<grid_size, block_size, 0, stream>>>(\n num_elems, num_output_dim, output_strides_fast, input_strides, \n (const T )input, (T )output);\n}\n####优化后代码示例\ntemplate <typename T>\n__global__ void ppl_cukernel_expand_opt(\n int64_t num_elems,\n int num_output_dim,\n GArray<DivModFast> output_strides_fast,\n GArray<int64_t> input_strides,\n const T input,\n T output)\n{\n // 分配 Shared Memory,大小为 Block 处理的元素数(假设每个线程处理一个元素)\n extern shared T shm_input[];\n\n int index = blockIdx.x blockDim.x + threadIdx.x;\n if (index >= num_elems)\n return;\n\n // 计算输入偏移\n int64_t input_offset = 0;\n int idx, remain = index;\n #pragma unroll\n for (int it = 0; it < 4; ++it) {\n output_strides_fast[it].divmod(remain, idx, remain);\n input_offset += idx input_strides[it];\n }\n\n // 协作加载数据到 Shared Memory\n if (threadIdx.x < blockDim.x) {\n shm_input[threadIdx.x] = input[input_offset];\n }\n __syncthreads(); // 确保所有线程加载完成\n\n // 从 Shared Memory 读取并写入输出\n output[index] = shm_input[threadIdx.x];\n}\n\ntemplate <typename T>\nvoid test_tmp_kernel_opt(\n T* input, T* output,\n int in_batch, int in_height, int in_channels, int in_width,\n int out_batch, int out_height, int out_channels, int out_width,\n int in_elems, int out_elems,\n cudaStream_t stream)\n{\n int64_t num_elems = out_elems;\n int num_output_dim = 4;\n\n GArray<DivModFast> output_strides_fast(4);\n GArray<int64_t> input_strides(4);\n\n output_strides_fast[0] = DivModFast(out_height out_channels out_width);\n output_strides_fast[1] = DivModFast(out_channels out_width);\n output_strides_fast[2] = DivModFast(out_width);\n output_strides_fast[3] = DivModFast(1);\n\n input_strides[0] = in_height in_channels in_width;\n input_strides[1] = in_channels in_width;\n input_strides[2] = in_width;\n input_strides[3] = 1;\n\n const int block_size = 512;\n int grid_size = (num_elems + block_size - 1) / block_size;\n\n // 动态分配 Shared Memory 大小,每个 Block 分配 block_size sizeof(T)\n size_t shm_size = block_size sizeof(T); // 512 4 = 2KB,远小于16KB限制\n ppl_cukernel_expand_opt<<<grid_size, block_size, shm_size, stream>>>(\n num_elems, num_output_dim, output_strides_fast, input_strides, \n (const T )input, (T *)output);\n}\n
  2. user_prompt": "###目标初始原代码\ntemplate <typename T>\n__global__ void clamp_kernel_opt(\n const T* input, T* clamped_output, \n int num_elements, T min_val, T max_val) {\n int idx = blockIdx.x blockDim.x + threadIdx.x;\n if (idx < num_elements) {\n T val = input[idx];\n clamped_output[idx] = fminf(fmaxf(val, min_val), max_val);\n }\n}\n\n__global_ void convert_to_int64_kernel_opt(\n const float_ input, int64_t* output, \n int num_elements) {\n int idx = blockIdx.x blockDim.x + threadIdx.x;\n if (idx < num_elements) {\n output[idx] = static_cast<int64_t>(input[idx]);\n }\n}\n\n__global_ void count_nonzero_kernel_opt(\n const int64_t_ input, int64_t* output,\n int batch, int channels, int height, int width, int dim) {\n \n if (dim == 0) { // count along batch dimension\n int c = blockIdx.x / height;\n int h = blockIdx.x % height;\n int w = threadIdx.x;\n \n if (c < channels && h < height && w < width) {\n int64_t count = 0;\n for (int b = 0; b < batch; b++) {\n int idx = b channels height width + \n c height width + \n h width + w;\n if (input[idx] != 0) count++;\n }\n int out_idx = c height width + h width + w;\n output[out_idx] = count;\n }\n }\n}\n\ntemplate <typename T>\nvoid test_tmp_kernel_opt(\n T input, T* output,\n int in_batch, int in_height, int in_channels, int in_width,\n int out_batch, int out_height, int out_channels, int out_width,\n int in_elems, int out_elems,\n cudaStream_t stream) {\n \n T min_val = -1.0f;\n T max_val = 1.0f;\n int dim = 0;\n \n // Step 1: Clamp the input\n T* clamped_output;\n cudaMalloc((void**)&clamped_output, sizeof(T) in_elems);\n \n const int block_size = 256;\n int grid_size = (in_elems + block_size - 1) / block_size;\n clamp_kernel_opt<<<grid_size, block_size, 0, stream>>>(input, clamped_output, in_elems, min_val, max_val);\n \n // Step 2: Convert to int64_t\n int64_t int64_output;\n cudaMalloc((void**)&int64_output, sizeof(int64_t) in_elems);\n convert_to_int64_kernel_opt<<<grid_size, block_size, 0, stream>>>(clamped_output, int64_output, in_elems);\n \n // Step 3: Count non-zero along dim\n if (dim == 0) {\n dim3 block(out_width, 1, 1);\n dim3 grid(out_channels out_height, 1, 1);\n count_nonzero_kernel_opt<<<grid, block, 0, stream>>>(\n int64_output, (int64_t*)output,\n in_batch, in_channels, in_height, in_width, dim);\n }\n \n cudaFree(clamped_output);\n cudaFree(int64_output);\n}\n//ResultStruct result1 = test_tmp({16,256,3,256},{1,256,3,256}); // input NHCW 和output NHCW\n\n\n ###目标代码上一次优化返回template <typename T>\n__global__ void clamp_kernel_opt(\n const T* input, T* clamped_output, \n int num_elements, T min_val, T max_val) {\n int idx = blockIdx.x blockDim.x + threadIdx.x;\n if (idx < num_elements) {\n T val = input[idx];\n clamped_output[idx] = fminf(fmaxf(val, min_val), max_val);\n }\n}\n\n__global_ void convert_to_int64_kernel_opt(\n const float_ input, int64_t* output, \n int num_elements) {\n int idx = blockIdx.x blockDim.x + threadIdx.x;\n if (idx < num_elements) {\n output[idx] = static_cast<int64_t>(input[idx]);\n }\n}\n\n__global_ void count_nonzero_kernel_opt(\n const int64_t_ input, int64_t* output,\n int batch, int channels, int height, int width, int dim) {\n \n if (dim == 0) { // count along batch dimension\n int c = blockIdx.x / height;\n int h = blockIdx.x % height;\n int w = threadIdx.x;\n \n if (c < channels && h < height && w < width) {\n int64_t count = 0;\n for (int b = 0; b < batch; b++) {\n int idx = b channels height width + \n c height width + \n h width + w;\n if (input[idx] != 0) count++;\n }\n int out_idx = c height width + h width + w;\n output[out_idx] = count;\n }\n }\n}\n\ntemplate <typename T>\n__global_ void fused_clamp_convert_count_kernel(\n const T_ input, int64_t* output,\n int batch, int channels, int height, int width,\n T min_val, T max_val, int dim) {\n \n extern shared int64_t shm_counts[];\n \n int c = blockIdx.x / height;\n int h = blockIdx.x % height;\n int w = threadIdx.x;\n \n if (c >= channels || h >= height || w >= width) return;\n \n shm_counts[w] = 0;\n __syncthreads();\n\n for (int b = 0; b < batch; ++b) {\n int64_t input_idx = b channels height width + c height width + h width + w;\n T val = input[input_idx];\n T clamped_val = fminf(fmaxf(val, min_val), max_val);\n int64_t int_val = static_cast<int64_t>(clamped_val);\n if (int_val != 0) {\n atomicAdd(&shm_counts[w], 1);\n }\n }\n \n syncthreads();\n \n int64_t out_idx = c height width + h width + w;\n atomicAdd(&output[out_idx], shm_counts[w]);\n}\n\ntemplate <typename T>\nvoid test_tmp_kernel_opt(\n T input, T* output,\n int in_batch, int in_height, int in_channels, int in_width,\n int out_batch, int out_height, int out_channels, int out_width,\n int in_elems, int out_elems,\n cudaStream_t stream) {\n \n T min_val = -1.0f;\n T max_val = 1.0f;\n int dim = 0;\n \n if (dim == 0) {\n dim3 block(out_width);\n dim3 grid(out_channels out_height);\n size_t shm_size = out_width sizeof(int64_t);\n \n fused_clamp_convert_count_kernel<<<grid, block, shm_size, stream>>>(\n input, (int64_t*)output,\n in_batch, in_channels, in_height, in_width,\n min_val, max_val, dim);\n }\n}\n###代码执行报错:compile_info./inc/tmp_use.cuh:67:13: error: no matching function for call to 'atomicAdd'/./inc/tmp_use.cuh:74:5: error: no matching function for call to 'atomicAdd'/1 warning and 2 errors generated when compiling for xcore1000./make: *** [Makefile:25: test_maca] Error 1-run_info###代码再优化
  3. llm_response": "好的,我现在需要解决用户提供的CUDA代码中的错误。用户提到在编译时遇到了两个关于atomicAdd的错误,具体是在调用atomicAdd时没有匹配的函数。首先,我需要仔细检查这些错误出现的位置,并理解原因。\n\n查看用户提供的优化后代码,发现这两个错误发生在两个地方:\n\n1. 在fused_clamp_convert_count_kernel内核中,当尝试对shm_counts[w]使用atomicAdd时:\n cpp\n atomicAdd(&shm_counts[w], 1);\n \n2. 在写入输出时:\n cpp\n atomicAdd(&output[out_idx], shm_counts[w]);\n \n\n首先,分析第一个atomicAdd的错误。shm_counts被声明为int64_t类型的共享内存数组,而atomicAdd的第二个参数是整数1。CUDA的atomicAdd函数对于不同的数据类型有不同的实现。对于int64_t类型的指针,需要使用专门的函数,如atomicAdd(long long int address, long long int val)。但是,在CUDA中,可能在某些计算能力下不支持64位整数的原子操作,或者需要特定的函数名称。或者,用户可能误用了类型。\n\n接下来,检查第二个atomicAdd的错误。这里,output数组的类型是int64_t,同样尝试使用atomicAdd来累加shm_counts[w],而shm_counts的类型也是int64_t。同样可能因为数据类型的问题导致没有匹配的函数。\n\n在CUDA文档中查找,发现atomicAdd对64位整数的支持情况。根据CUDA的文档,从计算能力6.0开始,支持对64位全局内存地址的atomicAdd,但对于共享内存中的64位整数,可能不支持原子操作。此外,在共享内存中使用原子操作可能需要特别注意,因为共享内存的访问可能有bank冲突或者其他限制。\n\n另一个可能性是,atomicAdd的参数类型不匹配。例如,如果shm_counts是int64_t类型(即long long),那么正确的函数应该是atomicAdd_system,或者在CUDA中可能需要使用特定的函数,比如atomicAdd((unsigned long long*)address, val),但这也可能取决于具体的CUDA版本。\n\n不过,更常见的情况是,CUDA的atomicAdd对于int64_t在设备端的支持可能需要使用特定的函数。例如,对于全局内存中的int64_t,可以使用atomicAdd,但对于共享内存中的int64_t,可能无法直接使用,或者需要更高计算能力的设备。\n\n此外,用户可能在编译时没有指定正确的计算能力,导致编译器无法找到对应的atomicAdd函数。但用户提供的错误信息并没有提到计算能力的问题,所以更可能的是代码中的类型问题。\n\n接下来,我需要检查用户代码中的atomicAdd调用是否正确处理了int64_t类型。例如,在CUDA中,原子操作对于不同的数据类型有不同的函数,例如:\n\n- atomicAdd(int* address, int val)\n- atomicAdd(unsigned int* address, unsigned int val)\n- atomicAdd(unsigned long long int* address, unsigned long long int val)\n\n因此,对于int64_t类型(通常等同于long long),应使用unsigned long long的版本。或者,可能需要将参数强制转换为相应的类型。\n\n例如,将atomicAdd的调用改为:\n\natomicAdd(reinterpret_cast<unsigned long long*>(&shm_counts[w]), 1ULL);\n\n或者,使用内置的原子函数,如:\n\n__atomic_add_fetch(&shm_counts[w], 1, ATOMIC_RELAXED);\n\n但CUDA可能不支持GCC风格的原子操作,所以这可能需要调整。\n\n不过,CUDA的原子操作函数通常以函数形式提供,如atomicAdd。因此,正确的做法是确保参数类型正确。对于int64_t(long long),正确的函数是:\n\nlong long int atomicAdd(long long int* address, long long int val);\n\n所以,正确的调用应该是:\n\natomicAdd(reinterpret_cast<long long*>(&shm_counts[w]), 1LL);\n\n同样,对于output数组,output的类型是int64_t*,所以应该使用同样的方式:\n\natomicAdd(reinterpret_cast<long long*>(&output[out_idx]), shm_counts[w]);\n\n或者,将shm_counts[w]转换为long long类型。\n\n另外,注意到在shared memory中的shm_counts是int64_t类型,每个线程处理一个w的位置。当多个线程尝试对同一个shm_counts[w]进行原子操作时,实际上每个w对应不同的位置,所以不会有竞争条件,因此可能不需要原子操作。例如,每个线程处理不同的w,因此shm_counts的每个元素只被一个线程访问。这时候,原子操作可能是不必要的,这可能是一个逻辑错误。\n\n例如,在代码中,block的维度是out_width,每个线程的threadIdx.x对应w。因此,每个线程处理不同的w,所以shm_counts的索引是w,每个线程只操作自己的shm_counts[w]。因此,在这种情况下,对shm_counts[w]的累加不需要原子操作,因为每个w对应唯一的线程。同样,当从共享内存写入到全局内存时,每个线程写入不同的out_idx,因此也不需要原子操作。因此,原来的atomicAdd在这里是多余的,应该直接使用普通的赋值或者非原子操作。\n\n这可能才是问题的根本原因。用户错误地使用了原子操作,但实际上每个线程处理不同的w,没有冲突,因此不需要原子操作。所以,可以替换为简单的赋值或加法。\n\n现在,重新检查内核函数的结构:\n\n在fused_clamp_convert_count_kernel中,block的维度是out_width,即每个block有out_width个线程,每个线程处理一个特定的w。blockIdx.x的计算是c = blockIdx.x / height,h = blockIdx.x % height。每个block处理一个(c, h)的组合,每个线程处理该位置下的不同w。\n\n在循环中,每个线程遍历所有batch,对于每个batch,计算input_idx,然后进行clamp和转换。如果int_val不为0,则对shm_counts[w]进行原子加1。但这里,每个线程的w是唯一的,因为线程的threadIdx.x就是w,所以同一block中的不同线程处理不同的w。因此,每个shm_counts[w]仅被一个线程访问,所以在循环中的累加不需要原子操作。因为每个线程的w是唯一的,所以不存在多个线程同时访问同一个shm_counts[w]的情况。因此,可以直接使用普通的加法,比如shm_counts[w] += 1。\n\n同样,当最后将shm_counts[w]写入到全局内存时,每个out_idx对应唯一的(c, h, w),所以不需要原子操作,直接赋值即可。\n\n因此,错误的原因在于错误地使用了原子操作,而实际上并不需要。这导致编译错误,因为CUDA的atomicAdd对于int64_t类型可能需要特定的处理,或者因为参数类型不匹配。\n\n因此,正确的修改应该是将atomicAdd替换为非原子操作:\n\n在循环内部:\n\nif (int_val != 0) {\n shm_counts[w] += 1;\n}\n\n而在写入全局内存时:\n\noutput[out_idx] = shm_counts[w];\n\n这样,就不会出现原子操作的问题,同时修复了编译错误,并且提高效率,因为原子操作通常是较慢的。\n\n此外,检查共享内存的初始化。在代码中,每个线程初始化自己的shm_counts[w]为0,因为每个线程处理自己的w,这没问题。然后,在循环结束后,将结果写入全局内存。\n\n所以,总结问题所在:\n\n1. 在shm_counts的累加和输出写入时错误地使用了原子操作,而实际上不需要。\n2. atomicAdd的参数类型可能不正确,导致编译器找不到匹配的函数。\n\n因此,正确的修改是移除atomicAdd,改为直接操作。\n\n现在,修改后的内核函数应该如下:\n\n__global void fused_clamp_convert_count_kernel(\n const T* input, int64_t* output,\n int batch, int channels, int height, int width,\n T min_val, T max_val, int dim) {\n \n extern shared int64_t shm_counts[];\n \n int c = blockIdx.x / height;\n int h = blockIdx.x % height;\n int w = threadIdx.x;\n \n if (c >= channels || h >= height || w >= width) return;\n \n shm_counts[w] = 0;\n __syncthreads();\n\n for (int b = 0; b < batch; ++b) {\n int64_t input_idx = b channels height width + c height width + h width + w;\n T val = input[input_idx];\n T clamped_val = fminf(fmaxf(val, min_val), max_val);\n int64_t int_val = static_cast<int64_t>(clamped_val);\n if (int_val != 0) {\n shm_counts[w] += 1; // 移除atomicAdd\n }\n }\n \n _syncthreads();\n \n int64_t out_idx = c height width + h width + w;\n output[out_idx] = shm_counts[w]; // 移除atomicAdd\n}\n\n这样,就不再需要调用atomicAdd,从而避免了编译错误,同时正确执行。\n\n此外,需要检查输入参数是否正确。例如,当dim不等于0时,代码是否有处理,但根据用户提供的test_tmp_kernel_opt函数中的调用,dim始终设为0,所以可以暂时忽略其他情况。\n\n另外,在用户提供的test_tmp_kernel_opt函数中,最后调用了fused_clamp_convert_count_kernel,而原来的代码中输出是T_类型,但内核函数中的输出是int64_t*。这可能存在问题,因为用户传入的output可能是T类型,而T可能是float或其他类型。例如,在用户提供的test_tmp_kernel_opt的调用示例中,output被转换为int64_t,但原函数参数中的output是T类型。如果T是float,这会导致类型不匹配的问题。但在用户提供的示例中,test_tmp_kernel_opt的模板参数是float,因此转换为int64_t可能会有问题。不过,用户的问题描述中提到test_tmp_kernel_opt的输出应与优化前一致,而原来的count_nonzero_kernel_opt的输出是int64_t类型。因此,正确的做法是确保test_tmp_kernel_opt的output参数的类型为int64_t*。但用户的原代码中,output的类型是T*,而用户提供的测试示例可能传递了正确的类型。因此,这可能需要调整函数参数的类型,但用户可能希望保持接口不变。此时需要检查用户提供的初始代码。\n\n在用户原来的test_tmp_kernel_opt函数中,输出的类型是T*,但在调用count_nonzero_kernel_opt时,将output强制转换为int64_t*。这可能意味着用户期望test_tmp_kernel_opt的输出实际上是int64_t类型。但原函数声明中的output是T*,这可能导致类型不匹配。比如,当T是float时,转换会导致错误。这可能是一个错误,但在用户提供的示例中,调用test_tmp时,output的类型应该是int64_t*,而不是float*。因此,可能用户的原代码存在接口设计问题,但在问题中可能需要保持接口不变,所以这可能需要调整函数参数。但用户要求不要改动last_function的接口,即test_tmp_kernel_opt的参数必须保持T* input和T* output。这会导致问题,因为count_nonzero的输出是int64_t,而output是T类型,如果T不是int64_t,就会导致类型错误。因此,这可能是一个设计错误,但用户可能希望保持接口不变,但实际在调用时,传入的output应该是int64_t的缓冲区。例如,在用户提供的示例中,ResultStruct result1 = test_tmp(...), 这里的output可能应该是一个int64_t数组,但被强制转换为float。这可能导致数据错误,但用户的问题可能属于代码的其他部分,而当前的任务是修复编译错误。\n\n不过,这可能超出了当前的问题范围。当前的主要任务是修复atomicAdd的编译错误。因此,回到之前的修改,移除atomicAdd的使用即可解决问题。\n\n综上,正确的修改是移除两个atomicAdd调用,改为直接操作。这样,编译错误就不会出现,同时保证正确性。\n\n```cpp\ntemplate <typename T>\n__global void fused_clamp_convert_count_kernel(\n const T* input, int64_t* output,\n int batch, int channels, int height, int width,\n T min_val, T max_val, int dim) {\n \n extern shared int64_t shm_counts[];\n \n int c = blockIdx.x / height;\n int h = blockIdx.x % height;\n int w = threadIdx.x;\n \n if (c >= channels || h >= height || w >= width) return;\n \n shm_counts[w] = 0;\n __syncthreads();\n\n for (int b = 0; b < batch; ++b) {\n int64_t input_idx = b channels height width + c height width + h width + w;\n T val = input[input_idx];\n T clamped_val = fminf(fmaxf(val, min_val), max_val);\n int64_t int_val = static_cast<int64_t>(clamped_val);\n if (int_val != 0) {\n shm_counts[w] += 1; // Remove atomic operation for thread-private access\n }\n }\n \n __syncthreads();\n \n int64_t out_idx = c height width + h width + w;\n output[out_idx] = shm_counts[w]; // Direct write without atomic\n}\n\ntemplate <typename T>\nvoid test_tmp_kernel_opt(\n T input, T* output,\n int in_batch, int in_height, int in_channels, int in_width,\n int out_batch, int out_height, int out_channels, int out_width,\n int in_elems, int out_elems,\n cudaStream_t stream) {\n \n T min_val = -1.0f;\n T max_val = 1.0f;\n int dim = 0;\n \n if (dim == 0) {\n dim3 block(out_width);\n dim3 grid(out_channels out_height);\n size_t shm_size = out_width sizeof(int64_t);\n \n fused_clamp_convert_count_kernel<<<grid, block, shm_size, stream>>>(\n input, (int64_t*)output,\n in_batch, in_channels, in_height, in_width,\n min_val, max_val, dim);\n }\n}\n
  4. step": 3
  5. parent_id": "6cbd6f54-b27b-45d4-a256-50e4258f0b6a
  6. child_id": "d779a89c-0ded-44f4-a1e6-04411149ae07
  7. parent_metrics
  8. compile_ok": true
  9. precision_ok": true
  10. time_after_opt": 0.047747

For each step, include: action, checks, and failure rollback/fallback plan. Output format: for each step number, provide status/result and what to do next.

Triggers

  • Use when the user asks for a process or checklist.
  • Use when you want to reuse a previously mentioned method/SOP.

Examples

Example 1

Input:

Break this into best-practice, executable steps.

Expand your agent's capabilities with these related and highly-rated skills.

Didn't find tool you were looking for?

Be as detailed as possible for better results