PTX and SASS (Nvidia)¶

C Kernel to Source Code¶

In [2]:
import numpy as np
import pyopencl as cl
import pyopencl.array as cla

ctx = cl.create_some_context(answers=["nvi", 0])
queue = cl.CommandQueue(ctx)
In [3]:
prg = cl.Program(ctx, """
__kernel void sum(
    __global const float *a_g, __global const float *b_g, __global float *res_g)
{
  int gid = get_global_id(0);
  res_g[gid] = a_g[gid] + b_g[gid];
}
""").build()

print(prg.binaries[0].decode())
//
// Generated by NVIDIA NVVM Compiler
//
// Compiler Build ID: CL-35042711
// Unknown Toolkit Version
// Based on NVVM 7.0.1
//

.version 8.2
.target sm_70, texmode_independent
.address_size 64

	// .globl	sum

.entry sum(
	.param .u64 .ptr .global .align 4 sum_param_0,
	.param .u64 .ptr .global .align 4 sum_param_1,
	.param .u64 .ptr .global .align 4 sum_param_2
)
{
	.reg .f32 	%f<4>;
	.reg .b32 	%r<7>;
	.reg .b64 	%rd<8>;


	ld.param.u64 	%rd1, [sum_param_0];
	ld.param.u64 	%rd2, [sum_param_1];
	ld.param.u64 	%rd3, [sum_param_2];
	mov.b32 	%r1, %envreg3;
	mov.u32 	%r2, %ntid.x;
	mov.u32 	%r3, %ctaid.x;
	mov.u32 	%r4, %tid.x;
	add.s32 	%r5, %r4, %r1;
	mad.lo.s32 	%r6, %r2, %r3, %r5;
	mul.wide.s32 	%rd4, %r6, 4;
	add.s64 	%rd5, %rd1, %rd4;
	ld.global.f32 	%f1, [%rd5];
	add.s64 	%rd6, %rd2, %rd4;
	ld.global.f32 	%f2, [%rd6];
	add.f32 	%f3, %f1, %f2;
	add.s64 	%rd7, %rd3, %rd4;
	st.global.f32 	[%rd7], %f3;
	ret;

}


Comments:

  • Intel or AT&T style?
  • Note: address spaces always explicit
  • What is ctaid.x? %ntid.x?
  • How does parameter passing work?
  • Is this the lowest-level abstraction?
In [10]:
!mkdir -p tmp

binary = prg.binaries[0]

with open("tmp/binary.ptx", "wb") as outf:
    outf.write(hacked_binary)
    
!(cd tmp; ptxas --gpu-name sm_70 --verbose binary.ptx -o binary.o)
ptxas info    : 0 bytes gmem
ptxas info    : Compiling entry function 'sum' for 'sm_70'
ptxas info    : Function properties for sum
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info    : Used 12 registers, 376 bytes cmem[0]
In [11]:
!cuobjdump --dump-sass tmp/binary.o
	code for sm_70
		Function : sum
	.headerflags	@"EF_CUDA_TEXMODE_INDEPENDENT EF_CUDA_64BIT_ADDRESS EF_CUDA_SM70 EF_CUDA_VIRTUAL_SM(EF_CUDA_SM70)"
        /*0000*/                   MOV R1, c[0x0][0x28] ;                 /* 0x00000a0000017a02 */
                                                                          /* 0x000fc40000000f00 */
        /*0010*/              @!PT SHFL.IDX PT, RZ, RZ, RZ, RZ ;          /* 0x000000fffffff389 */
                                                                          /* 0x000fe200000e00ff */
        /*0020*/                   S2R R0, SR_TID.X ;                     /* 0x0000000000007919 */
                                                                          /* 0x000e220000002100 */
        /*0030*/                   MOV R7, 0x4 ;                          /* 0x0000000400077802 */
                                                                          /* 0x000fc60000000f00 */
        /*0040*/                   S2R R3, SR_CTAID.X ;                   /* 0x0000000000037919 */
                                                                          /* 0x000e620000002500 */
        /*0050*/                   IADD3 R0, R0, c[0x0][0x94], RZ ;       /* 0x0000250000007a10 */
                                                                          /* 0x001fca0007ffe0ff */
        /*0060*/                   IMAD R0, R3, c[0x0][0x0], R0 ;         /* 0x0000000003007a24 */
                                                                          /* 0x002fc800078e0200 */
        /*0070*/                   IMAD.WIDE R2, R0, R7, c[0x0][0x160] ;  /* 0x0000580000027625 */
                                                                          /* 0x000fc800078e0207 */
        /*0080*/                   IMAD.WIDE R4, R0, R7, c[0x0][0x168] ;  /* 0x00005a0000047625 */
                                                                          /* 0x000fc800078e0207 */
        /*0090*/                   LDG.E.SYS R2, [R2] ;                   /* 0x0000000002027381 */
                                                                          /* 0x000ea800001ee900 */
        /*00a0*/                   LDG.E.SYS R5, [R4] ;                   /* 0x0000000004057381 */
                                                                          /* 0x000ea200001ee900 */
        /*00b0*/                   IMAD.WIDE R6, R0, R7, c[0x0][0x170] ;  /* 0x00005c0000067625 */
                                                                          /* 0x000fc800078e0207 */
        /*00c0*/                   FADD R9, R2, R5 ;                      /* 0x0000000502097221 */
                                                                          /* 0x004fd00000000000 */
        /*00d0*/                   STG.E.SYS [R6], R9 ;                   /* 0x0000000906007386 */
                                                                          /* 0x000fe2000010e900 */
        /*00e0*/                   EXIT ;                                 /* 0x000000000000794d */
                                                                          /* 0x000fea0003800000 */
        /*00f0*/                   BRA 0xf0;                              /* 0xfffffff000007947 */
                                                                          /* 0x000fc0000383ffff */
		..........


Is Division Expensive?¶

In [13]:
prg = cl.Program(ctx, """
__kernel void sum(
    __global float *a_g, int n)
{
    int gid = get_global_id(0);
    
    // try dividing by n
    
    int row = gid / 117;
    int col = gid % 117;
    
    a_g[row * 128 + col] *= 2;
    // a_g[gid] *= 2;
    
}
""").build()

binary = prg.binaries[0]

with open("tmp/binary.ptx", "wb") as outf:
    outf.write(hacked_binary)
    
!(cd tmp; ptxas --gpu-name sm_70 --verbose binary.ptx -o binary.o)
!cuobjdump --dump-sass tmp/binary.o | cut -c -80
ptxas info    : 0 bytes gmem
ptxas info    : Compiling entry function 'sum' for 'sm_70'
ptxas info    : Function properties for sum
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info    : Used 12 registers, 376 bytes cmem[0]

	code for sm_70
		Function : sum
	.headerflags	@"EF_CUDA_TEXMODE_INDEPENDENT EF_CUDA_64BIT_ADDRESS EF_CUDA_SM70 E
        /*0000*/                   MOV R1, c[0x0][0x28] ;                 /* 0x0
                                                                          /* 0x0
        /*0010*/              @!PT SHFL.IDX PT, RZ, RZ, RZ, RZ ;          /* 0x0
                                                                          /* 0x0
        /*0020*/                   S2R R0, SR_TID.X ;                     /* 0x0
                                                                          /* 0x0
        /*0030*/                   MOV R7, 0x4 ;                          /* 0x0
                                                                          /* 0x0
        /*0040*/                   S2R R3, SR_CTAID.X ;                   /* 0x0
                                                                          /* 0x0
        /*0050*/                   IADD3 R0, R0, c[0x0][0x94], RZ ;       /* 0x0
                                                                          /* 0x0
        /*0060*/                   IMAD R0, R3, c[0x0][0x0], R0 ;         /* 0x0
                                                                          /* 0x0
        /*0070*/                   IMAD.WIDE R2, R0, R7, c[0x0][0x160] ;  /* 0x0
                                                                          /* 0x0
        /*0080*/                   IMAD.WIDE R4, R0, R7, c[0x0][0x168] ;  /* 0x0
                                                                          /* 0x0
        /*0090*/                   LDG.E.SYS R2, [R2] ;                   /* 0x0
                                                                          /* 0x0
        /*00a0*/                   LDG.E.SYS R5, [R4] ;                   /* 0x0
                                                                          /* 0x0
        /*00b0*/                   IMAD.WIDE R6, R0, R7, c[0x0][0x170] ;  /* 0x0
                                                                          /* 0x0
        /*00c0*/                   FADD R9, R2, R5 ;                      /* 0x0
                                                                          /* 0x0
        /*00d0*/                   STG.E.SYS [R6], R9 ;                   /* 0x0
                                                                          /* 0x0
        /*00e0*/                   EXIT ;                                 /* 0x0
                                                                          /* 0x0
        /*00f0*/                   BRA 0xf0;                              /* 0xf
                                                                          /* 0x0
		..........


An Example with Control Flow¶

In [18]:
prg = cl.Program(ctx, """
__kernel void sum(
    __global const float *a_g, __global const float *b_g, __global float *res_g, int n)
{
    int gsize = get_global_size(0);
    
    for (int i = get_global_id(0); i < n; i += gsize)
      res_g[i] = a_g[i] + b_g[i];
      
    res_g[get_global_id(0)] = 15;
}
""").build()

binary = prg.binaries[0]
#print(binary.decode())
with open("tmp/binary.ptx", "wb") as outf:
    outf.write(binary)
    
!(cd tmp; ptxas --gpu-name sm_70 --verbose binary.ptx -o binary.o)
!cuobjdump --dump-sass tmp/binary.o | cut -c -80
ptxas info    : 0 bytes gmem
ptxas info    : Compiling entry function 'sum' for 'sm_70'
ptxas info    : Function properties for sum
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info    : Used 28 registers, 380 bytes cmem[0]

	code for sm_70
		Function : sum
	.headerflags	@"EF_CUDA_TEXMODE_INDEPENDENT EF_CUDA_64BIT_ADDRESS EF_CUDA_SM70 E
        /*0000*/                   IMAD.MOV.U32 R1, RZ, RZ, c[0x0][0x28] ;      
                                                                                
        /*0010*/              @!PT SHFL.IDX PT, RZ, RZ, RZ, RZ ;                
                                                                                
        /*0020*/                   S2R R0, SR_TID.X ;                           
                                                                                
        /*0030*/                   BMOV.32.CLEAR RZ, B0 ;                       
                                                                                
        /*0040*/                   BSSY B0, 0x670 ;                             
                                                                                
        /*0050*/                   S2R R3, SR_CTAID.X ;                         
                                                                                
        /*0060*/                   IADD3 R0, R0, c[0x0][0x94], RZ ;             
                                                                                
        /*0070*/                   IMAD R0, R3, c[0x0][0x0], R0 ;               
                                                                                
        /*0080*/                   ISETP.GE.AND P0, PT, R0, c[0x0][0x178], PT ; 
                                                                                
        /*0090*/                   SHF.R.S32.HI R3, RZ, 0x1f, R0 ;              
                                                                                
        /*00a0*/               @P0 BRA 0x660 ;                                  
                                                                                
        /*00b0*/                   IMAD.MOV.U32 R2, RZ, RZ, c[0x0][0x0] ;       
                                                                                
        /*00c0*/                   MOV R6, RZ ;                                 
                                                                                
        /*00d0*/                   IMAD.MOV.U32 R5, RZ, RZ, R0 ;                
                                                                                
        /*00e0*/                   BMOV.32.CLEAR RZ, B1 ;                       
                                                                                
        /*00f0*/                   IMAD R2, R2, c[0x0][0xa0], RZ ;              
                                                                                
        /*0100*/                   BSSY B1, 0x440 ;                             
                                                                                
        /*0110*/                   LOP3.LUT R4, RZ, R5, RZ, 0x33, !PT ;         
                                                                                
        /*0120*/                   IADD3 R9, RZ, -R2, RZ ;                      
                                                                                
        /*0130*/                   I2F.U32.RP R8, R2 ;                          
                                                                                
        /*0140*/                   ISETP.NE.U32.AND P2, PT, R2, RZ, PT ;        
                                                                                
        /*0150*/                   MUFU.RCP R8, R8 ;                            
                                                                                
        /*0160*/                   IADD3 R10, R8, 0xffffffe, RZ ;               
                                                                                
        /*0170*/                   F2I.FTZ.U32.TRUNC.NTZ R7, R10 ;              
                                                                                
        /*0180*/                   IMAD R9, R9, R7, RZ ;                        
                                                                                
        /*0190*/                   IMAD.WIDE.U32 R6, R7, R9, R6 ;               
                                                                                
        /*01a0*/                   IADD3 R9, R4, c[0x0][0x178], RZ ;            
                                                                                
        /*01b0*/                   IMAD.WIDE.U32 R6, R7, R9, RZ ;               
                                                                                
        /*01c0*/                   IMAD.MOV R4, RZ, RZ, -R7 ;                   
                                                                                
        /*01d0*/                   IMAD R9, R2, R4, R9 ;                        
                                                                                
        /*01e0*/                   ISETP.GE.U32.AND P0, PT, R9, R2, PT ;        
                                                                                
        /*01f0*/               @P0 IADD3 R9, -R2, R9, RZ ;                      
                                                                                
        /*0200*/               @P0 IADD3 R7, R7, 0x1, RZ ;                      
                                                                                
        /*0210*/                   ISETP.GE.U32.AND P1, PT, R9, R2, PT ;        
                                                                                
        /*0220*/               @P1 IADD3 R7, R7, 0x1, RZ ;                      
                                                                                
        /*0230*/              @!P2 LOP3.LUT R7, RZ, R2, RZ, 0x33, !PT ;         
                                                                                
        /*0240*/                   IADD3 R4, R7.reuse, 0x1, RZ ;                
                                                                                
        /*0250*/                   ISETP.GE.U32.AND P0, PT, R7, 0x3, PT ;       
                                                                                
        /*0260*/                   LOP3.LUT P1, R4, R4, 0x3, RZ, 0xc0, !PT ;    
                                                                                
        /*0270*/              @!P1 BRA 0x430 ;                                  
                                                                                
        /*0280*/                   IMAD.SHL.U32 R8, R0.reuse, 0x4, RZ ;         
                                                                                
        /*0290*/                   SHF.L.U64.HI R9, R0, 0x2, R3 ;               
                                                                                
        /*02a0*/                   IADD3 R18, P1, R8.reuse, c[0x0][0x170], RZ ; 
                                                                                
        /*02b0*/                   IADD3 R6, P2, R8.reuse, c[0x0][0x168], RZ ;  
                                                                                
        /*02c0*/                   IADD3 R8, P3, R8, c[0x0][0x160], RZ ;        
                                                                                
        /*02d0*/                   IADD3.X R21, R9.reuse, c[0x0][0x174], RZ, P1,
                                                                                
        /*02e0*/                   IADD3.X R7, R9.reuse, c[0x0][0x16c], RZ, P2, 
                                                                                
        /*02f0*/                   IADD3.X R9, R9, c[0x0][0x164], RZ, P3, !PT ; 
                                                                                
        /*0300*/                   LDG.E.SYS R10, [R6] ;                        
                                                                                
        /*0310*/                   LDG.E.SYS R11, [R8] ;                        
                                                                                
        /*0320*/                   MOV R16, R18 ;                               
                                                                                
        /*0330*/                   IMAD.MOV.U32 R17, RZ, RZ, R21 ;              
                                                                                
        /*0340*/                   IADD3 R4, R4, -0x1, RZ ;                     
                                                                                
        /*0350*/                   IMAD.WIDE R12, R2.reuse, 0x4, R6 ;           
                                                                                
        /*0360*/                   IADD3 R5, R2, R5, RZ ;                       
                                                                                
        /*0370*/                   ISETP.NE.AND P1, PT, R4, RZ, PT ;            
                                                                                
        /*0380*/                   IMAD.WIDE R14, R2, 0x4, R8 ;                 
                                                                                
        /*0390*/                   MOV R6, R12 ;                                
                                                                                
        /*03a0*/                   IMAD.MOV.U32 R7, RZ, RZ, R13 ;               
                                                                                
        /*03b0*/                   MOV R8, R14 ;                                
                                                                                
        /*03c0*/                   IMAD.MOV.U32 R9, RZ, RZ, R15 ;               
                                                                                
        /*03d0*/                   FADD R19, R10, R11 ;                         
                                                                                
        /*03e0*/                   IMAD.WIDE R10, R2, 0x4, R16 ;                
                                                                                
        /*03f0*/                   IMAD.MOV.U32 R21, RZ, RZ, R11 ;              
                                                                                
        /*0400*/                   MOV R18, R10 ;                               
                                                                                
        /*0410*/                   STG.E.SYS [R16], R19 ;                       
                                                                                
        /*0420*/               @P1 BRA 0x300 ;                                  
                                                                                
        /*0430*/                   BSYNC B1 ;                                   
                                                                                
        /*0440*/              @!P0 BRA 0x660 ;                                  
                                                                                
        /*0450*/                   IMAD.MOV.U32 R10, RZ, RZ, 0x4 ;              
                                                                                
        /*0460*/                   IMAD.WIDE R8, R5, R10, c[0x0][0x168] ;       
                                                                                
        /*0470*/                   IMAD.WIDE R6, R5, R10, c[0x0][0x160] ;       
                                                                                
        /*0480*/                   LDG.E.SYS R4, [R8] ;                         
                                                                                
        /*0490*/                   LDG.E.SYS R13, [R6] ;                        
                                                                                
        /*04a0*/                   IMAD.WIDE R10, R5, R10, c[0x0][0x170] ;      
                                                                                
        /*04b0*/                   IMAD.WIDE R14, R2, 0x4, R8 ;                 
                                                                                
        /*04c0*/                   FADD R21, R4, R13 ;                          
                                                                                
        /*04d0*/                   IMAD.WIDE R12, R2, 0x4, R6 ;                 
                                                                                
        /*04e0*/                   STG.E.SYS [R10], R21 ;                       
                                                                                
        /*04f0*/                   LDG.E.SYS R4, [R14] ;                        
                                                                                
        /*0500*/                   LDG.E.SYS R19, [R12] ;                       
                                                                                
        /*0510*/                   IMAD.WIDE R16, R2, 0x4, R10 ;                
                                                                                
        /*0520*/                   IMAD.WIDE R8, R2, 0x4, R14 ;                 
                                                                                
        /*0530*/                   IMAD.WIDE R6, R2, 0x4, R12 ;                 
                                                                                
        /*0540*/                   FADD R23, R4, R19 ;                          
                                                                                
        /*0550*/                   STG.E.SYS [R16], R23 ;                       
                                                                                
        /*0560*/                   LDG.E.SYS R4, [R8] ;                         
                                                                                
        /*0570*/                   LDG.E.SYS R25, [R6] ;                        
                                                                                
        /*0580*/                   IMAD.WIDE R18, R2, 0x4, R16 ;                
                                                                                
        /*0590*/                   IMAD.WIDE R14, R2, 0x4, R8 ;                 
                                                                                
        /*05a0*/                   IMAD.WIDE R10, R2, 0x4, R6 ;                 
                                                                                
        /*05b0*/                   FADD R25, R4, R25 ;                          
                                                                                
        /*05c0*/                   STG.E.SYS [R18], R25 ;                       
                                                                                
        /*05d0*/                   LDG.E.SYS R14, [R14] ;                       
                                                                                
        /*05e0*/                   LDG.E.SYS R11, [R10] ;                       
                                                                                
        /*05f0*/                   IMAD.WIDE R12, R2.reuse, 0x4, R18 ;          
                                                                                
        /*0600*/                   IADD3 R5, R2, R5, R2 ;                       
                                                                                
        /*0610*/                   IADD3 R5, R2, R5, R2 ;                       
                                                                                
        /*0620*/                   ISETP.GE.AND P0, PT, R5, c[0x0][0x178], PT ; 
                                                                                
        /*0630*/                   FADD R17, R14, R11 ;                         
                                                                                
        /*0640*/                   STG.E.SYS [R12], R17 ;                       
                                                                                
        /*0650*/              @!P0 BRA 0x450 ;                                  
                                                                                
        /*0660*/                   BSYNC B0 ;                                   
                                                                                
        /*0670*/                   LEA R2, P0, R0.reuse, c[0x0][0x170], 0x2 ;   
                                                                                
        /*0680*/                   MOV R5, 0x41700000 ;                         
                                                                                
        /*0690*/                   LEA.HI.X R3, R0, c[0x0][0x174], R3, 0x2, P0 ;
                                                                                
        /*06a0*/                   STG.E.SYS [R2], R5 ;                         
                                                                                
        /*06b0*/                   EXIT ;                                       
                                                                                
        /*06c0*/                   BRA 0x6c0;                                   
                                                                                
        /*06d0*/                   NOP;                                         
                                                                                
        /*06e0*/                   NOP;                                         
                                                                                
        /*06f0*/                   NOP;                                         
                                                                                
		..........


  • Spot something that doesn't quite seem to belong?

From CUDA¶

Vector add stolen from ORNL.

In [20]:
%%writefile tmp/vector-add.cu

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
__global__ void vecAdd(double *a, double *b, double *c, int n)
{
    // Get our global thread ID
    int id = blockIdx.x*blockDim.x+threadIdx.x;
 
    // Make sure we do not go out of bounds
    if (id < n)
        c[id] = a[id] + b[id];
}
 
int main( int argc, char* argv[] )
{
    // Size of vectors
    int n = 100000;
 
    double *h_a;
    double *h_b;
    double *h_c;
 
    double *d_a;
    double *d_b;
    double *d_c;
 
    size_t bytes = n*sizeof(double);
 
    h_a = (double*)malloc(bytes);
    h_b = (double*)malloc(bytes);
    h_c = (double*)malloc(bytes);
 
    cudaMalloc(&d_a, bytes);
    cudaMalloc(&d_b, bytes);
    cudaMalloc(&d_c, bytes);
 
    int i;
    for( i = 0; i < n; i++ ) {
        h_a[i] = sin(i)*sin(i);
        h_b[i] = cos(i)*cos(i);
    }
 
    // Copy host vectors to device
    cudaMemcpy( d_a, h_a, bytes, cudaMemcpyHostToDevice);
    cudaMemcpy( d_b, h_b, bytes, cudaMemcpyHostToDevice);
 
    int blockSize, gridSize;
 
    blockSize = 1024;
 
    gridSize = (int)ceil((float)n/blockSize);
 
    vecAdd<<<gridSize, blockSize>>>(d_a, d_b, d_c, n);
 
    cudaMemcpy( h_c, d_c, bytes, cudaMemcpyDeviceToHost );
 
    double sum = 0;
    for(i=0; i<n; i++)
        sum += h_c[i];
    printf("final result: %f\n", sum/n);
 
    cudaFree(d_a);
    cudaFree(d_b);
    cudaFree(d_c);
 
    free(h_a);
    free(h_b);
    free(h_c);
 
    return 0;
}
Writing tmp/vector-add.cu
In [21]:
!(cd tmp; nvcc -c vector-add.cu)
!cuobjdump --dump-sass tmp/vector-add.o
Fatbin elf code:
================
arch = sm_52
code version = [1,7]
host = linux
compile_size = 64bit

	code for sm_52
		Function : _Z6vecAddPdS_S_i
	.headerflags	@"EF_CUDA_TEXMODE_UNIFIED EF_CUDA_64BIT_ADDRESS EF_CUDA_SM52 EF_CUDA_VIRTUAL_SM(EF_CUDA_SM52)"
                                                                                 /* 0x001cfc00e22007f6 */
        /*0008*/                   MOV R1, c[0x0][0x20] ;                        /* 0x4c98078000870001 */
        /*0010*/                   S2R R0, SR_CTAID.X ;                          /* 0xf0c8000002570000 */
        /*0018*/                   S2R R2, SR_TID.X ;                            /* 0xf0c8000002170002 */
                                                                                 /* 0x001fd842fec20ff1 */
        /*0028*/                   XMAD.MRG R3, R0.reuse, c[0x0] [0x8].H1, RZ ;  /* 0x4f107f8000270003 */
        /*0030*/                   XMAD R2, R0.reuse, c[0x0] [0x8], R2 ;         /* 0x4e00010000270002 */
        /*0038*/                   XMAD.PSL.CBCC R0, R0.H1, R3.H1, R2 ;          /* 0x5b30011800370000 */
                                                                                 /* 0x001ff400fd4007ed */
        /*0048*/                   ISETP.GE.AND P0, PT, R0, c[0x0][0x158], PT ;  /* 0x4b6d038005670007 */
        /*0050*/                   NOP ;                                         /* 0x50b0000000070f00 */
        /*0058*/               @P0 EXIT ;                                        /* 0xe30000000000000f */
                                                                                 /* 0x081fd800fea207f1 */
        /*0068*/                   SHL R8, R0.reuse, 0x3 ;                       /* 0x3848000000370008 */
        /*0070*/                   SHR R0, R0, 0x1d ;                            /* 0x3829000001d70000 */
        /*0078*/                   IADD R4.CC, R8.reuse, c[0x0][0x140] ;         /* 0x4c10800005070804 */
                                                                                 /* 0x001fd800fe0207f2 */
        /*0088*/                   IADD.X R5, R0.reuse, c[0x0][0x144] ;          /* 0x4c10080005170005 */
        /*0090*/                   IADD R6.CC, R8, c[0x0][0x148] ;               /* 0x4c10800005270806 */
        /*0098*/                   LDG.E.64 R4, [R4] ;                           /* 0xeed5200000070404 */
                                                                                 /* 0x001fd800f62007e2 */
        /*00a8*/                   IADD.X R7, R0, c[0x0][0x14c] ;                /* 0x4c10080005370007 */
        /*00b0*/                   LDG.E.64 R2, [R6] ;                           /* 0xeed5200000070602 */
        /*00b8*/                   IADD R8.CC, R8, c[0x0][0x150] ;               /* 0x4c10800005470808 */
                                                                                 /* 0x003fc420e28007f7 */
        /*00c8*/                   IADD.X R9, R0, c[0x0][0x154] ;                /* 0x4c10080005570009 */
        /*00d0*/                   DADD R2, R2, R4 ;                             /* 0x5c70000000470202 */
        /*00d8*/                   STG.E.64 [R8], R2 ;                           /* 0xeedd200000070802 */
                                                                                 /* 0x001ffc00ffe007e8 */
        /*00e8*/                   NOP ;                                         /* 0x50b0000000070f00 */
        /*00f0*/                   EXIT ;                                        /* 0xe30000000007000f */
        /*00f8*/                   BRA 0xf8 ;                                    /* 0xe2400fffff87000f */
		..........



Fatbin ptx code:
================
arch = sm_52
code version = [8,2]
host = linux
compile_size = 64bit
compressed
  • What is _Z6vecAddPdS_S_i?
In [36]:
!echo _Z6vecAddPdS_S_i | c++filt
vecAdd(double*, double*, double*, int)

Inline PTX¶

In [22]:
prg = cl.Program(ctx, """
__kernel void getlaneid(__global int *d_ptr, int length)
{
    int elemID = get_global_id(0);
    if (elemID < length)
    {
        unsigned int laneid;
        asm("mov.u32 %0, %%laneid;" : "=r"(laneid));
        d_ptr[elemID] = laneid;
    }
}
""").build()

print(prg.binaries[0].decode())
//
// Generated by NVIDIA NVVM Compiler
//
// Compiler Build ID: CL-35042711
// Unknown Toolkit Version
// Based on NVVM 7.0.1
//

.version 8.2
.target sm_70, texmode_independent
.address_size 64

	// .globl	getlaneid

.entry getlaneid(
	.param .u64 .ptr .global .align 4 getlaneid_param_0,
	.param .u32 getlaneid_param_1
)
{
	.reg .pred 	%p<2>;
	.reg .b32 	%r<9>;
	.reg .b64 	%rd<4>;


	ld.param.u64 	%rd1, [getlaneid_param_0];
	ld.param.u32 	%r2, [getlaneid_param_1];
	mov.b32 	%r3, %envreg3;
	mov.u32 	%r4, %ctaid.x;
	mov.u32 	%r5, %ntid.x;
	mov.u32 	%r6, %tid.x;
	add.s32 	%r7, %r6, %r3;
	mad.lo.s32 	%r1, %r5, %r4, %r7;
	setp.ge.s32 	%p1, %r1, %r2;
	@%p1 bra 	$L__BB0_2;

	// begin inline asm
	mov.u32 %r8, %laneid;
	// end inline asm
	mul.wide.s32 	%rd2, %r1, 4;
	add.s64 	%rd3, %rd1, %rd2;
	st.global.u32 	[%rd3], %r8;

$L__BB0_2:
	ret;

}


  • What do the constraints mean again?
  • Spot the inline assembly
  • Observe how the if is realized
  • Observe the realization of get_global_id()
In [48]:
a = cla.empty(queue, 5000, np.uint32)
prg.getlaneid(queue, lanes.shape, None, a.data, np.uint32(a.size))
Out[48]:
<pyopencl._cl.Event at 0x7fa528c8b360>
In [50]:
a[:500]
Out[50]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,  0,  1,
        2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
       19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,  0,  1,  2,  3,
        4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
       21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,  0,  1,  2,  3,  4,  5,
        6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
       23, 24, 25, 26, 27, 28, 29, 30, 31,  0,  1,  2,  3,  4,  5,  6,  7,
        8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
       25, 26, 27, 28, 29, 30, 31,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
       10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
       27, 28, 29, 30, 31,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,
       12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
       29, 30, 31,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,
       14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  1,  2,  3,  4,
        5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
       22, 23, 24, 25, 26, 27, 28, 29, 30, 31,  0,  1,  2,  3,  4,  5,  6,
        7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
       24, 25, 26, 27, 28, 29, 30, 31,  0,  1,  2,  3,  4,  5,  6,  7,  8,
        9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
       26, 27, 28, 29, 30, 31,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
       11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
       28, 29, 30, 31,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
       13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
       30, 31,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
       15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,  0,  1,
        2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
       19, 20, 21, 22, 23, 24, 25], dtype=uint32)
In [ ]: