Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Debugging new models] Any idea of how to expose __device__ void calculate_model() in order to check model implementation? #30

Open
mscipio opened this issue Nov 22, 2017 · 8 comments

Comments

@mscipio
Copy link

mscipio commented Nov 22, 2017

I just want to test a new model but despite note having compilation issue, it doesn't fit my data.
I thought of testing my code giving my kernel a set of parameter and checking the shape of the simulated curve but I am having more troubles than expected.

Down here what I tried to do, but it is not working at all ...

  1. created a new method in lm_fit_cuda.cpp as:
void LMFitCUDA::simul()
{
    // initialize the chi-square values
    calc_curve_values();
}
  1. and then in lm_fit.cpp a new method of LMfit class:
void LMFit::simul(float const tolerance)
{
    set_parameters_to_fit_indices();

    GPUData gpu_data(info_);
    gpu_data.init_user_info(user_info_);

    // loop over data chunks
    while (n_fits_left_ > 0)
    {
        chunk_size_ = int((std::min)(n_fits_left_, info_.max_chunk_size_));
        info_.set_fits_per_block(chunk_size_);

        gpu_data.init(
            chunk_size_,
            ichunk_,
            data_,
            weights_,
            initial_parameters_,
            parameters_to_fit_indices_);

        LMFitCUDA lmfit_cuda(
            tolerance,
            info_,
            gpu_data,
            chunk_size_);
        lmfit_cuda.simul();
        get_results(gpu_data, chunk_size_);
        n_fits_left_ -= chunk_size_;
        ichunk_++;
    }
}
  1. A new method for class FitInterface:
void FitInterface::simulate(ModelID const model_id)
{
    int n_dimensions = 0;
    configure_model(model_id, n_parameters_, n_dimensions);

    check_sizes();

    Info info;
    configure_info(info, model_id);

    LMFit modelsim
    (
        data_,
        weights_,
        info,
        initial_parameters_,
        parameters_to_fit_,
        user_info_,
        output_parameters_,
        output_states_,
        output_chi_squares_,
        output_n_iterations_
    ) ;
    modelsim.simul(tolerance_);
}
  1. And eventually a new function in gpufit.cpp
int gpusimul
(
    size_t n_fits,
    size_t n_points,
    float * data,
    float * weights,
    ModelID model_id,
    float * initial_parameters,
    float tolerance,
    int max_n_iterations,
    int * parameters_to_fit,
    EstimatorID estimator_id,
    size_t user_info_size,
    char * user_info,
    float * output_parameters,
    int * output_states,
    float * output_chi_squares,
    int * output_n_iterations
)
try
{
    __int32 n_points_32 = 0;
    if (n_points <= (unsigned int)(std::numeric_limits<__int32>::max()))
    {
        n_points_32 = __int32(n_points);
    }
    else
    {
        throw std::runtime_error("maximum number of data points per fit exceeded");
    }

    FitInterface fi(
        data,
        weights,
        n_fits,
        n_points_32,
        tolerance,
        max_n_iterations,
        estimator_id,
        initial_parameters,
        parameters_to_fit,
        user_info,
        user_info_size,
        output_parameters,
        output_states,
        output_chi_squares,
        output_n_iterations);

    fi.simulate(model_id);

    return ReturnState::OK  ;
}
@caowencai
Copy link

void LMFitCUDA::simul()
void LMFit::simul(float const tolerance) same function name in different class?
By the way, still confused about what your new model is like.

@superchromix
Copy link
Collaborator

For debugging purposes, it may be useful to implement the model within Cpufit, first. Then, you can use a standard debugger without having to run the code on the GPU.

@mscipio
Copy link
Author

mscipio commented Nov 27, 2017

@gittry
They are meant just to debug, and not as a general interface.
The same naming in different classes should cause interference, as far as I know.
If you want to know more about the model, give a look at my GitHub.
my own tool
my fork of Gpufit - not working yet

@superchromix
That was a good hint. I will give it a try.
By the way, I think that having one additional output to LMFit::LMFit with the values of the fitted curve can be useful to avoid computing again the model from the estimated parameters. In my current fork, I added an additional input float * output_data to LMFit class initialization, that I use to read the value of gpu_data_.values_ and that seems to be doing the trick, so far.

I agree that maybe an additional gpusimul() function could be overkilling ...

@jkfindeisen
Copy link
Collaborator

I agree that maybe an additional gpusimul() function could be overkilling ...

My impression is that it would not be overkill. Cpufit is the simulation of Gpufit in a manner of speaking.

What we ideally would like to have is to write down the model once and then use it once on the CPU (for debugging purposes) and once on the GPU without duplicating the code. So far we did not manage to do that and we are duplicating code in the CPU and GPU library versions with all the drawbacks but in a future version this might well be the case.

@jkfindeisen
Copy link
Collaborator

Also, just being able to compute the model or the gradients at the current parameters sounds like an obvious enhancement to me. Often enough you not only need the final fit parameters but also the model values at these parameters. Would need to extend the interface for that. We should keep this in mind.

@superchromix
Copy link
Collaborator

I think that having one additional output to LMFit::LMFit with the values of the fitted curve can be useful to avoid computing again the model from the estimated parameters.

This would involve copying a large amount of data from the GPU to the CPU, resulting in slower performance. This could possibly be an optional output.

@mscipio
Copy link
Author

mscipio commented Nov 27, 2017

This would involve copying a large amount of data from the GPU to the CPU, resulting in slower performance. This could possibly be an optional output.

@superchromix
Yes, this is true, indeed.
But for what I need, having the fitting output as a (matrix of) time series is necessary. So far, I just added one additional output, that is used just at the very end of the fitting (so just one transfer GPU-CPU) ... mainly because I don't know how to make it optional, yet! xD

@jkfindeisen
Copy link
Collaborator

mainly because I don't know how to make it optional, yet!

So far, the C interface of Gpufit is stateless, so either one would need to add another input flag (controlling outputs) or set this with another function and then Gpufit would need to remember its state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants