dpilger26 / NumCpp

C++ implementation of the Python Numpy library
https://dpilger26.github.io/NumCpp
MIT License
3.58k stars 555 forks source link

Function: NdArrayConstIterator Line: 70 Error: NdArray has not been initialized. #191

Closed ArEnSc closed 1 year ago

ArEnSc commented 1 year ago

Describe the bug At runtime without optimizations I am running into this error 1/3 times. I am building on iOS. Maybe this is a timing issue with library initialization?

terminating with uncaught exception of type std::runtime_error: File: /opt/homebrew/opt/numcpp/include/NumCpp/NdArray/NdArrayIterators.hpp Function: NdArrayConstIterator Line: 70 Error: NdArray has not been initialized.

To Reproduce

#pragma once
#ifndef RWKV_TYPICAL_H
#define RWKV_TYPICAL_H

#import <Foundation/Foundation.h>

#ifdef __cplusplus
extern "C" {
#endif

int typical(float* _logits, float _temp = 0.9, float _tau = 0.8);
int greedy(float* _logits,float _temp = 0.9);
#ifdef __cplusplus
}
#endif

#endif
#import "typical.h"
#include "NumCpp.hpp"

#include <cassert>
int typical(float* _logits, float _temp, float _tau)
{
    assert(_logits != NULL);
    int len = 50277;
    // choose top token
    nc::NdArray<double> logits = nc::NdArray<double>(1,len);
    for (int i = 0; i < len; i++) {

        logits[i] = _logits[i];
    }

    nc::NdArray<double> probs = nc::special::softmax(logits);
    logits = -nc::log(probs);
    nc::NdArray<double> ent = nc::nansum(logits * probs);
    nc::NdArray<double> shifted_logits = nc::abs(logits - ent);
    nc::NdArray<uint32_t> sorted_ids = nc::argsort(shifted_logits);
    nc::NdArray<double> sorted_logits = shifted_logits[sorted_ids];
    nc::NdArray<double> sorted_probs = probs[sorted_ids];
    nc::NdArray<double> cumulative_probs = nc::cumsum(sorted_probs);
    nc::NdArray<double> tau = nc::NdArray<double>(1,1);
    tau[0] = _tau;
    auto mask = (cumulative_probs < tau);
    // convert mask to int
    nc::NdArray<int> mask_int = nc::NdArray<int>(1,mask.size());
    for (int i = 0; i < mask.size(); i++) {
        mask_int[i] = mask[i];
    }

    // get cutoff
    auto cutoff = nc::sum(mask_int);
    // set probs to 0
    probs[shifted_logits > sorted_logits[cutoff]] = 0;
    if (_temp != 1.0) {
        probs = nc::power(probs, 1.0 / _temp);
    }

    // get random token
    auto out = nc::random::discrete<int>(nc::shape(tau),probs);
    return out[0];
}

Expected behavior Expected that it does not crash because of that issue

Screenshots If applicable, add screenshots to help explain your problem.

Additional context Add any other context about the problem here.

dpilger26 commented 1 year ago

Fixed as part of release version 2.11.0.