Coverage for cuda/bindings/_internal/utils.pyx: 43.02%

86 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-03 02:41 +0000

1# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 

2# 

3# SPDX-License-Identifier: Apache-2.0 

4  

5cimport cpython 

6from libc.stdint cimport intptr_t 

7from libcpp.utility cimport move 

8from cython.operator cimport dereference as deref 

9  

10  

11cdef extern from *: 

12 """ 

13 #if defined(__clang__) 

14 #define _COMPILER_VERSION ("Clang " __clang_version__) 

15 #elif defined(__GNUC__) || defined(__GNUG__) 

16 #define _COMPILER_VERSION ("GCC " __VERSION__) 

17 #elif defined(_MSC_VER) 

18 #define _COMPILER_VERSION ("MSVC " Py_STRINGIFY(_MSC_VER)) 

19 #else 

20 #define _COMPILER_VERSION ("Unknown Compiler") 

21 #endif 

22 """ 

23 cdef char *_COMPILER_VERSION 

24  

25  

26cpdef str get_c_compiler(): 

27 """ 

28 Returns a string describing the C compiler used to build cuda.bindings 

29 """ 

30 return _COMPILER_VERSION.decode() 2~b

31  

32  

33cdef bint is_nested_sequence(data): 

34 if not cpython.PySequence_Check(data): 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

35 return False 

36 else: 

37 for i in data: 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

38 if not cpython.PySequence_Check(i): 2a f g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ d abbbe cbdbebfbgbhbibjb

39 return False 

40 else: 

41 return True 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

42  

43  

44cdef void* get_buffer_pointer(buf, Py_ssize_t size, readonly=True) except*: 

45 """The caller must ensure ``buf`` is alive when the returned pointer is in use.""" 

46 cdef void* bufPtr 

47 cdef int flags = cpython.PyBUF_ANY_CONTIGUOUS 

48 if not readonly: 

49 flags |= cpython.PyBUF_WRITABLE 

50 cdef int status = -1 

51 cdef cpython.Py_buffer view 

52  

53 if isinstance(buf, int): 

54 bufPtr = <void*><intptr_t>buf 

55 else: # try buffer protocol 

56 try: 

57 status = cpython.PyObject_GetBuffer(buf, &view, flags) 

58 # when the caller does not provide a size, it is set to -1 at generate-time by cybind 

59 if size != -1: 

60 assert view.len == size 

61 assert view.ndim == 1 

62 except Exception as e: 

63 adj = "writable " if not readonly else "" 

64 raise ValueError( 

65 "buf must be either a Python int representing the pointer " 

66 f"address to a valid buffer, or a 1D contiguous {adj}" 

67 "buffer, of size bytes") from e 

68 else: 

69 bufPtr = view.buf 

70 finally: 

71 if status == 0: 

72 cpython.PyBuffer_Release(&view) 

73  

74 return bufPtr 

75  

76  

77# Cython can't infer the ResT overload when it is wrapped in nullable_unique_ptr, 

78# so we need a dummy (__unused) input argument to help it 

79cdef int get_resource_ptr(nullable_unique_ptr[vector[ResT]] &in_out_ptr, object obj, ResT* __unused) except 1: 

80 if cpython.PySequence_Check(obj): 

81 vec = new vector[ResT](len(obj)) 

82 # set the ownership immediately to avoid leaking the `vec` memory in 

83 # case of exception in the following loop 

84 in_out_ptr.reset(vec, True) 

85 for i in range(len(obj)): 

86 deref(vec)[i] = obj[i] 

87 else: 

88 in_out_ptr.reset(<vector[ResT]*><intptr_t>obj, False) 

89 return 0 

90  

91  

92cdef int get_resource_ptrs(nullable_unique_ptr[ vector[PtrT*] ] &in_out_ptr, object obj, PtrT* __unused) except 1: 

93 if cpython.PySequence_Check(obj): 

94 vec = new vector[PtrT*](len(obj)) 

95 # set the ownership immediately to avoid leaking the `vec` memory in 

96 # case of exception in the following loop 

97 in_out_ptr.reset(vec, True) 

98 for i in range(len(obj)): 

99 deref(vec)[i] = <PtrT*><intptr_t>(obj[i]) 

100 else: 

101 in_out_ptr.reset(<vector[PtrT*]*><intptr_t>obj, False) 

102 return 0 

103  

104  

105cdef int get_nested_resource_ptr(nested_resource[ResT] &in_out_ptr, object obj, ResT* __unused) except 1: 

106 cdef nullable_unique_ptr[ vector[intptr_t] ] nested_ptr 

107 cdef nullable_unique_ptr[ vector[vector[ResT]] ] nested_res_ptr 

108 cdef vector[intptr_t]* nested_vec = NULL 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

109 cdef vector[vector[ResT]]* nested_res_vec = NULL 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

110 cdef size_t i = 0, length = 0 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

111 cdef intptr_t addr 

112  

113 if is_nested_sequence(obj): 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

114 length = len(obj) 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

115 nested_res_vec = new vector[vector[ResT]](length) 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

116 nested_vec = new vector[intptr_t](length) 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

117 # set the ownership immediately to avoid leaking memory in case of 

118 # exception in the following loop 

119 nested_res_ptr.reset(nested_res_vec, True) 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

120 nested_ptr.reset(nested_vec, True) 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

121 for i, obj_i in enumerate(obj): 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

122 if ResT is char: 

123 obj_i_type = type(obj_i) 2a f g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ d abbbe cbdbebfbgbhbibjb

124 if obj_i_type is str: 2a f g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ d abbbe cbdbebfbgbhbibjb

125 obj_i_bytes = obj_i.encode("utf-8") 2a f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbibjb

126 elif obj_i_type is bytes: 1bcde

127 obj_i_bytes = obj_i 1bcde

128 else: 

129 raise TypeError( 

130 f"Expected str or bytes, got {obj_i_type.__name__}") 

131 str_len = <size_t>(len(obj_i_bytes)) + 1 # including null termination 2a f g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ d abbbe cbdbebfbgbhbibjb

132 deref(nested_res_vec)[i].resize(str_len) 2a f g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ d abbbe cbdbebfbgbhbibjb

133 obj_i_ptr = <char*>(obj_i_bytes) 2a f g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ d abbbe cbdbebfbgbhbibjb

134 # cast to size_t explicitly to work around a potentially Cython bug 

135 deref(nested_res_vec)[i].assign(obj_i_ptr, obj_i_ptr + <size_t>str_len) 2a f g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ d abbbe cbdbebfbgbhbibjb

136 else: 

137 deref(nested_res_vec)[i] = obj_i 

138 deref(nested_vec)[i] = <intptr_t>(deref(nested_res_vec)[i].data()) 2a f g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ d abbbe cbdbebfbgbhbibjb

139 elif cpython.PySequence_Check(obj): 

140 length = len(obj) 

141 nested_vec = new vector[intptr_t](length) 

142 nested_ptr.reset(nested_vec, True) 

143 for i, addr in enumerate(obj): 

144 deref(nested_vec)[i] = addr 

145 nested_res_ptr.reset(NULL, False) 

146 else: 

147 # obj is an int (ResT**) 

148 nested_res_ptr.reset(NULL, False) 

149 nested_ptr.reset(<vector[intptr_t]*><intptr_t>obj, False) 

150  

151 in_out_ptr.ptrs = move(nested_ptr) 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

152 in_out_ptr.nested_resource_ptr = move(nested_res_ptr) 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

153 return 0 2a kblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbIbJbKbLbMbNbObPbQbf g h i j k l m n o p q r s t u v b w x y z A B C D E F G H I J K L M N O P Q R RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?bS T U V W X Y Z 0 1 2 3 4 5 6 7 8 c 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | @b[b]b^b_b} ~ d `babbbe {bcbdb|bebfbgb}bhbibjb

154  

155  

156class FunctionNotFoundError(RuntimeError): pass 

157  

158class NotSupportedError(RuntimeError): pass