Perform a synchronous copy from the array. Parameters ---------- source_array : array_like The data source we should like to copy from. Returns ------- arr : Tensor Reference to self.
(self, source_array)
| 92 | raise TypeError(f"type {type(value)} not supported") |
| 93 | |
| 94 | def copyfrom(self, source_array): |
| 95 | """Perform a synchronous copy from the array. |
| 96 | |
| 97 | Parameters |
| 98 | ---------- |
| 99 | source_array : array_like |
| 100 | The data source we should like to copy from. |
| 101 | |
| 102 | Returns |
| 103 | ------- |
| 104 | arr : Tensor |
| 105 | Reference to self. |
| 106 | """ |
| 107 | if isinstance(source_array, Tensor): |
| 108 | source_array.copyto(self) |
| 109 | return self |
| 110 | |
| 111 | if not isinstance(source_array, np.ndarray): |
| 112 | try: |
| 113 | source_array = np.array(source_array, dtype=self.dtype) |
| 114 | except Exception: |
| 115 | raise TypeError( |
| 116 | f"array must be an array_like data, type {type(source_array)} is not supported" |
| 117 | ) |
| 118 | |
| 119 | t = tvm_ffi.dtype(self.dtype) |
| 120 | shape, dtype = self.shape, self.dtype |
| 121 | if t.lanes > 1: |
| 122 | shape = shape + (t.lanes,) |
| 123 | t = t.with_lanes(1) |
| 124 | dtype = str(t) |
| 125 | |
| 126 | if source_array.shape != shape: |
| 127 | raise ValueError( |
| 128 | f"array shape do not match the shape of Tensor {source_array.shape} vs {shape}" |
| 129 | ) |
| 130 | numpy_str_map = tvm_ffi.dtype._NUMPY_DTYPE_TO_STR |
| 131 | np_dtype_str = ( |
| 132 | numpy_str_map[source_array.dtype] |
| 133 | if source_array.dtype in numpy_str_map |
| 134 | else str(source_array.dtype) |
| 135 | ) |
| 136 | if (not source_array.flags["C_CONTIGUOUS"]) or ( |
| 137 | dtype == "bfloat16" or dtype != np_dtype_str |
| 138 | ): |
| 139 | if dtype == "bfloat16": |
| 140 | source_array = np.frombuffer(source_array.tobytes(), "uint16") |
| 141 | source_array = np.ascontiguousarray( |
| 142 | source_array, dtype="uint16" if dtype == "bfloat16" else dtype |
| 143 | ) |
| 144 | if self.dtype.startswith("float4_e2m1fn"): |
| 145 | # we need to pack the input data when converting to float4_e2m1fn type, |
| 146 | data_bits = source_array.view(dtype="uint8").flatten() |
| 147 | if data_bits.size % 2: |
| 148 | data_bits = np.pad(data_bits, (0, 1), mode="constant", constant_values=0) |
| 149 | data_bits = data_bits.reshape(-1, 2) |
| 150 | packed = ((data_bits[:, 0] & 0x0F) << 4) | (data_bits[:, 1] & 0x0F) |
| 151 | source_array = packed.astype(np.int8) |