Internals
This page describes the internal implementation of the framework.
FFI bridge
src/Lib/TensorEngine.php declares the native C interface exactly once.
Key native types
typedef struct {
int ndim;
int shape[8];
size_t stride[8];
size_t total_size;
size_t byte_size;
bool owns_data;
bool is_arena;
int dtype;
void* data;
} TensorC;
TensorC is the PHP-visible struct used by Pml\Tensor.
Dataset internal modes
- ETL mode:
Dataset::$dfPtrholds a C DataFrame pointer. - Tensor mode:
Dataset::$samplesandDataset::$labelshold numeric tensors.
Dataset::_ensureTensorMode() lazily converts the dataset and frees the DataFrame pointer.
Zero-copy view semantics
Tensor::slice() and Tensor::view() use native C kernels that return a TensorC* view. The PHP wrapper stores the parent tensor reference so the underlying buffer remains valid.
Persistence internals
ModelStore::toArray()serializes PHP state and skips allTensorandFFI\CDatavalues.ModelStore::extractTensors()collects tensor state fromStatefulobjects or via reflection onTensor-typed properties.SafeTensorsIOwrites tensor bytes via native kernels and loads them withTensor::fromMmap().
Neural network internals
Pml\NeuralNetwork\Sequentialholds layers, a loss, and an optimizer.Densestores parameters and gradients as tensors and implementsStateful.- Backpropagation is performed by calling
backward()on layers in reverse order. - The training loop in
Trainerhandles batching, validation, early stopping, and LR scheduling.
GBDT internals
GBDTRegressorandGBDTClassifierbuild histogram-based trees using tensor kernels.- The native C backend provides functions such as
tensor_gbdt_train_tree()andtensor_gbdt_predict_all(). - The PHP class assembles and saves tree structure tensors for inference.
Example internal flow: Dataset::fromCSV()
- Call
tensor_dataset_from_csv()in the C backend. - If it returns a pointer array, wrap the returned sample and label tensors.
- If it returns
NULL, fallback todf_read_csv()and use ETL mode.
Example internal flow: model saving
Pipeline::save()collects transformer config and tensor state.- Transformer tensors are stored in
transformers.safetensors. - The estimator is saved either with its own
Persistable::save()or viaModelStore::save(). config.jsoncontains metadata, class names, and transformer prefixes.