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

set nil as the initial value of the struct reference type fields #51

Merged
merged 1 commit into from
Nov 21, 2023

Conversation

shove70
Copy link
Contributor

@shove70 shove70 commented Nov 21, 2023

for green CI:
vlang/v#19944

Summary by CodeRabbit

  • Refactor

    • Default initialization of various fields across multiple structures has been updated to nil for improved safety and predictability in the system's behavior.
  • Bug Fixes

    • Ensured that fields that were previously left uninitialized are now explicitly set to nil to prevent accidental usage of uninitialized data.
  • Documentation

    • Updated internal documentation to reflect changes in default field initializations.

Please note that these changes enhance the stability and reliability of the application without altering the existing functionality or user interface.

Copy link

coderabbitai bot commented Nov 21, 2023

Walkthrough

The overarching change across the codebase is the introduction of default nil initializations for various struct fields, using unsafe blocks. This adjustment seems to be a systematic effort to ensure that fields are explicitly set to nil when instances are created, likely to prevent the use of uninitialized data and to handle optional values more predictably.

Changes

Files Change Summary
autograd/gates_.v, nn/gates//.v, nn/layers/linear.v, datasets/.v, src/.v, nn/models/.v Fields in structs now default to nil using unsafe blocks.
nn/gates/loss/*.v cache and target fields in loss-related structs now default to nil.
nn/gates/layers/*.v Fields in layer-related structs now default to nil, ensuring proper initialization.

🐇 In the code where tensors flow, 🍂
🌟 A rabbit sets nil with a glow.
As autumn leaves twirl and spin, 🍁
Safe defaults usher a win. 🏆


Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • If you reply to a review comment from CodeRabbit, the bot will automatically respond.
  • To engage with CodeRabbit bot directly around the specific lines of code in the PR, mention @coderabbitai in your review comment
  • Note: Review comments are made on code diffs or files, not on the PR overview.
  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Note: For conversation with the bot, please use the review comments on code diffs or files.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

@shove70 shove70 merged commit edf4fc8 into vlang:main Nov 21, 2023
3 of 8 checks passed
@shove70 shove70 deleted the ref_init branch November 21, 2023 04:34
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 13

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between e191e63 and e7e059f.
Files selected for processing (28)
  • autograd/gates_basic.v (2 hunks)
  • autograd/gates_blas.v (1 hunks)
  • autograd/gates_exp.v (1 hunks)
  • autograd/gates_pow.v (1 hunks)
  • autograd/gates_trig.v (3 hunks)
  • autograd/node.v (1 hunks)
  • autograd/payload.v (1 hunks)
  • autograd/variable.v (1 hunks)
  • datasets/imdb.v (1 hunks)
  • datasets/mnist.v (1 hunks)
  • nn/gates/activation/elu.v (1 hunks)
  • nn/gates/activation/leaky_relu.v (1 hunks)
  • nn/gates/activation/relu.v (1 hunks)
  • nn/gates/activation/sigmoid.v (1 hunks)
  • nn/gates/layers/dropout.v (1 hunks)
  • nn/gates/layers/flatten.v (1 hunks)
  • nn/gates/layers/linear.v (1 hunks)
  • nn/gates/layers/maxpool.v (1 hunks)
  • nn/gates/loss/mse.v (1 hunks)
  • nn/gates/loss/sigmoid_cross_entropy.v (1 hunks)
  • nn/gates/loss/softmax_cross_entropy.v (1 hunks)
  • nn/layers/linear.v (1 hunks)
  • nn/models/sequential.v (1 hunks)
  • nn/models/sequential_info.v (1 hunks)
  • src/iter.v (1 hunks)
  • src/iter_axis.v (1 hunks)
  • src/tensor.v (1 hunks)
  • src/tensor_vcl_d_vcl.v (1 hunks)
Files skipped from review due to trivial changes (5)
  • autograd/gates_trig.v
  • datasets/imdb.v
  • nn/gates/layers/dropout.v
  • nn/gates/loss/mse.v
  • nn/gates/loss/sigmoid_cross_entropy.v
Additional comments: 14
nn/gates/activation/elu.v (1)
  • 9-9: Initialization of cache to nil within an unsafe block is a critical change for preventing the use of uninitialized memory. This change should be cross-checked to ensure that all usages of EluGate properly initialize cache before accessing it to avoid null pointer dereferences.
nn/gates/layers/flatten.v (1)
  • 6-10: The initialization of input to nil using an unsafe block is a significant change that ensures the field is explicitly initialized before use. This is a good practice to prevent the use of uninitialized memory, which can lead to undefined behavior or crashes. However, it's important to ensure that all usages of FlattenGate throughout the codebase are updated to handle this new initialization pattern correctly.
nn/layers/linear.v (1)
  • 12-13: The initialization of weights and bias fields to nil using an unsafe block is a significant change that ensures these fields are explicitly initialized before use. This can prevent potential null pointer dereferences. However, it is crucial to ensure that all code that constructs LinearLayer instances properly initializes these fields to avoid runtime errors. The use of unsafe should be carefully documented, explaining why it is necessary and what precautions must be taken when working with these fields.
nn/gates/activation/leaky_relu.v (1)
  • 6-10: The initialization of cache to nil using an unsafe block is a significant change that addresses potential issues with uninitialized memory. This change should be verified across the codebase to ensure that all instances where LeakyReluGate is used are updated to handle the nil value appropriately. Additionally, it's important to ensure that the cache field is assigned a proper value before any operations are performed on it to avoid null pointer dereferences.
autograd/node.v (1)
  • 13-19: The initialization of payload to nil using an unsafe block is a significant change that ensures the field is explicitly set to a known state before use. This change helps prevent issues related to uninitialized memory access, which can lead to unpredictable behavior or crashes. However, it is important to ensure that all code that relies on the Node struct is updated to handle the possibility of payload being nil. This may require additional null checks or initialization logic before accessing the payload field.
src/tensor.v (1)
  • 12-18: The initialization of data to nil using an unsafe block is a significant change that addresses potential issues with uninitialized memory. However, it is important to ensure that all code that creates or manipulates Tensor objects is updated to handle this new default nil value appropriately. Failing to do so could lead to null pointer dereferences. It is also worth noting that this change might require updates to the documentation to reflect the new behavior and guide developers on the correct usage of the Tensor struct.
autograd/gates_exp.v (1)
  • 4-10: The initialization of the a field within the ExpGate struct to nil using an unsafe block is a significant change that addresses potential issues with uninitialized memory. This change should be verified to ensure that all parts of the code that create instances of ExpGate are aware of the need to explicitly initialize the a field before use. Additionally, it's important to ensure that this change does not introduce any new issues, such as null pointer dereferences, and that it is consistent with the initialization patterns in other parts of the codebase.
datasets/mnist.v (1)
  • 14-21: The initialization of MnistDataset fields to nil using unsafe blocks is a significant change that ensures these fields are explicitly set to nil upon struct creation. This change enhances the safety and predictability of the struct's usage by preventing accidental use of uninitialized data. However, it is important to ensure that all parts of the code that instantiate MnistDataset are aware of this change and handle the nil values appropriately to avoid null pointer dereferences.
nn/models/sequential.v (1)
  • 12-15: The initialization of info to nil within an unsafe block is a significant change that ensures the field is explicitly set to a known state before use. This change is in line with the overall pull request's goal of preventing uninitialized memory access. However, it is important to ensure that all code that relies on Sequential now handles the possibility of info being nil. This may require additional null checks or initialization logic before accessing info fields or methods.
nn/gates/loss/softmax_cross_entropy.v (1)
  • 13-13: The function softmax_cross_entropy_gate correctly returns a new instance of SoftmaxCrossEntropyGate with the cache and target fields set to the provided arguments. This ensures that the fields are not nil when the gate is used, which is consistent with the changes made to the struct definition. It's important to verify that all usages of this function pass valid, non-nil arguments for cache and target.
nn/gates/activation/relu.v (1)
  • 6-10: The initialization of cache to unsafe { nil } is a significant change that ensures the field is explicitly initialized to nil. This change is part of a broader effort to initialize reference type fields to nil to prevent undefined behavior due to uninitialized memory access. However, it is important to ensure that all usages of ReLUGate properly handle the nil value of cache to avoid null pointer dereferences, which can lead to crashes or other unintended behavior. The use of unsafe indicates that this operation bypasses the language's safety features, so extra caution should be taken when working with this field.
nn/gates/activation/sigmoid.v (1)
  • 7-10: The initialization of the cache field within the SigmoidGate struct using unsafe { nil } is a significant change that ensures the field is explicitly set to nil. This change is likely intended to prevent the use of uninitialized memory, which can lead to undefined behavior. However, it's important to ensure that all code that creates instances of SigmoidGate properly initializes the cache field before it's used, as accessing a nil reference can lead to runtime errors. The use of unsafe indicates that this operation bypasses the language's safety features, which is necessary for low-level operations like this but should be used with caution.
nn/gates/layers/linear.v (1)
  • 15-15: The linear_gate function correctly initializes the LinearGate struct with the provided input, weight, and bias arguments. This is the expected behavior and ensures that the fields are not nil when the struct is used. However, it is important to note that the safety of this function relies on the caller always providing valid arguments. If the caller passes nil for any of these arguments, it could lead to the same issues as mentioned above.
autograd/gates_pow.v (1)
  • 6-9: The PowGate struct now initializes its a and b fields to nil within an unsafe block. This change is consistent with the pull request's goal of initializing reference type fields to nil to prevent uninitialized memory access. However, it is important to ensure that all usages of PowGate properly initialize these fields before accessing them to avoid null pointer dereferences, which can lead to crashes or undefined behavior. The use of unsafe blocks should be carefully reviewed to ensure that it does not introduce new safety issues.

Comment on lines 6 to 10
pub struct MatMulGate[T] {
pub:
a &Variable[T]
b &Variable[T]
a &Variable[T] = unsafe { nil }
b &Variable[T] = unsafe { nil }
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialization of a and b fields in the MatMulGate struct to nil using unsafe blocks is a significant change. This change assumes that the fields will be properly initialized before they are used. It is crucial to ensure that all usages of MatMulGate are reviewed and updated to handle the possibility of nil values to prevent null pointer dereferences, which can lead to crashes or undefined behavior. Additionally, the use of unsafe blocks should be carefully documented, explaining why this approach is necessary and what precautions should be taken when working with these fields.

Comment on lines 6 to 12
@[heap]
pub struct VclTensor[T] {
pub mut:
data &storage.VclStorage[T]
data &storage.VclStorage[T] = unsafe { nil }
memory MemoryFormat
size int
shape []int
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialization of data to nil using an unsafe block is a significant change that addresses potential issues with uninitialized memory. However, it is important to ensure that all code that interacts with VclTensor instances properly checks for nil before dereferencing data. Failing to do so could lead to null pointer dereference errors at runtime.

Comment on lines 5 to 11
@[heap]
pub struct TensorAxisIterator[T] {
pub:
tensor &Tensor[T]
tensor &Tensor[T] = unsafe { nil }
pub mut:
shape []int
strides []int
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change to initialize the tensor field with unsafe { nil } is a significant one. It is important to ensure that all usages of TensorAxisIterator are reviewed to confirm that the tensor field is being properly initialized before use, as this change could potentially introduce null pointer dereferences if the field is accessed without proper initialization. This is a critical safety concern, especially in a language like V that emphasizes safety and simplicity.

@@ -12,7 +12,7 @@ pub enum IteratorStrategy {
@[heap]
pub struct TensorIterator[T] {
pub:
tensor &Tensor[T]
tensor &Tensor[T] = unsafe { nil }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialization of tensor to nil using an unsafe block is a significant change that addresses potential issues with uninitialized memory. However, it's important to ensure that all usages of TensorIterator throughout the codebase are updated to handle the possibility of tensor being nil. This change could lead to runtime errors if the tensor field is dereferenced without proper checks. It is recommended to add null checks or handle the nil case appropriately wherever TensorIterator is used.

Comment on lines 7 to 11
pub struct Payload[T] {
pub:
// Contents of the paylod
variable &Variable[T]
variable &Variable[T] = unsafe { nil }
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change to initialize the variable field within the Payload struct to nil using an unsafe block is a significant alteration aimed at preventing the use of uninitialized memory. This is a good practice for safety, especially in a language like V that emphasizes memory safety. However, it is important to ensure that all code that relies on Payload is updated to handle the possibility of variable being nil. This change could potentially lead to runtime errors if the variable field is dereferenced without checking for nil. It is recommended to review all usages of Payload to ensure that proper nil checks or initializations are in place before dereferencing the variable field.

Comment on lines 8 to 13
pub struct LinearGate[T] {
pub:
input &autograd.Variable[T]
weight &autograd.Variable[T]
bias &autograd.Variable[T]
input &autograd.Variable[T] = unsafe { nil }
weight &autograd.Variable[T] = unsafe { nil }
bias &autograd.Variable[T] = unsafe { nil }
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialization of input, weight, and bias fields to nil using unsafe blocks is a significant change that could potentially lead to runtime errors if these fields are accessed before being properly initialized. It is crucial to ensure that all code paths that create instances of LinearGate properly initialize these fields before use. This change may require a thorough review of all usages of LinearGate to prevent null pointer dereferences.

Comment on lines 15 to 29
// The value of the Variable. This should not be edited outside
// of Variable operations, as other edits will not be tracked
// and will lead to incorrect results
value &vtl.Tensor[T]
value &vtl.Tensor[T] = unsafe { nil }
// The graph the variable is associated with. This is a reference,
// as a variable does not own its context
context &Context[T]
context &Context[T] = unsafe { nil }
// The gradient of the Variable. This is set as a reference to
// the value of a Variable unless `backprop` has been called, in
// which case all related Variables will have their gradient
// updated correctly
grad &vtl.Tensor[T]
grad &vtl.Tensor[T] = unsafe { nil }
// If set to true, this variable will track its operations,
// otherwise it will act similar to a vtl.Tensor, only calculating
// forward operations
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of unsafe { nil } to initialize reference type fields is a critical change that addresses potential issues with uninitialized memory. However, it's important to ensure that all parts of the code that interact with these fields are now expecting and correctly handling nil values. This change could introduce nil pointer dereferences if the rest of the codebase is not updated accordingly. The team should verify that all usages of Variable fields are checked for nil before access and that appropriate error handling is in place.

a &Variable[T]
b &Variable[T]
a &Variable[T] = unsafe { nil }
b &Variable[T] = unsafe { nil }
}

pub fn pow_gate[T](a &Variable[T], b &Variable[T]) &PowGate[T] {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pow_gate function signature has not been updated to reflect the changes in the PowGate struct. Since the fields a and b are now optional and initialized to nil, the function parameters a and b are no longer necessary for the struct initialization. If the intention is to keep the function signature as is and require the caller to provide a and b, then the struct should not initialize these fields to nil. If the fields are meant to be optional, the function signature should be updated accordingly, and the function body should handle the case where a and b might be nil.

Comment on lines 76 to 80
pub struct MultiplyGate[T] {
pub:
a &Variable[T]
b &Variable[T]
a &Variable[T] = unsafe { nil }
b &Variable[T] = unsafe { nil }
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialization of a and b to nil using unsafe blocks is a significant change that addresses potential issues with uninitialized memory. However, it is important to ensure that all code that creates instances of MultiplyGate properly initializes these fields before they are used. Failing to do so could lead to null pointer dereferences, which can cause crashes or other undefined behavior. It is also worth considering if there are safer ways to ensure initialization without resorting to unsafe blocks, such as providing default values or factory functions that guarantee proper initialization.

Comment on lines 120 to 124
pub struct DivideGate[T] {
pub:
a &Variable[T]
b &Variable[T]
a &Variable[T] = unsafe { nil }
b &Variable[T] = unsafe { nil }
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the MultiplyGate, the DivideGate struct now initializes its a and b fields to nil within unsafe blocks. This change requires careful review to ensure that all instances of DivideGate are properly initialized before use. Additionally, the use of unsafe blocks should be justified and reviewed to ensure that the safety benefits outweigh the risks of bypassing the language's safety features.

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

Successfully merging this pull request may close these issues.

1 participant