or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-operations.mdcuda-integration.mdfft.mdindex.mdindexing-selection.mdinput-output.mdjit-kernels.mdlinear-algebra.mdlogic-operations.mdmathematical-functions.mdrandom-generation.mdscipy-extensions.mdstatistics.mdtesting.md

input-output.mddocs/

0

# Input/Output Operations

1

2

File I/O operations supporting NumPy's binary formats (NPZ) and text formats with GPU-optimized loading and saving capabilities. CuPy provides comprehensive file operations for data persistence and exchange between CPU and GPU memory spaces.

3

4

## Capabilities

5

6

### Binary Format Operations

7

8

High-performance binary file operations for efficient data storage and loading.

9

10

```python { .api }

11

def save(file, arr, allow_pickle=True, fix_imports=True):

12

"""Save array to binary file in NumPy format.

13

14

Args:

15

file: File path or file object

16

arr: Array to save

17

allow_pickle: Allow pickling of Python objects

18

fix_imports: Fix Python 2/3 compatibility

19

20

Note:

21

Saves in uncompressed .npy format

22

"""

23

24

def load(file, mmap_mode=None, allow_pickle=False, fix_imports=True, encoding='ASCII'):

25

"""Load array from binary file.

26

27

Args:

28

file: File path or file object

29

mmap_mode: Memory mapping mode (None, 'r', 'r+', 'w+', 'c')

30

allow_pickle: Allow loading pickled objects

31

fix_imports: Fix Python 2/3 compatibility

32

encoding: String encoding for Python 2/3 compatibility

33

34

Returns:

35

cupy.ndarray: Loaded array on GPU

36

"""

37

38

def savez(file, *args, **kwds):

39

"""Save multiple arrays to compressed archive.

40

41

Args:

42

file: Output file path

43

*args: Arrays to save (saved as arr_0, arr_1, ...)

44

**kwds: Named arrays to save

45

46

Note:

47

Creates uncompressed .npz archive

48

"""

49

50

def savez_compressed(file, *args, **kwds):

51

"""Save multiple arrays to compressed archive.

52

53

Args:

54

file: Output file path

55

*args: Arrays to save (saved as arr_0, arr_1, ...)

56

**kwds: Named arrays to save

57

58

Note:

59

Creates compressed .npz archive with better compression

60

"""

61

62

def loadz(file):

63

"""Load arrays from .npz archive.

64

65

Args:

66

file: Path to .npz file

67

68

Returns:

69

NpzFile: Dictionary-like object for array access

70

"""

71

```

72

73

### Text Format Operations

74

75

Text-based file operations for human-readable data exchange and compatibility.

76

77

```python { .api }

78

def savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n',

79

header='', footer='', comments='# ', encoding=None):

80

"""Save array to text file.

81

82

Args:

83

fname: Output filename

84

X: Array to save (1D or 2D)

85

fmt: Format string or sequence of format strings

86

delimiter: String/character separating columns

87

newline: String/character separating lines

88

header: Text to write at beginning of file

89

footer: Text to write at end of file

90

comments: String to prepend to header/footer

91

encoding: Text encoding

92

93

Note:

94

Data is transferred to CPU before saving

95

"""

96

97

def loadtxt(fname, dtype=float, comments='#', delimiter=None,

98

converters=None, skiprows=0, usecols=None, unpack=False,

99

ndmin=0, encoding='bytes', max_rows=None):

100

"""Load data from text file.

101

102

Args:

103

fname: Input filename

104

dtype: Data type of resulting array

105

comments: Character(s) indicating start of comment

106

delimiter: String used to separate values

107

converters: Dictionary of converter functions

108

skiprows: Number of rows to skip at beginning

109

usecols: Columns to read (None for all)

110

unpack: Unpack columns into separate arrays

111

ndmin: Minimum dimensions of returned array

112

encoding: Text encoding

113

max_rows: Maximum number of rows to read

114

115

Returns:

116

cupy.ndarray: Loaded data on GPU

117

"""

118

119

def genfromtxt(fname, dtype=float, comments='#', delimiter=None,

120

skip_header=0, skip_footer=0, converters=None,

121

missing_values=None, filling_values=None, usecols=None,

122

names=None, excludelist=None, deletechars=None,

123

defaultfmt='f%i', autostrip=False, replace_space='_',

124

case_sensitive=True, unpack=None, invalid_raise=True,

125

max_rows=None, encoding='bytes'):

126

"""Enhanced text loading with missing value support.

127

128

Args:

129

fname: Input filename

130

dtype: Data type

131

comments: Comment character(s)

132

delimiter: Value separator

133

skip_header: Lines to skip at beginning

134

skip_footer: Lines to skip at end

135

converters: Converter functions

136

missing_values: Strings indicating missing data

137

filling_values: Values for missing data

138

usecols: Columns to use

139

names: Field names for structured arrays

140

excludelist: Names of fields to exclude

141

deletechars: Characters to remove from field names

142

defaultfmt: Default format for field names

143

autostrip: Strip whitespace from values

144

replace_space: Character to replace spaces in names

145

case_sensitive: Case sensitivity for field names

146

unpack: Unpack arrays

147

invalid_raise: Raise exception on invalid values

148

max_rows: Maximum rows to read

149

encoding: Text encoding

150

151

Returns:

152

cupy.ndarray: Loaded data with missing value handling

153

"""

154

```

155

156

### Array String Representation

157

158

Functions for converting arrays to string representations and formatting.

159

160

```python { .api }

161

def array_str(a, max_line_width=None, precision=None, suppress_small=None):

162

"""Return string representation of array data.

163

164

Args:

165

a: Input array

166

max_line_width: Maximum characters per line

167

precision: Floating point precision

168

suppress_small: Suppress small values in scientific notation

169

170

Returns:

171

str: String representation of array data

172

"""

173

174

def array_repr(arr, max_line_width=None, precision=None, suppress_small=None):

175

"""Return string representation of array.

176

177

Args:

178

arr: Input array

179

max_line_width: Maximum characters per line

180

precision: Floating point precision

181

suppress_small: Suppress small values

182

183

Returns:

184

str: String representation including array constructor

185

"""

186

187

def array2string(a, max_line_width=None, precision=None, suppress_small=None,

188

separator=' ', prefix="", style=str, formatter=None,

189

threshold=None, edgeitems=None, sign=None,

190

floatmode=None, suffix="", **kwds):

191

"""Return string representation with comprehensive formatting.

192

193

Args:

194

a: Input array

195

max_line_width: Maximum line width

196

precision: Number precision

197

suppress_small: Suppress small values

198

separator: Element separator

199

prefix: String prefix

200

style: Formatting style function

201

formatter: Custom formatting functions

202

threshold: Total items threshold for summarization

203

edgeitems: Items at beginning/end in summary

204

sign: Sign handling (' ', '+', '-')

205

floatmode: Float formatting mode

206

suffix: String suffix

207

**kwds: Additional formatting parameters

208

209

Returns:

210

str: Formatted string representation

211

"""

212

213

def base_repr(number, base=2, padding=0):

214

"""Return string representation in given base.

215

216

Args:

217

number: Input number

218

base: Number base (2-36)

219

padding: Minimum width with zero padding

220

221

Returns:

222

str: String representation in specified base

223

"""

224

```

225

226

### Memory Mapping and Direct Access

227

228

Advanced file operations for memory-mapped arrays and direct disk access.

229

230

```python { .api }

231

def memmap(filename, dtype='uint8', mode='r+', offset=0, shape=None, order='C'):

232

"""Create memory-mapped array.

233

234

Args:

235

filename: Path to file

236

dtype: Data type

237

mode: File access mode ('r', 'r+', 'w+', 'c')

238

offset: Byte offset in file

239

shape: Array shape (required for modes other than 'r')

240

order: Memory layout ('C' or 'F')

241

242

Returns:

243

numpy.memmap: Memory-mapped array (CPU-based)

244

245

Note:

246

Returns NumPy memmap object. Use cp.asarray() to copy to GPU.

247

"""

248

249

def fromfile(file, dtype=float, count=-1, sep='', offset=0):

250

"""Create array from binary or text file data.

251

252

Args:

253

file: Open file object or filename

254

dtype: Data type of array elements

255

count: Number of items to read (-1 for all)

256

sep: Separator for text files (empty for binary)

257

offset: Byte offset for binary files

258

259

Returns:

260

cupy.ndarray: Array created from file data

261

"""

262

263

def tofile(arr, fid, sep="", format="%s"):

264

"""Write array to file as text or binary.

265

266

Args:

267

arr: Input array

268

fid: Open file object or filename

269

sep: Separator for text output (empty for binary)

270

format: Format string for text output

271

272

Note:

273

Data is transferred to CPU before writing

274

"""

275

276

def fromstring(string, dtype=float, count=-1, sep=''):

277

"""Create array from string data.

278

279

Args:

280

string: Input string

281

dtype: Data type

282

count: Number of items (-1 for all)

283

sep: Separator character

284

285

Returns:

286

cupy.ndarray: Array from string data

287

"""

288

289

def frombuffer(buffer, dtype=float, count=-1, offset=0):

290

"""Create array from buffer object.

291

292

Args:

293

buffer: Buffer object (bytes-like)

294

dtype: Data type

295

count: Number of items (-1 for all)

296

offset: Byte offset in buffer

297

298

Returns:

299

cupy.ndarray: Array from buffer data

300

"""

301

```

302

303

### Configuration and Formatting Control

304

305

Functions for controlling array display and I/O behavior.

306

307

```python { .api }

308

def set_printoptions(precision=None, threshold=None, edgeitems=None,

309

linewidth=None, suppress=None, nanstr=None,

310

infstr=None, formatter=None, sign=None,

311

floatmode=None, **kwds):

312

"""Set printing options for arrays.

313

314

Args:

315

precision: Number of digits of precision

316

threshold: Total array elements triggering summarization

317

edgeitems: Number of edge items in summary mode

318

linewidth: Characters per line for wrapping

319

suppress: Suppress small floating point values

320

nanstr: String representation of NaN values

321

infstr: String representation of infinity values

322

formatter: Custom formatting functions

323

sign: Control sign display

324

floatmode: Floating point formatting mode

325

**kwds: Additional options

326

"""

327

328

def get_printoptions():

329

"""Return current print options.

330

331

Returns:

332

dict: Current printing configuration

333

"""

334

335

def printoptions(*args, **kwargs):

336

"""Context manager for temporary print options.

337

338

Args:

339

*args, **kwargs: Print option arguments

340

341

Returns:

342

Context manager for temporary option changes

343

"""

344

345

def set_string_function(f, repr=True):

346

"""Set function for array string representation.

347

348

Args:

349

f: Function to use for string conversion

350

repr: Whether function is for repr (True) or str (False)

351

"""

352

```

353

354

### Data Exchange and Interoperability

355

356

Functions for converting between different data formats and libraries.

357

358

```python { .api }

359

def asarray(a, dtype=None, order=None):

360

"""Convert input to CuPy array.

361

362

Args:

363

a: Input data (any array-like)

364

dtype: Data type

365

order: Memory layout

366

367

Returns:

368

cupy.ndarray: Array on GPU

369

"""

370

371

def asnumpy(a, stream=None, order='C', out=None):

372

"""Convert CuPy array to NumPy array.

373

374

Args:

375

a: Input CuPy array

376

stream: CUDA stream for asynchronous transfer

377

order: Memory layout ('C', 'F', 'A', 'K')

378

out: Output NumPy array

379

380

Returns:

381

numpy.ndarray: Array on CPU

382

"""

383

384

def from_dlpack(x):

385

"""Create CuPy array from DLPack tensor.

386

387

Args:

388

x: Object with __dlpack__ method

389

390

Returns:

391

cupy.ndarray: Array sharing memory with DLPack tensor

392

"""

393

394

def fromDlpack(dltensor):

395

"""Create array from DLPack tensor capsule.

396

397

Args:

398

dltensor: DLPack tensor capsule

399

400

Returns:

401

cupy.ndarray: Array from DLPack tensor

402

"""

403

```

404

405

### Compression and Archive Operations

406

407

Advanced operations for compressed data and multi-file archives.

408

409

```python { .api }

410

class NpzFile:

411

"""Object for reading .npz archive files.

412

413

Provides dictionary-like access to arrays stored in .npz files.

414

415

Attributes:

416

files: List of file names in archive

417

418

Methods:

419

close(): Close the archive file

420

__getitem__(key): Get array by name

421

__contains__(key): Check if array exists

422

__iter__(): Iterate over array names

423

"""

424

425

def __init__(self, fid, own_fid=False, allow_pickle=False,

426

pickle_kwargs=None):

427

pass

428

429

def __enter__(self):

430

return self

431

432

def __exit__(self, exc_type, exc_value, traceback):

433

self.close()

434

435

def close(self):

436

"""Close the archive file."""

437

pass

438

439

def __getitem__(self, key):

440

"""Load array from archive."""

441

pass

442

443

def save_compressed(file, **arrays):

444

"""Save arrays to compressed archive with optimal compression.

445

446

Args:

447

file: Output file path

448

**arrays: Named arrays to save

449

450

Note:

451

Uses advanced compression for minimal file size

452

"""

453

454

def load_archive(file, lazy=False):

455

"""Load archive with optional lazy loading.

456

457

Args:

458

file: Archive file path

459

lazy: Load arrays only when accessed

460

461

Returns:

462

dict or NpzFile: Archive contents

463

"""

464

```

465

466

## Usage Examples

467

468

### Basic File Operations

469

470

```python

471

import cupy as cp

472

import numpy as np

473

474

# Create sample data

475

data = cp.random.randn(1000, 100).astype(cp.float32)

476

labels = cp.random.randint(0, 10, 1000)

477

metadata = {'version': '1.0', 'description': 'Sample dataset'}

478

479

print(f"Data shape: {data.shape}, dtype: {data.dtype}")

480

print(f"Labels shape: {labels.shape}, dtype: {labels.dtype}")

481

482

# Save single array to binary format

483

cp.save('data.npy', data)

484

print("Saved data to 'data.npy'")

485

486

# Load single array

487

loaded_data = cp.load('data.npy')

488

print(f"Loaded data shape: {loaded_data.shape}")

489

print(f"Arrays equal: {cp.array_equal(data, loaded_data)}")

490

491

# Save multiple arrays to archive

492

cp.savez('dataset.npz',

493

features=data,

494

targets=labels,

495

train_indices=cp.arange(800),

496

test_indices=cp.arange(800, 1000))

497

print("Saved multiple arrays to 'dataset.npz'")

498

499

# Load from archive

500

with cp.load('dataset.npz') as archive:

501

print(f"Archive files: {archive.files}")

502

features = archive['features']

503

targets = archive['targets']

504

train_idx = archive['train_indices']

505

test_idx = archive['test_indices']

506

507

print(f"Loaded features shape: {features.shape}")

508

print(f"Loaded targets shape: {targets.shape}")

509

print(f"Train samples: {len(train_idx)}")

510

print(f"Test samples: {len(test_idx)}")

511

512

# Compressed saving for better storage efficiency

513

cp.savez_compressed('dataset_compressed.npz',

514

features=data,

515

targets=labels,

516

metadata=str(metadata))

517

print("Saved compressed archive to 'dataset_compressed.npz'")

518

```

519

520

### Text File Operations

521

522

```python

523

import cupy as cp

524

import os

525

526

# Create sample numeric data

527

measurements = cp.array([

528

[1.23, 4.56, 7.89],

529

[2.34, 5.67, 8.90],

530

[3.45, 6.78, 9.01],

531

[4.56, 7.89, 0.12]

532

])

533

534

# Save to text file with custom formatting

535

header_text = "Time Temperature Humidity"

536

cp.savetxt('measurements.txt', measurements,

537

fmt='%.2f',

538

delimiter='\t',

539

header=header_text,

540

comments='# ')

541

542

print("Saved measurements to 'measurements.txt'")

543

544

# Read the file content

545

with open('measurements.txt', 'r') as f:

546

content = f.read()

547

print("File contents:")

548

print(content)

549

550

# Load from text file

551

loaded_measurements = cp.loadtxt('measurements.txt')

552

print(f"Loaded measurements shape: {loaded_measurements.shape}")

553

print(f"Arrays equal: {cp.allclose(measurements, loaded_measurements)}")

554

555

# Load specific columns

556

time_temp = cp.loadtxt('measurements.txt', usecols=(0, 1))

557

print(f"Time and temperature shape: {time_temp.shape}")

558

559

# Advanced text loading with missing values

560

# Create data with missing values

561

mixed_data_text = """# Weather data

562

1.0 2.5 normal

563

2.0 nan windy

564

3.0 1.8 normal

565

nan 3.2 storm

566

5.0 2.1 normal"""

567

568

with open('weather.txt', 'w') as f:

569

f.write(mixed_data_text)

570

571

# Load with missing value handling

572

try:

573

weather_data = cp.genfromtxt('weather.txt',

574

missing_values={'nan': cp.nan},

575

filling_values={'nan': -999},

576

usecols=(0, 1), # Only numeric columns

577

dtype=float)

578

579

print(f"Weather data with missing values:")

580

print(weather_data)

581

print(f"NaN count: {cp.sum(cp.isnan(weather_data))}")

582

except Exception as e:

583

print(f"Error loading weather data: {e}")

584

```

585

586

### Large File Handling and Performance

587

588

```python

589

import cupy as cp

590

import time

591

import os

592

593

# Create large dataset for performance testing

594

n_samples = 100_000

595

n_features = 200

596

large_data = cp.random.randn(n_samples, n_features).astype(cp.float32)

597

598

print(f"Large dataset: {large_data.shape}, "

599

f"size: {large_data.nbytes / 1024**2:.1f} MB")

600

601

# Time different saving methods

602

save_methods = [

603

('Uncompressed NPY', lambda: cp.save('large_data.npy', large_data)),

604

('Uncompressed NPZ', lambda: cp.savez('large_data.npz', data=large_data)),

605

('Compressed NPZ', lambda: cp.savez_compressed('large_compressed.npz', data=large_data)),

606

]

607

608

file_sizes = {}

609

for name, save_func in save_methods:

610

start_time = time.perf_counter()

611

save_func()

612

cp.cuda.Stream.null.synchronize() # Wait for GPU operations

613

end_time = time.perf_counter()

614

615

# Get file size

616

if 'NPY' in name:

617

filename = 'large_data.npy'

618

elif 'Compressed' in name:

619

filename = 'large_compressed.npz'

620

else:

621

filename = 'large_data.npz'

622

623

file_size = os.path.getsize(filename) / 1024**2 # MB

624

file_sizes[name] = file_size

625

626

print(f"{name}: {(end_time - start_time)*1000:.1f} ms, "

627

f"file size: {file_size:.1f} MB")

628

629

# Time loading methods

630

load_methods = [

631

('Load NPY', lambda: cp.load('large_data.npy')),

632

('Load NPZ', lambda: cp.load('large_data.npz')['data']),

633

('Load Compressed', lambda: cp.load('large_compressed.npz')['data']),

634

]

635

636

for name, load_func in load_methods:

637

start_time = time.perf_counter()

638

loaded = load_func()

639

cp.cuda.Stream.null.synchronize()

640

end_time = time.perf_counter()

641

642

# Verify data integrity

643

is_equal = cp.array_equal(large_data, loaded)

644

645

print(f"{name}: {(end_time - start_time)*1000:.1f} ms, "

646

f"data integrity: {is_equal}")

647

648

# Demonstrate chunked processing for very large files

649

chunk_size = 10_000

650

print(f"\nProcessing data in chunks of {chunk_size:,} samples:")

651

652

# Save data in chunks

653

for i in range(0, n_samples, chunk_size):

654

chunk_end = min(i + chunk_size, n_samples)

655

chunk_data = large_data[i:chunk_end]

656

657

# Save each chunk

658

chunk_filename = f'chunk_{i//chunk_size:03d}.npy'

659

cp.save(chunk_filename, chunk_data)

660

661

if i < 3 * chunk_size: # Show first few chunks

662

print(f"Saved chunk {i//chunk_size + 1}: "

663

f"samples {i:,} to {chunk_end:,}")

664

665

print("Chunked saving completed")

666

```

667

668

### Memory-Mapped Files and Direct Access

669

670

```python

671

import cupy as cp

672

import numpy as np

673

import os

674

675

# Create large file for memory mapping demonstration

676

n_elements = 1_000_000

677

dtype = np.float32

678

679

# Create memory-mapped file

680

filename = 'large_memmap.dat'

681

mmap_array = np.memmap(filename, dtype=dtype, mode='w+', shape=(n_elements,))

682

683

# Fill with data (on CPU)

684

mmap_array[:] = np.random.randn(n_elements).astype(dtype)

685

mmap_array.flush() # Ensure data is written to disk

686

687

print(f"Created memory-mapped file: {filename}")

688

print(f"File size: {os.path.getsize(filename) / 1024**2:.1f} MB")

689

690

# Read portions of the file to GPU

691

chunk_size = 100_000

692

693

# Method 1: Load specific ranges

694

start_idx = 200_000

695

end_idx = start_idx + chunk_size

696

gpu_chunk = cp.asarray(mmap_array[start_idx:end_idx])

697

698

print(f"Loaded chunk [{start_idx:,}:{end_idx:,}] to GPU")

699

print(f"Chunk statistics: mean={cp.mean(gpu_chunk):.3f}, "

700

f"std={cp.std(gpu_chunk):.3f}")

701

702

# Method 2: Process file in streaming fashion

703

def process_large_file(filename, chunk_size=50_000):

704

"""Process large memory-mapped file in chunks."""

705

# Open as memory-mapped array

706

mmap_data = np.memmap(filename, dtype=dtype, mode='r')

707

n_total = len(mmap_data)

708

709

results = []

710

for i in range(0, n_total, chunk_size):

711

chunk_end = min(i + chunk_size, n_total)

712

713

# Load chunk to GPU

714

gpu_chunk = cp.asarray(mmap_data[i:chunk_end])

715

716

# Process chunk (example: compute statistics)

717

chunk_stats = {

718

'start': i,

719

'end': chunk_end,

720

'mean': float(cp.mean(gpu_chunk)),

721

'std': float(cp.std(gpu_chunk)),

722

'min': float(cp.min(gpu_chunk)),

723

'max': float(cp.max(gpu_chunk))

724

}

725

results.append(chunk_stats)

726

727

if i < 5 * chunk_size: # Show first few chunks

728

print(f"Chunk {i//chunk_size + 1}: "

729

f"mean={chunk_stats['mean']:.3f}, "

730

f"std={chunk_stats['std']:.3f}")

731

732

return results

733

734

# Process the large file

735

chunk_results = process_large_file(filename)

736

print(f"Processed {len(chunk_results)} chunks")

737

738

# Aggregate results

739

overall_mean = np.mean([r['mean'] for r in chunk_results])

740

print(f"Overall mean (approximate): {overall_mean:.3f}")

741

742

# Direct file operations

743

# Save array directly from GPU to file

744

gpu_data = cp.random.randn(50_000).astype(cp.float32)

745

with open('direct_output.bin', 'wb') as f:

746

# Convert to CPU and save

747

cpu_data = cp.asnumpy(gpu_data)

748

f.write(cpu_data.tobytes())

749

750

print(f"Saved GPU data directly to binary file")

751

752

# Read binary data back

753

with open('direct_output.bin', 'rb') as f:

754

raw_bytes = f.read()

755

recovered_data = cp.frombuffer(raw_bytes, dtype=cp.float32)

756

757

print(f"Recovered data shape: {recovered_data.shape}")

758

print(f"Data integrity: {cp.array_equal(gpu_data, recovered_data)}")

759

```

760

761

### Array Formatting and Display

762

763

```python

764

import cupy as cp

765

766

# Create sample arrays for formatting examples

767

small_array = cp.array([1.23456789, -2.3456789, 0.0001234])

768

large_array = cp.random.randn(100, 50)

769

integer_array = cp.arange(1000).reshape(10, 100)

770

771

# Basic string representations

772

print("Array string representations:")

773

print(f"Small array str: {cp.array_str(small_array)}")

774

print(f"Small array repr: {cp.array_repr(small_array)}")

775

776

# Custom formatting options

777

formatted = cp.array2string(small_array,

778

precision=3,

779

suppress_small=True,

780

separator=', ')

781

print(f"Custom formatted: {formatted}")

782

783

# Set global print options

784

original_options = cp.get_printoptions()

785

print(f"Original print options: {original_options}")

786

787

# Temporarily change print options

788

with cp.printoptions(precision=2, suppress=True, threshold=20):

789

print("With custom print options:")

790

print(f"Small array: {small_array}")

791

print(f"Large array (summarized):\n{large_array}")

792

793

# Demonstrate different formatting styles

794

print("\nDifferent formatting styles:")

795

796

# Scientific notation

797

scientific = cp.array2string(small_array,

798

formatter={'float_kind': lambda x: f'{x:.2e}'})

799

print(f"Scientific: {scientific}")

800

801

# Fixed point

802

fixed_point = cp.array2string(small_array,

803

formatter={'float_kind': lambda x: f'{x:.4f}'})

804

print(f"Fixed point: {fixed_point}")

805

806

# Custom separators and brackets

807

custom_format = cp.array2string(small_array,

808

separator=' | ',

809

prefix='[',

810

suffix=']',

811

formatter={'float_kind': lambda x: f'{x:+.2f}'})

812

print(f"Custom format: {custom_format}")

813

814

# Integer formatting in different bases

815

binary_repr = cp.base_repr(42, base=2, padding=8)

816

hex_repr = cp.base_repr(42, base=16)

817

octal_repr = cp.base_repr(42, base=8)

818

819

print(f"\nNumber 42 in different bases:")

820

print(f"Binary (base 2): {binary_repr}")

821

print(f"Hexadecimal (base 16): {hex_repr}")

822

print(f"Octal (base 8): {octal_repr}")

823

824

# Array info for debugging

825

def array_info(arr, name="Array"):

826

"""Print comprehensive array information."""

827

print(f"\n{name} Information:")

828

print(f" Shape: {arr.shape}")

829

print(f" Dtype: {arr.dtype}")

830

print(f" Size: {arr.size:,} elements")

831

print(f" Memory: {arr.nbytes / 1024**2:.2f} MB")

832

print(f" Min/Max: {cp.min(arr):.3f} / {cp.max(arr):.3f}")

833

print(f" Mean/Std: {cp.mean(arr):.3f} / {cp.std(arr):.3f}")

834

835

# Show sample of data

836

if arr.size <= 20:

837

print(f" Data: {arr}")

838

else:

839

flat = arr.flatten()

840

sample = cp.concatenate([flat[:5], flat[-5:]])

841

print(f" Sample: [{sample[0]:.3f}, {sample[1]:.3f}, ..., "

842

f"{sample[-2]:.3f}, {sample[-1]:.3f}]")

843

844

# Demonstrate array info function

845

array_info(small_array, "Small Array")

846

array_info(large_array, "Large Array")

847

array_info(integer_array, "Integer Array")

848

```

849

850

### Data Conversion and Interoperability

851

852

```python

853

import cupy as cp

854

import numpy as np

855

856

# Demonstrate conversion between CuPy and NumPy

857

print("GPU ↔ CPU Data Transfer:")

858

859

# Create data on GPU

860

gpu_data = cp.random.randn(1000, 500).astype(cp.float32)

861

print(f"GPU data: shape={gpu_data.shape}, device={gpu_data.device}")

862

863

# Transfer to CPU

864

cpu_data = cp.asnumpy(gpu_data)

865

print(f"CPU data: shape={cpu_data.shape}, type={type(cpu_data)}")

866

867

# Transfer back to GPU

868

gpu_data2 = cp.asarray(cpu_data)

869

print(f"Back to GPU: shape={gpu_data2.shape}, device={gpu_data2.device}")

870

print(f"Data integrity: {cp.array_equal(gpu_data, gpu_data2)}")

871

872

# Demonstrate asynchronous transfer with streams

873

stream1 = cp.cuda.Stream()

874

stream2 = cp.cuda.Stream()

875

876

print("\nAsynchronous transfers:")

877

large_gpu_data = cp.random.randn(5000, 1000)

878

879

with stream1:

880

# Asynchronous transfer to CPU

881

cpu_result1 = cp.asnumpy(large_gpu_data[:2500], stream=stream1)

882

883

with stream2:

884

# Asynchronous transfer to CPU

885

cpu_result2 = cp.asnumpy(large_gpu_data[2500:], stream=stream2)

886

887

# Wait for transfers to complete

888

stream1.synchronize()

889

stream2.synchronize()

890

891

print(f"Async transfer 1 completed: {cpu_result1.shape}")

892

print(f"Async transfer 2 completed: {cpu_result2.shape}")

893

894

# Combine results

895

combined_cpu = np.concatenate([cpu_result1, cpu_result2])

896

print(f"Combined result: {combined_cpu.shape}")

897

print(f"Transfer integrity: {np.array_equal(cp.asnumpy(large_gpu_data), combined_cpu)}")

898

899

# Demonstrate zero-copy operations where possible

900

print("\nMemory sharing and zero-copy operations:")

901

902

# Create GPU array

903

original_gpu = cp.arange(1000)

904

print(f"Original GPU array: {original_gpu.shape}")

905

906

# Create view (shares memory)

907

gpu_view = original_gpu[::2] # Every other element

908

print(f"GPU view: {gpu_view.shape}, shares memory: {cp.shares_memory(original_gpu, gpu_view)}")

909

910

# Modify view

911

gpu_view *= 10

912

913

# Check if original was modified

914

print(f"Original modified through view: {cp.sum(original_gpu != cp.arange(1000)) > 0}")

915

print(f"First few elements of original: {original_gpu[:10]}")

916

917

# DLPack interoperability (if available)

918

try:

919

# Convert to DLPack tensor

920

dlpack_tensor = gpu_data.__dlpack__()

921

922

# Create new array from DLPack tensor

923

from_dlpack = cp.from_dlpack(dlpack_tensor)

924

925

print(f"\nDLPack interoperability:")

926

print(f"Original shape: {gpu_data.shape}")

927

print(f"From DLPack shape: {from_dlpack.shape}")

928

print(f"Memory shared: {cp.shares_memory(gpu_data, from_dlpack)}")

929

930

except Exception as e:

931

print(f"DLPack not available: {e}")

932

933

# Clean up files created in examples

934

import os

935

files_to_clean = [

936

'data.npy', 'dataset.npz', 'dataset_compressed.npz',

937

'measurements.txt', 'weather.txt', 'large_data.npy',

938

'large_data.npz', 'large_compressed.npz', 'large_memmap.dat',

939

'direct_output.bin'

940

]

941

942

for filename in files_to_clean:

943

if os.path.exists(filename):

944

os.remove(filename)

945

946

# Clean up chunk files

947

for i in range(100): # Arbitrary upper limit

948

chunk_file = f'chunk_{i:03d}.npy'

949

if os.path.exists(chunk_file):

950

os.remove(chunk_file)

951

952

print("\nCleaned up temporary files")

953

```